2015-04-09 1 views
0
... 
IF LP assignment-expression RP marker statement { 
    backpatch($3.tlist,$5.instr); 
    $$.nextList = mergeList($3.flist,$6.nextList); 
} 
|IF LP assignment-expression RP marker statement ELSE Next statement { 
    backpatch($3.tlist,$5.instr); 
    backpatch($3.flist,$8.instr); 
    YYSTYPE::BackpatchList *temp = mergeList($6.nextList,$8.nextList); 
    $$.nextList = mergeList(temp,$9.nextList); 
} 
... 

Выражение-присваивание - любое выражение присваивания, которое возможно с использованием операторов C =, +=, -=, *=, /=.Перевод if then else в грамматику компилятора

LP = (
RP =) 

и Next оба EMPTY правила

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

bool a; 
if(a){ 
    printf("hi"); 
} 
else{ 
    prinf("die"); 
} 

Он ожидает, что назначение -выражение должно содержать relop или OR или AND до generate correct code. Так как в этом случае мы проводим сравнение для relop, то этот же случай относится к OR и AND.

Но, как и в приведенном выше кодексе, это не содержит ничего, поэтому он не может создать правильный код. Правильный код может быть сгенерирован с использованием следующего правила, но это приводит к two reduce-reduce conflict.

... 
    IF LP assignment-expression { 
    if($3.flist == NULL && $3.tlist == NULL) 
     ... 
     } RP marker statement { 
      ... 
    } 
    |IF LP assignment-expression{ 
    if($3.flist == NULL && $3.tlist == NULL) 
    ... 
    } RP marker statement ELSE Next statement { 
     ... 
    } 
    ... 

Какая модификация должна быть сделана в правиле грамматики, чтобы она работала должным образом?

Я попробовал IF ELSE grammar rule отсюда, а также от книги драконов, но не смог решить эту проблему. Целую грамматику можно найти здесь Github

+0

Я использовал гибкий зубров несколько лет назад и вспомнить такого рода ситуации.. Я считаю, что решение заключается в использовании условий запуска в lexer для введения разных правил. Синтакс с моим старым гибким бизоном скользко отличается. Надеюсь, это поможет. –

ответ

1

Похоже, ваша грамматика имеет неправильное определение expression.

Выражение присваивания является лишь одним из многих нетерминалов, которые должны быть способны свести к выражению. Для построения if/then/else вам обычно необходимо указать любое выражение, которое должно происходить между parens. Ваш первый пример, как вы указываете, является вполне допустимым C, но не содержит задания.

В вашей грамматике, у вас есть эта строка:

/*Expression list**/ 
expression: 
assignment-expression{} 
|expression COMMA assignment-expression{} 
; 

Однако, выражение должно быть в состоянии иметь больше назначений выражений. Не будучи очень знаком с Yacc/бизона, я думаю, вы должны изменить это на что-то вроде следующего:

/*Expression **/ 
expression: 
assignment-expression{} 
|logical-OR-expression{} 
|logical-AND-expression{} 
|inclusive-OR-expression{} 
|exclusive-OR-expression{} 
|inclusive-AND-expression{} 
|equality-expression{} 
|relational-expression{} 
|additive-expression{} 
|multiplicative-expression{} 
|exponentiation-expression{} 
|unary-expression{} 
|postfix-expression{} 
|primary-expression{} 
|expression COMMA expression{} 
; 

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

Возможно, вам будет полезно прочитать или посмотреть некоторые уроки на how LR grammars work.

+0

Я взял грамматику из программирования С Деннисом Ричи. –

+0

У меня нет K & R передо мной. Если вы хотите получить более подробный ответ, можете ли вы обновить свой вопрос с помощью большей части соответствующей грамматики? Например, все правила, которые сводятся к 'assign_expression'? – seanmk

+0

Правильно, мне не нужно видеть всю грамматику. Давайте начнем с правил, где левая сторона - 'присваивание_выражения'. – seanmk

1

Для того чтобы вставить действие среднего действия, вам нужно левое-фактор; в противном случае созданный бизоном анализатор не может решить, какой из двух MRA должен уменьшить. (Хотя они, по-видимому, идентичны, бизон этого не знает.)

if_prefix: "if" '(' expression ')' { $$ = $3; /* Normalize the flist */ } 
if: if_prefix marker statement { ... } 
    | if_prefix marker statement "else" Next statement { ... } 

(Вы могли бы оставили фактор по-другому, это только одно предложение)

 Смежные вопросы

  • Нет связанных вопросов^_^