0

我想爲minipython的一個版本(使用後綴/前綴增量和減量運算符)編寫sablecc的規範文件,有些產品自然需要使用標識符,但是我在解析期間得到這些衝突: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: 

我開始遵循給定的語言bnf並得到了這一點。 這裏是語法文件:

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。 我通過實驗刪除了前綴/後綴和prepost_operand以查看衝突是否至少會稍微改變,但這隻會導致最後兩次衝突。 有沒有什麼辦法可以解決這些衝突,而不用更改語法呢,或者我是否完全弄錯了路徑?

回答

1

的問題是它的右側是生產:

print expression more_expressions 

more_expressions匹配表情列表(所以它可能應該叫expression_list是減少混亂)。兩條連續的expression s通常顯然不明確(如果您可以有兩個表達式,1+1+11+1,然後是+11,然後是+1+1?)。你想要的只是

print more_expressions 
+0

謝謝!我不敢相信這是一個愚蠢的錯誤... – user113377

+0

@ user113377這就是命名很重要的原因:-) – rici