【问题标题】:How to create a simple calculator for sum two numbers using flex, bison and cmake?如何使用 flex、bison 和 cmake 创建一个简单的计算器来计算两个数字的和?
【发布时间】:2020-07-12 01:55:05
【问题描述】:

如何使用 flex、bison 和 cmake 创建一个简单的计算器来计算两个数字的和? 我尝试了解 flex 和 bison(两者都学习),但我仍然不知道如何使用它们,我想要一个如何编译(使用 cmake)一个简单项目供我学习的实际示例。

I found an example calculatoran example from cmake,但是不能编译测试,可以学习理解。下面尝试编译失败。

此代码在GitHub中可用

使用

find_package(需要 BISON) find_package(需要灵活)

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();
}

main.cpp

#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

【问题讨论】:

  • 如果你描述了这个问题,这个问题可能是可以回答的。会发生什么不符合您的预期?
  • "编译尝试失败"...怎么回事?请提供您收到的具体错误...
  • thisthis 问题的回答是否适用于您的情况?

标签: cmake bison flex-lexer yacc


【解决方案1】:

如果您想在Parser.cpp 中使用yyparse,那么您需要声明它才能在Parser.cpp 中可见。显然,没有这样的声明。

yyparse() 是在野牛生成的标头中声明的,因此在 Parser.cpp 中包含 #include 可能会解决您的问题。

FWIW,Parser.cpp 似乎没有从您在原始问题中提到的任何一个项目中提取。显然,不提及它的存在会使您最初的问题更难回答。这就是为什么我们总是要求问题包含一个能够展示问题的最小但完整的程序。

【讨论】:

    【解决方案2】:

    问题出在我的 cmake 中 add_executable,下面的代码不存在:

    $ {BISON_MyParser_OUTPUTS} $ {FLEX_MyScanner_OUTPUTS} 
    

    正确的是:

    $ {BISON_lesson-parser_OUTPUTS} $ {FLEX_lesson-scanner_OUTPUTS}
    

    The code is updated in github

    【讨论】:

      猜你喜欢
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多