flex и bison: ошибка компиляции g ++

Я пытаюсь скомпилировать сканер и парсер для игрушечного языка, используя g ++. Вот код для каждого файла, который я использую (если вы хотите, я могу опубликовать его на pastebin или где-нибудь еще).

caesar.ll

/* Simple scanner for a Caesar language */
%{
#include "caesar.tab.h"#include <iostream>
#include <string>
int chars = 0;
int words = 0;
int lines = 0;
%}

/* Define constants */
OWS            [" "\t]*
COMMA          {OWS}","{OWS}
ID             [A-Za-z_][A-Za-z0-9_]*
INT            ([0-9]+)|("0x"[A-Ha-h0-9]+)
FLOAT          [0-9]+"."[0-9]+
BSTREAM        b[\'\"].*[\'\"]
USTREAM        u?[\'\"].*[\'\"]
ARRAY          {LBRACE}({INT}|{FLOAT})({COMMA}({INT}|{FLOAT})){RBRACE}
LIST           {LBRACKET}.*({COMMA}.*){RBRACKET}
RANGE          {LBRACE}{INT}":"{INT}(":"{INT})?{RBRACE}
ARGS           {ID}({COMMA}{ID})*
LPARENTHESIS   "("{OWS}
RPARENTHESIS   {OWS}")"LBRACE         "{"{OWS}
RBRACE         {OWS}"}"LBRACKET       "["{OWS}
RBRACKET       {OWS}"]"
%%
%{
/*============================================================================*/
/* Define types */
/*============================================================================*/
%}
{INT} {
cout << "int: " << yytext << endl;
yylval = atoi(yytext);
return INT;
} /* int type */

{FLOAT} {
cout << "float: " << yytext << endl;
yylval = atof(yytext);
return FLOAT;
} /* float type */

{BSTREAM} {
cout << "bstream: " << yytext << endl;
return BSTREAM;
} /* bstream type */

{USTREAM} {
cout << "ustream: " << yytext << endl;
return USTREAM;
} /* ustream type */

%{
/*============================================================================*/
/* Define operators */
/*============================================================================*/
%}
"+"    { return ADD; }
"-"    { return SUB; }
"*"    { return MUL; }
"/"    { return DIV; }
"//"   { return FDIV; }
"|"    { return ABS; }
"\n"   { return EOL; }

%{
/*============================================================================*/
/* Define statements */
/*============================================================================*/
%}
{RANGE} {
cout << "range: " << yytext << endl;
return RANGE;
} /* range function */

%%

caesar.yy

/* Simple parser for a Caesar language */
%{
#include <iostream>
using namespace std;
%}

/* Define built-in types */
%token INT FLOAT BSTREAM USTREAM
%token ADD SUB MUL DIV FDIV ABS
%token EOL

%%

calclist: /* nothing */
| calclist exp EOL {
cout << $2 << endl;
}
| calclist EOL {
cout << ">>> ";
}
;

exp: factor
| exp ADD exp { $$ = $1 + $3; }
| exp SUB factor { $$ = $1 - $3; }
| exp ABS factor { $$ = $1 | $3; }
;

factor: term
| factor MUL term { $$ = $1 * $3; }
| factor DIV term { $$ = $1 / $3; }
;

term: INT
| ABS term { $$ = $2 >= 0? $2 : - $2; }
;

%%

main()
{
cout << ">>> ";
yyparse();
}

yyerror(char *error)
{
cerr << error;
}

Makefile

caesar: caesar.ll caesar.yy
bison -d caesar.yy
flex caesar.ll
g++ -o $@ caesar.tab.cc lex.yy.c -lfl

Когда я пытаюсь скомпилировать его с помощью makeВижу пару ошибок:

bison -d caesar.yy
caesar.yy: conflicts: 3 shift/reduce
flex caesar.ll
g++ -o caesar caesar.tab.cc lex.yy.c -lfl
caesar.tab.cc: In function 'int yyparse()':
caesar.tab.cc:1281:16: error: 'yylex' was not declared in this scope
caesar.tab.cc:1470:35: error: 'yyerror' was not declared in this scope
caesar.tab.cc:1612:35: error: 'yyerror' was not declared in this scope
caesar.yy: At global scope:
caesar.yy:46:20: error: ISO C++ forbids declaration of 'yyerror' with no type [-fpermissive]
caesar.ll:3:24: fatal error: caesar.tab.h: No such file or directory
compilation terminated.
make: *** [caesar] Error 1

Не могли бы вы мне помочь, пожалуйста? Спасибо!

ОБНОВИТЬ: Я уже исправил ошибку с неправильным типом функции.

1

Решение

Сначала исправьте очевидные ошибки — добавьте объявления в начало caesar.yy:

int yylex(void);
void yyerror(const char *);

и возвращаемые типы для main а также yyerror (примечание — я тоже добавил const к аргументу yyerror, чтобы заставить замолчать предупреждения о передаваемых ему строковых литералах).

Вам нужны похожие тривиальные исправления к caesar.ll:

#include "caesar.tab.hh"using namespace std;

Теперь вы можете увидеть реальные ошибки:

caesar.yy: conflicts: 3 shift/reduce
caesar.ll: In function ‘int yylex()’:
caesar.ll:79:10: error: ‘RANGE’ was not declared in this scope

Второй первый — ваш сканер пытается вернуть токен RANGE, который не определен.
Можете добавить %token RANGE в caesaer.yy чтобы определить его, хотя вы не используете его (или различные другие токены, такие как BSTREAM или же USTREAM) в вашей грамматике это просто вызовет синтаксическую ошибку.

Это подводит нас к грамматическим конфликтам. На самом деле это не ошибки (скорее предупреждения), но вы действительно хотите обратить на них внимание. Добавьте флаг -v к bison команда в Makefile и вы получите caesaer.output файл с информацией о конфликтах.

Все 3 конфликта происходят из состояния 16, которое вы можете увидеть в файле .output:

state 16

5 exp: exp . ADD exp
5    | exp ADD exp .
6    | exp . SUB factor
7    | exp . ABS factor

ADD  shift, and go to state 10
SUB  shift, and go to state 11
ABS  shift, and go to state 12

ADD       [reduce using rule 5 (exp)]
SUB       [reduce using rule 5 (exp)]
ABS       [reduce using rule 5 (exp)]
$default  reduce using rule 5 (exp)

Это говорит о том, что все 3 конфликта происходят от вашего exp: exp ADD exp править. Наличие рекурсивного правила как слева, так и справа всегда неоднозначно, но в этом случае исправление очевидно — измените его на exp: exp ADD factorв соответствии с остальными вашими правилами.

4

Другие решения

http://dinosaur.compilertools.net/flex/flex_19.html Прочтите это о том, как использовать g++ с flex, Проблема в том, что вы используете его в C режим и генерирует C лексеры. использование flex с -+ переключатель.

3

FWIW, бесполезно обрабатывать ваш код вручную, чтобы увидеть, какие правила соответствуют. И Flex, и Bison делают это для вас бесплатно. Увидеть http://westes.github.io/flex/manual/Debugging-Options.html для Flex, и http://www.gnu.org/software/bison/manual/bison.html#Tracing для бизонов.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector