2016-05-20 7 views
0

У меня есть два очень маленьких файла (в попытке удалить все другие смешающие переменные), написанные в Lex и Yacc, соответственно.Моя программа «Лекс» и «Yacc» запускается после того, как она прекрасна, а затем падает со второй попытки?

Lex:

%{ 
    #include <stdlib.h> 
    #include "y.tab.h" 
    void yyerror(char *); 
%} 

%% 

[a] { 
    yylval = *yytext; 
    return VAR; 
    } 

[ \t\n] ; 

. yyerror("invalid character"); 

%% 

int yywrap(void) { 
return 1; 
} 

Yacc:

%token VAR 

%{ 
    void yyerror(char *); 
    int yylex(void); 
    #include <stdio.h> 
%} 

%% 

butts: 
    VAR { printf("%d\n", $1); } 

%% 

void yyerror(char *s) { 
    fprintf(stderr, "%s\n", s); 
} 


int main(void) { 
    #if YYDEBUG 
    yydebug = 1; 
    #endif 
    yyparse(); 
    return 0; 
} 

и когда я компилирую все это (с -DYYDEBUG) вариант, я получаю выход:

Starting parse 
Entering state 0 
Reading a token: a 
Next token is token VAR() 
Shifting token VAR() 
Entering state 1 
Reducing stack by rule 1 (line 12): 
    $1 = token VAR() 
97 
-> $$ = nterm butts() 
Stack now 0 
Entering state 2 
Reading a token: a 
Next token is token VAR() 
syntax error 
Error: popping nterm butts() 
Stack now 0 
Cleanup: discarding lookahead token VAR() 
Stack now 0 

когда вводя «a» дважды. В первый раз, когда я нажимаю «а», когда он спрашивает Reading a token:, программа, похоже, работает нормально, но во второй раз она рвется.

Я в затруднении относительно того, почему это так.

+2

FWIW, «crash» обычно означает segfault или некоторые такие, в то время как я бы интерпретировал «рвоту», чтобы означать «производит огромное количество бесполезного выхода». Если ответ Брайана правильный, фактический проблемный симптом будет «во второй раз, когда он сообщит о синтаксической ошибке». Точные описания проблем облегчают поиск проблем. Нет ничего плохого в некоторой неформальности или юморе, но когда вы сообщаете о проблеме, всегда хорошо четко указывать (1), что произошло; (2) то, что вы ожидали; и (3) как они отличаются. – rici

ответ

3

Это потому, что ваш файл грамматики говорит, что разрешено только одно «а». Еще одна ошибка, и вы получаете ошибку. В правиле вашей грамматики указано:

butts: VAR 

ничего более, не меньше.

Таким образом, действует только программа, которая соответствует вашей грамматике:

a 

Любой другой вход, например:

aa 

или:

a 
a 

Вызовет ошибку синтаксиса , Ваше правило очень прямо говорит один VAR только; не последовательность ВАРС; не несколько варов. Только один VAR.

Если вы хотите, чтобы он соответствовал более чем одному во входном сигнале, вы должны сказать. Таким образом, грамматика должна описывать разрешенную последовательность:

butts: VAR | butts VAR 

Тогда это позволит последовательность.

Яснее?

+0

Короче говоря, прикладам должно быть разрешено быть как прикладами (начиная с рекурсивного дерева), так и var, что является концом ветки (единственное решение)? – Stegosaurus