yacc - как выполнить условие if - PullRequest
1 голос
/ 10 февраля 2012

Я пытаюсь выполнить простое условие if из входного файла.

У меня будет что-то вроде

if(color = black)

Независимо от того, что я делаю, я получаю 1 сдвиг / уменьшение.я очень плохо знаком с lex и yacc. Часто ли в грамматике YACC возникают конфликты с уменьшением числа сдвигов?и я не должен беспокоиться о них?

Мой файл lex вернет каждый символ в файле правильно, поэтому я не покажу вам файл lex

Однако, вот мой файл yacc:

%{

#include <ctype.h>
#include <stdio.h>

%}
 |IF LPAREN COLOR EQ BLACK RPAREN  {$$ = $1;  printf("WONT COMPILE\n");} 
     ;

в файле yacc я пробовал это, но именно здесь я получаю сдвиг / уменьшение

IF LPAREN COLOR EQ BLACK RPAREN {$$ = $1;  printf("If statement\n");} 

решено

1 Ответ

2 голосов
/ 10 февраля 2012

Первоначально я написал длинный ответ о двусмысленности, но затем я внимательно рассмотрел вашу грамматику.Давайте немного уменьшим его и покажем, в чем проблемы:

%token IF COLOR BLACK
%%
statement
    : statement command
    | /*nothing*/
    ;

command
    : IF              {$$ = $1; printf ("IF\n");}
    | ELSE            {$$ = $1; printf("ELSE\n");}
    | EQ              {$$ = $1; printf("EQ\n");}
    | THEN            {$$ = $1; printf("THEN\n");}
    | LPAREN          {$$ = $1; printf("LPAREN\n");}
    | RPAREN          {$$ = $1; printf("RPAREN\n");}
    | COLOR EQ BLACK  {$$ = $3; printf("color is black\n");}
    | IF LPAREN COLOR EQ BLACK RPAREN  {$$ = $1;  printf("WONT COMPILE\n");} 
    ;

Как вы ожидаете, что выражение if(color = black) будет проанализировано?Обратите внимание, что «color = black» может уменьшиться до command через COLOR EQ BLACK или может быть «сдвинут» в стек, чтобы стать частью более длинного анализа IF LPAREN COLOR EQ BLACK RPAREN.

Это объясняет конкретное предупреждениевы получаетеТеперь перейдем к остальной части вашей грамматики:

Вы не хотите писать свою грамматику, поэтому неполные утверждения имеют смысл.Обратите внимание, что одиночный символ «=» является полным действительным command и, следовательно, полным действительным statement - это действительно то, что вы хотите?

Вы собираетесь переписать это с нуля,Начните с простого:

%token NUMBER COMMAND IF THEN ELSE COLOR BLACK
%%
statement
    : COMMAND NUMBER
    | IF cond THEN statement
    | /* nothing */
    ;
cond
    : '(' COLOR '=' BLACK ')'
    ;

Не проверено;но этого должно быть достаточно, чтобы вы начали.Если вам нужно что-то сделать при обнаружении токена, вы можете (например) заменить IF cond THEN COMMAND на if cond then command и добавить правила, такие как

if  : IF   { printf("%s\n", "IF"); }
    ;
then: THEN { printf("%s\n", "THEN"); }
    ;

Начните с простого, добавляйте медленно и выполняйте рефакторинг при получении правилслишком волосатый или повторяющийся.И проработайте учебное пособие, прежде чем приступить к большому проекту.Руководство GNU Bison содержит хороший учебник, как и Kernighan & Pike's Среда программирования Unix .

...