2015-12-08 5 views
-1

я создал простую грамматику для сложения и вычитания:Как сбросить дерево разбора

S : EXPRESSION ENDLINE  {printf("Result: %d\n",$1);}  
    ; 

EXPRESSION 
    : NUMBER '+' NUMBER  {$$ = $1 + $3;}   
    | NUMBER '-' NUMBER   {$$ = $1 - $3;}  
    ; 

NUMBER : NUM   {$$ = $1;} 
     ; 

%% 

После достижения S терминала Я хотел бы написать новый вход после первого результата печати. К сожалению, после ввода второй формулы я получил синтаксическую ошибку. Как я могу это достичь? Я был бы благодарен за помощь.

ответ

1

Речь идет не об перезагрузке дерева разбора; вам нужно расширить грамматику, чтобы разрешить любое количество строк, содержащих выражения. Просто разверните правило S включать рекурсивные вызовы, например:

S : EXPRESSION ENDLINE  {printf("Result: %d\n",$1);} 
    | S EXPRESSION ENDLINE  {printf("Result: %d\n",$2);} 
    ; 

Это может быть немного липким, так что вы можете добавить новое правило к тому же эффекту:

S: RESULT 
| S RESULT 
; 

RESULT : EXPRESSION ENDLINE  {printf("Result: %d\n",$1);} 
+0

Первый выигранный» t работает, как ожидалось, так как будет распечатывать результаты в обратном порядке и только после завершения ввода. Второй будет работать, но будет бесполезно переваривать стек парсера. Всегда используйте левую рекурсию, если у вас нет действительно веской причины. – rici

+0

@rici - Да, вы правы, как обычно. Я отредактировал, чтобы показать левую рекурсию, как я должен был сделать в первую очередь! –