cmake - 如何使用 flex、bison 和 cmake 创建一个简单的计算器来计算两个数字的和?
问题描述
如何使用 flex、bison 和 cmake 创建一个简单的计算器来计算两个数字的和?我尝试了解 flex 和 bison(两者都学习),但我仍然不知道如何使用它们,我想要一个如何编译(使用 cmake)一个简单项目供我学习的实际示例。
我从 cmake找到了一个示例计算器和一个示例,但我无法编译测试并能够学习和理解。下面有一个失败的编译尝试。
此代码在GitHub中可用
使用
find_package (BISON REQUIRED) find_package (FLEX REQUIRED)
flex_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];}
%%
解析器.h
#ifndef LESSON_PARSER_H
#define LESSON_PARSER_H
namespace Test {
class Parser {
public:
static int parser();
};
}
#endif //LESSON_PARSER_H
解析器.cpp
#include "Parser.h"
int Test::Parser::parser() {
return yyparse();
}
主文件
#include <iostream>
#include "Parser.h"
int main(int argc, char **argv) {
return Test::Parser::parser();
}
我尝试调用“Test::Parser::parser()”来分析输入。编译器日志错误是:
====================[ 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
解决方案
问题出在我在 add_executable 的 cmake 中,以下代码不存在:
$ {BISON_MyParser_OUTPUTS} $ {FLEX_MyScanner_OUTPUTS}
正确的是:
$ {BISON_lesson-parser_OUTPUTS} $ {FLEX_lesson-scanner_OUTPUTS}
推荐阅读
- javascript - Sails - 为什么我只从 CRUD“快捷方式”接收套接字更新?
- dll - Lua:使用 2 个函数时在 dll 库中的堆栈
- android - 新创建的 ionic3 应用程序无法在 android 设备上运行
- python - 如何获得熊猫表中的最小增量?
- c++ - 将 boost::filesystem::path 转换为字符?
- javascript - 如何在 Firestore 的数组中查询多个项目?(“数组包含”)
- visual-studio-code - 在 Visual Studio 代码中单击时禁用替换预览
- java - Postgres JDBC连接作为应用程序用户而不是系统用户
- postgresql - 使用 Chef 配方更改密码 Postgresql 用户
- routing - 如何在 navigationStart 路由器事件中暂停路由更改