0

Я пытаюсь написать файл спецификации для sablecc для версии minipython (с операторами поэтапного и декрементирования постфикса/префикса), и некоторым продуктам, естественно, нужно использовать идентификаторы, но i получить эти конфликты во время разбора:Sablecc сменяет/уменьшает конфликты в продуктах с идентификаторами

shift/reduce conflict in state [stack: TPrint TIdentifier *] on TPlusPlus in { 
    [ PMultiplication = TIdentifier * ] followed by TPlusPlus (reduce), 
    [ PPostfix = TIdentifier * TPlusPlus ] (shift) 
} 

shift/reduce conflict in state [stack: TPrint TIdentifier *] on TMinusMinus in { 
    [ PMultiplication = TIdentifier * ] followed by TMinusMinus (reduce), 
    [ PPostfix = TIdentifier * TMinusMinus ] (shift) 
} 

shift/reduce conflict in state [stack: TPrint TIdentifier *] on TLPar in { 
    [ PFunctionCall = TIdentifier * TLPar PArglist TRPar ] (shift), 
    [ PFunctionCall = TIdentifier * TLPar TRPar ] (shift), 
    [ PMultiplication = TIdentifier * ] followed by TLPar (reduce) 
} 

shift/reduce conflict in state [stack: TPrint TIdentifier *] on TLBr in { 
    [ PExpression = TIdentifier * TLBr PExpression TRBr ] (shift), 
    [ PMultiplication = TIdentifier * ] followed by TLBr (reduce), 
    [ PPostfix = TIdentifier * TLBr PExpression TRBr TMinusMinus ] (shift), 
    [ PPostfix = TIdentifier * TLBr PExpression TRBr TPlusPlus ] (shift) 
} 
java.lang.RuntimeException: 

Я начал с того, что получил заданное значение в этом языке и добрался до этого. Вот файл грамматики:

Productions 
goal = {prgrm}program* ; 

program = {func}function | {stmt}statement; 

function = {func}def identifier l_par argument? r_par semi statement ; 

argument = {arg} identifier assign_value? subsequent_arguments* ; 

assign_value = {assign} eq value ; 

subsequent_arguments = {more_args} comma identifier assign_value? ; 

statement = {case1}tab* if comparison semi statement 
      | {case2}tab* while comparison semi statement 
      | {case3}tab* for [iterator]:identifier in [collection]:identifier semi statement 
      | {case4}tab* return expression 
      | {case5}tab* print expression more_expressions 
      | {simple_equals}tab* identifier eq expression 
      | {add_equals}tab* identifier add_eq expression 
      | {minus_equals}tab* identifier sub_eq expression 
      | {div_equals}tab* identifier div_eq expression 
      | {case7}tab* identifier l_br [exp1]:expression r_br eq [exp2]:expression 
      | {case8}tab* function_call; 

comparison = {less_than} comparison less relation 
      | {greater_than} comparison great relation 
      | {rel} relation; 

relation = {relational_value} relational_value 
     | {logic_not_equals} relation logic_neq relational_value 
     | {logic_equals} relation logic_equals relational_value; 

relational_value = {expression_value} expression_value 
     | {true} true 
     | {false} false; 

expression = {case1} arithmetic_expression 
      | {case2} prefix 
      | {case4} identifier l_br expression r_br 
      | {case9} l_br more_values r_br; 

more_expressions = {more_exp} expression subsequent_expressions*; 

subsequent_expressions = {more_exp} comma expression; 

arithmetic_expression = {plus} arithmetic_expression plus multiplication 
     | {minus} arithmetic_expression minus multiplication 
     | {multiplication} multiplication ; 

multiplication = {expression_value} expression_value 
     | {div} multiplication div expression_value 
     | {mult} multiplication mult expression_value; 

expression_value = {exp} l_par expression r_par 
       | {function_call} function_call 
       | {value} value 
       | {identifier} identifier ; 

prefix = {pre_increment} plus_plus prepost_operand 
     | {pre_decrement} minus_minus prepost_operand 
     | {postfix} postfix; 

postfix = {post_increment} prepost_operand plus_plus 
     | {post_decrement} prepost_operand minus_minus; 

prepost_operand = {value} identifier l_br expression r_br 
       | {identifier} identifier; 

function_call = {args} identifier l_par arglist? r_par; 

arglist = {arglist} more_expressions ; 

value = {number} number 
     | {string} string ; 

more_values = {more_values} value subsequent_values* ; 

subsequent_values = comma value ; 

number = {int} numeral    
     | {float} float_numeral ; 

где идентификатор, конечно, маркер, и проблематичные производства, где ее можно найти в function_call, prepost_operand, expression_value. Я экспериментально удалил префикс/postfix и prepost_operand, чтобы увидеть, будут ли конфликты, по крайней мере, немного изменяться, но это просто оставляет два последних конфликта. Есть ли способ разрешить эти конфликты, не меняя грамматики, или я пошел по совершенно неправильному пути?

ответ

1

Проблема является производство которого правая рука:

print expression more_expressions 

more_expressions соответствует список выражений (так что, вероятно, следует назвать expression_list быть менее запутанной). Два последовательных expression s в правиле явно неоднозначны (если бы у вас было два выражения, было бы 1+1+1 be 1+1, а затем +1 или 1, а затем +1+1?). Вы хотите только

+0

Спасибо! Я не могу поверить, что это была такая идиотская ошибка ... – user113377

+0

@ user113377 Вот почему именование важно :-) – rici

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