how to create a simple calculator for sum two numbers using flex, bison and cmake? i try understand flex and bison (studying both), I still don't know how to use them, and I would like a practical example of how to compile (with cmake) a simple project for me to study.
I found an example calculator and an example from cmake, but I can't compile to test and be able to study and understand. Below has a failed attempt to compile.
This code is available in GitHub
using
find_package (BISON REQUIRED) find_package (FLEX REQUIRED)
flex_target bison_target
CMakeFiles.txt
cmake_minimum_required(VERSION 3.7)
project(lesson)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)
bison_target(lesson-parser
calc-parser.y
${CMAKE_CURRENT_BINARY_DIR}/parser.tab.cpp
)
flex_target(lesson-scanner
calc-scanner.l
${CMAKE_CURRENT_BINARY_DIR}/scanner.tab.cpp
)
add_executable(lesson ${BISON_MyParser_OUTPUTS} ${FLEX_MyScanner_OUTPUTS} main.cpp)
add_flex_bison_dependency(lesson-scanner lesson-parser)
calc-parser.y
/* Gramatica: {Vt, Vn, P, S}
* Vt = {INTEGER, NEWLINE, +, -, *, /, (, )}
* Vn = {line, term, expr}
* P = {
* line -> epsilon
* line -> term
* term -> newline
* term -> expr newline
* expr -> intnumer
* expr -> expr + expr
* expr -> expr - expr
* expr -> expr * expr
* expr -> expr / expr
* expr -> (expr)
* expr -> -expr
* }
* S = line
*/
%{
#include <stdio.h>
int intval;
extern char *yytext;
%}
%token INTEGER, NEWLINE
%left '+' '-'
%left '*' '/'
%nonassoc UMINUS
%start line /* simbolo sentencial */
%%
line:
| line term
;
term: NEWLINE
| expr NEWLINE {printf("%d\n", $1);}
| error NEWLINE {yyerror;}
;
expr: INTEGER {$$ = intval;}
| expr '+' expr {$$ = $1 + $3;}
| expr '-' expr {$$ = $1 - $3;}
| expr '*' expr {$$ = $1 * $3;}
| expr '/' expr {if($3) $$ = $1 / $3;
else {
printf("Divide by zero");
yyerror;
}
}
| '(' expr ')' {$$ = $2;}
| '-' expr %prec UMINUS {$$ = - $2;}
;
%%
yyerror(s)
char *s;
{
printf("Oops: %s at symbol %c\n", s, yytext[0]);
}
calc-scanner.l
%{
#include "y.tab.h"
extern int intval;
%}
integer [0-9]+
nl \n
%%
[ \t]+ ;
{integer} {sscanf(yytext, "%d", &intval); return INTEGER;}
{nl} {return NEWLINE;}
. {return yytext[0];}
%%
Parser.h
#ifndef LESSON_PARSER_H
#define LESSON_PARSER_H
namespace Test {
class Parser {
public:
static int parser();
};
}
#endif //LESSON_PARSER_H
Parser.cpp
#include "Parser.h"
int Test::Parser::parser() {
return yyparse();
}
main.cpp
#include <iostream>
#include "Parser.h"
int main(int argc, char **argv) {
return Test::Parser::parser();
}
I try call the "Test::Parser::parser()" to analyze the input. The compiler log error is:
====================[ Build | all | Debug-Debian ]==============================
/usr/bin/cmake --build /tmp/tmp.SIGMymeLDv/cmake-build-debug-debian --target all -- -j 4
[ 66%] Building CXX object CMakeFiles/lesson.dir/Parser.cpp.o
[ 66%] Building CXX object CMakeFiles/lesson.dir/main.cpp.o
/tmp/tmp.SIGMymeLDv/Parser.cpp: In static member function 'static int Test::Parser::parser()':
/tmp/tmp.SIGMymeLDv/Parser.cpp:8:12: error: 'yyparse' was not declared in this scope
return yyparse();
^~~~~~~
/tmp/tmp.SIGMymeLDv/Parser.cpp:8:12: note: suggested alternative: 'parser'
return yyparse();
^~~~~~~
parser
make[2]: *** [CMakeFiles/lesson.dir/build.make:76: CMakeFiles/lesson.dir/Parser.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [CMakeFiles/Makefile2:73: CMakeFiles/lesson.dir/all] Error 2
make: *** [Makefile:84: all] Error 2