2017-01-09 11 views
4

Iam пытается разработать программу для калькулятора с использованием lex и yacc. Я продолжаю получать следующую ошибку:Неустранимая ошибка: символ начала не получает никакого предложения

calc.y: warning: 5 nonterminals useless in grammar [-Wother] 
calc.y: warning: 8 rules useless in grammar [-Wother] 
calc.y:8.1: fatal error: start symbol I does not derive any sentence 
I : E '\n' {printf("%d\n",$1);} 

Я смотрел на похожие проблемы, но у них были бесконечные рекурсии, но этого не было.

calc.l

%{ 
#include"y.tab.h" 
%} 

digits [0-9]* 

%% 
{digits} {return DIGITS} 
%% 

int yywrap() 
{ 
} 

calc.y

%{ 
    #include<stdio.h> 
%} 

%token DIGITS 

%% 
I : E '\n' {printf("%d\n",$1);} 
    ; 
E : E '+' F {$$ = $1 + $3;} 
    | E '-' F {$$ = $1 - $3;} 
    ; 
F : F '*' G {$$ = $1 * $3;} 
    | F '/' G {$$ = $1/$3;} 
G :'('E')' 
    | DIGITS 
    ; 
%% 

int main() 
{ 
    yyparse(); 
} 
int yyerror() 
{ 
} 

ответ

3

Я не знаю Yacc, но:

  • Чтобы построить I, вам нужен E:

    I : E '\n' 
    
  • Чтобы построить E, вам нужен E:

    E : E '+' F 
        | E '-' F 
    

Поскольку не существует никакого способа построить E, если вы еще не один (а в в начале у вас ничего нет), нет способа построить I.

Или смотреть на него с другой стороны: E бесконечно рекурсивно, потому что он всегда обращается к себе.


Если мы начнем с лексером, мы получаем DIGITS первый.

DIGITS может использоваться для сборки G.

Но нет ничего, что мы можем сделать с G, поскольку единственные правила, которые его используют (F '*' G и F '/' G) также требуют F продолжить, и мы не имеем F. Поэтому мы застряли.

+0

Но в конце мы используем токен DIGITS.So он должен заканчиваться там –

+0

@anoop, но вы никогда не дойдете до конца, потому что 'E' не может вывести ни одного' F', ни 'F' a' G' , – rici

+0

@Anoopsaju Внесены изменения в мой ответ. – melpomene