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("%dn", $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 %cn", 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
2
Answers
The problem was in my cmake at add_executable, the below code do not exist:
The correct is:
The code is updated in github
If you want to use
yyparse
inParser.cpp
, then you need a declaration for it to be visible inParser.cpp
. Clearly, there is no such declaration.yyparse()
is declared in the bison-generated header, so #including that inParser.cpp
will likely solve your problem.FWIW,
Parser.cpp
does not appear to have been extracted from either of the projects you mentioned in your original question. Evidently, not mentioning its existence made your original question much harder to answer. This is why we always request that questions include a minimal but complete program which exhibits the problem.