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 : 다음은 문법 파일입니다. prefix/postfix와 prepost_operand를 실험적으로 제거하여 충돌이 적어도 조금은 바뀌는 지 확인했지만 두 충돌이 남았습니다. 문법을 많이 변경하지 않고 이러한 충돌을 해결할 수있는 방법이 있습니까? 아니면 완전히 잘못된 경로로 이동 했습니까?

print expression more_expressions 

more_expressions이 (가 아마 덜 혼란을 expression_list를 호출해야하므로) 식의 목록과 일치 :

답변

1

문제는 누구의 오른쪽 측면입니다 생산이다. 연속적으로 두 개의 연속 된 expression이 분명히 모호합니다 (두 표현식을 사용할 수 있다면 1+1+11+1이고 그 다음은 +1 또는 1이고 그 뒤에 +1+1입니까?). 원하는 것은 단지

print more_expressions 
+0

감사합니다! 나는 그것이 바보 같은 실수라고 믿을 수 없다 ... – user113377

+0

@ user113377 이것은 이름 짓기가 중요한 이유이다 :-) – rici