Как создать простой калькулятор для суммирования двух чисел с помощью flex, bison и cmake? - PullRequest
0 голосов
/ 12 июля 2020

как создать простой калькулятор для суммы двух чисел с помощью flex, bison и cmake? Я пытаюсь понять flex и bison (изучаю оба), я все еще не знаю, как их использовать, и мне нужен практический пример того, как скомпилировать (с помощью cmake) простой проект, который я мог бы изучить.

Я нашел пример калькулятора и пример из cmake , но я не могу скомпилировать для тестирования и уметь изучать и понимать. Ниже приведена неудачная попытка компиляции.

Этот код доступен в GitHub

с использованием

find_package (ТРЕБУЕТСЯ ЗУБР) find_package (ТРЕБУЕТСЯ FLEX)

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)

cal c -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]);
}

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

Я пытаюсь вызвать «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

Ответы [ 2 ]

0 голосов
/ 13 июля 2020

Проблема была в моем cmake в add_executable, код ниже не существует:

$ {BISON_MyParser_OUTPUTS} $ {FLEX_MyScanner_OUTPUTS} 

Правильно:

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

Код обновлен в github

0 голосов
/ 13 июля 2020

Если вы хотите использовать yyparse в Parser.cpp, вам нужно объявление, чтобы оно было видно в Parser.cpp. Очевидно, что такого объявления нет.

yyparse() объявлено в сгенерированном bison заголовке, поэтому # включение этого в Parser.cpp, скорее всего, решит вашу проблему.

FWIW, Parser.cpp похоже, не было извлечено ни из одного из проектов, упомянутых вами в исходном вопросе. Очевидно, что из-за того, что не было упоминания о его существовании, на ваш первоначальный вопрос было гораздо труднее ответить. Вот почему мы всегда просим, ​​чтобы вопросы включали минимальную, но полную программу, которая демонстрирует проблему.

...