Итак, я пытаюсь понять Bison и Flex (и как они идут вместе). Пример грамматики я получил очень просто,Зубцы жевательной резинки Bison/Flex в обратном порядке
e → e plus t
e → t
t → t TIMES f
t → f
f → LPAREN e RPAREN
f → ID
Мой тестовый вход только «х» и я ожидаю выход быть:
"(e (t (f (ID x))))"
Фактический выход я получаю :
ID x f t
Мне интересно, почему мой вывод обратный (я еще не добавил круглую скобку). Вот мои файлы flex и bison.
Bison:
%{
#include "expr-parse-defs.h"
#include <iostream>
std::string AST;
%}
%union {
char *sval;
}
%token <sval> ID PLUS TIMES LPAREN RPAREN
%%
e :
| e PLUS t { AST += std::string("e ") + $2 + "t "; }
| t { AST += "t "; }
;
t :
| t TIMES f { AST += std::string("t ") + $2 + "f "; }
| f { AST += "f "; }
;
f :
| LPAREN e RPAREN { AST += $1 + std::string("e ") + $3; }
| ID { AST += std::string("ID ") + $1 + " " ; }
;
%%
int main() {
yyparse();
std::cout << AST;
return 0;
}
Flex:
%{
#include <cstring>
#include <string>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include "expr-parse.tab.h"
#include "expr-parse-defs.h"
using namespace std;
int tokenpos = 0;
char * process_token(const char* token){
// we have to copy because we can't rely on yytext not changing underneath us:
char *res = new char[strlen(yytext) + 3];
strcpy(res, yytext);
yylval.sval = res;
}
%}
ID [a-zA-Z][a-zA-Z0-9_]*
%%
"+" { yylval.sval = process_token("PLUS"); return PLUS; }
"*" { yylval.sval = process_token("TIMES"); return TIMES; }
"(" { yylval.sval = process_token("LPAREN"); return LPAREN; }
")" { yylval.sval = process_token("RPAREN"); return RPAREN; }
{ID} { yylval.sval = process_token("ID"); return ID; }
[\n]
%%
int yyerror(const char *s) {
cerr << "this is a bad error message and needs to be changed eventually" << endl;
return 0;
}
Я не смотрел код достаточно подробно, но моя немедленная реакция заключается в том, что это примерно то, что я ожидаю от анализатора снизу вверх. –
Хорошо, так оно и начнется с последнего токена, который он находит? – AlexLordThorsen
Нет - он обрабатывает маркеры по порядку, но начинается со дна дерева (самые примитивные элементы, такие как идентификатор в вашей грамматике) и прокладывает путь вверх по дереву, чтобы достичь производства верхнего уровня. По крайней мере, насколько я вижу, вы только смотрите на разбор одного токена. –