2010-10-28 7 views
1

я следующий лимонную грамматику (упрощенная от реальной грамматики):Как удалить неоднозначность вызова функции из грамматики Lemon?

%right ASSIGN . 
%nonassoc FN_CALL . 

program ::= expression . 
expression ::= expression ASSIGN expression . 
expression ::= function_call . [FN_CALL] 
expression ::= IDENTIFIER . 


function_call ::= expression LPAREN RPAREN . [FN_CALL] 

Я не в состоянии зафиксировать сдвиг-свертка конфликт в следующем состоянии:

State 3: 
     expression ::= expression * ASSIGN expression 
    (1) expression ::= expression ASSIGN expression * 
     function_call ::= expression * LPAREN RPAREN 
        ASSIGN shift 1 
        LPAREN shift 4 
        LPAREN reduce 1 ** Parsing conflict ** 
       {default} reduce 1 

Моя мысль что проблема заключалась в двусмысленности между a = (b (c)) и (a = b) (c), но я бы подумал, что при вызове функции более высокий приоритет, чем назначение, это исправит. Какие-нибудь идеи, что может быть?

ответ

0

Первая и самая большая точка: конфликт с уменьшением смены редко настоящая проблема. Таким образом, это может быть то, что вам не нужно (или даже не заботьтесь), чтобы исправить.

Второй момент: к сожалению, мне кажется, что вы, возможно, слишком упростили свою грамматику. Например, грамматика (как вы ее разместили) выглядит так: a=(b(c)) и (a=b)(c) должны быть отклонены напрямую (единственное место, где вы указали LPAREN, следует немедленно указать с помощью RPAREN). То, что вы опубликовали, не дает нам достаточно, чтобы догадываться о том, что может быть неправильным с реальной грамматикой.

+0

Я только в скобках, чтобы показать двусмысленность; два возможных дерева синтаксического анализа, которые я пытался показать, - это те, где выражение верхнего уровня является вызовом функции, выражение которого «a = b» и дерево, где выражение верхнего уровня является назначением, первое выражение которого является идентификатором, а второе является вызовом функции. Проблема возникает даже в этой крошечной грамматике; есть конфликт, если вы скомпилируете это как есть. – Topoli

0

Это делает то, что вы хотите?

program ::= assignment . 

assignment ::= expression ASSIGN assignment . 
assignment ::= expression . 

expression ::= expression LPAREN RPAREN . 
expression ::= IDENTIFIER . 

Он позволяет назначать вызовы функций (что необычно), но также и ваша оригинальная грамматика. Я понимаю, что это всего лишь часть большей грамматики.

+0

Это сделало бы это, хотя да, но факт, что мне пришлось бы переписать всю грамматику, чтобы кодировать правила приоритета, вызывает у меня немного беспокойство. – Topoli

+0

Вам не придется переписывать все это. Вы могли бы, вероятно, разделить его на просто двоичные, префиксные и суффиксные операторы достаточно легко и использовать объявления% right% left в двоичных частях. – xscott