2011-12-03 13 views
0

私はbisonでパーサーを構築しようとしていますが、すべてのエラーを難しいものに絞り込んでいます。ここでBison:競合:1シフト/エラーを減らす

は、エラーがある状態でバイソンのデバッグ出力です:私はそこif_statementルールを削除する場合ここで

state 120 

    12 statement_list: statement_list . SEMICOLON statement 
    24 if_statement: IF conditional THEN statement_lists ELSE statement_list . 

    SEMICOLON shift, and go to state 50 

    SEMICOLON [reduce using rule 24 (if_statement)] 
    $default reduce using rule 24 (if_statement) 

はparser.yソース

%% 

program    : ID COLON block ENDP ID POINT 
        ; 
block    : CODE statement_list 
        | DECLARATIONS declaration_block CODE statement_list 
        ; 
declaration_block : id_list OF TYPE type SEMICOLON 
        | declaration_block id_list OF TYPE type SEMICOLON 
        ; 
id_list    : ID 
        | ID COMMA id_list 
        ; 
type     : CHARACTER 
        | INTEGER 
        | REAL 
        ; 
statement_list  : statement 
        | statement_list SEMICOLON statement 
        ; 
statement_lists  : statement 
        | statement_list SEMICOLON statement 
        ; 
statement   : assignment_statement 
        | if_statement 
        | do_statement 
        | while_statement 
        | for_statement 
        | write_statement 
        | read_statement 
        ; 
assignment_statement : expression OUTPUTTO ID 
        ; 
if_statement   : IF conditional THEN statement_lists ENDIF 
        | IF conditional THEN statement_lists ELSE statement_list 
        ; 
do_statement   : DO statement_list WHILE conditional ENDDO 
        ; 
while_statement  : WHILE conditional DO statement_list ENDWHILE 
        ; 
for_statement  : FOR ID IS expression BY expressions TO expression DO statement_list ENDFOR 
        ; 
write_statement  : WRITE BRA output_list KET 
        | NEWLINE 
        ; 
read_statement  : READ BRA ID KET 
        ; 
output_list   : value 
        | value COMMA output_list 
        ; 
condition   : expression comparator expression 
        ; 
conditional   : condition 
        | NOT conditional 
        | condition AND conditional 
        | condition OR conditional 
        ; 
comparator   : ASSIGNMENT 
        | BETWEEN 
        | LT 
        | GT 
        | LESSEQUAL 
        | GREATEREQUAL 
        ; 
expression   : term 
        | term PLUS expression 
        | term MINUS expression 
        ; 
expressions   : term 
        | term PLUS expressions 
        | term MINUS expressions 
        ; 
term     : value 
        | value MULTIPLY term 
        | value DIVIDE term 
        ; 
value    : ID 
        | constant 
        | BRA expression KET 
        ; 
constant    : number_constant 
        | CHARCONST 
        ; 
number_constant  : NUMBER 
        | MINUS NUMBER 
        | NUMBER POINT NUMBER 
        | MINUS NUMBER POINT NUMBER 
        ;    
%% 

に翻訳ルールですエラーはないので、かなり絞り込んだが、それでもエラーを解決することはできない。

ありがとうございました。

+0

あなたの構文は他のすべてのコンストラクトと同様に、どのようにendifで終了し、if-elseはendifで終了しますか? – Hobblin

+0

また、私はentierly確信していないが、私は "else_statement"特別な "else_statement"を指定すると同じような問題を解決したと思う "else文"または空の場合と "if文else_statement'を指定する – Hobblin

+0

ありがとうたくさん。私はそれを逃したと信じられない:) – Lee

答えて

3

次のステートメントを考慮してください。if条件then s2 else s3;

if condition then 
    s1; 
else 
    s2; 
s3; 

他方は次のとおりです:S4

は二つの解釈がある最初のもので

if condition then 
    s1; 
else 
    s2; 
    s3; 

、なステートメントのリストがifの文とs3で構成されています。他のステートメントは1つのifステートメントだけで構成されています。それはあいまいさの原因です。 Bisonはshift-reduce競合が存在するときにshiftを減らすことを好みます。したがって、上記の場合、パーサはs3をシフトすることを選択します。

あなたif-then文でENDIFを持っているので、問題が解決され、あなたのif-then-else文でENDIFを導入することを検討してください。

+0

それを指摘してくれてありがとう! – Lee

2

IF-THEN-ELSE-ENDIFルールにはENDIFがありません。

+0

応答ありがとう – Lee