当缺少时,flex / bison接受开口支撑

时间:2017-12-01 07:53:04

标签: compiler-construction bison flex-lexer yacc

我正在开展flex / bison。

问题是,当我输入if(a<b)}时,它接受了它,但是缺少一个左大括号。

下面是语法:

S : ST { printf("\nCORRECT INPUT\n"); exit(0); }

ST : IF  OB Expr1 CB | IF OB Expr1 CB OCB CCB 

Expr1 : ID EQ ID
    | ID EQ NUM
    | NUM EQ NUM
    | NUM EQ ID
    | ID NE ID
    | ID NE NUM
    | NUM NE NUM
    | NUM NE ID
    | ID LT ID
    | ID LT NUM
    | NUM LT NUM
    | NUM LT ID
    | ID GT ID
    | ID GT NUM
    | NUM GT NUM
    | NUM GT ID
    | ID LE ID
    | ID LE NUM
    | NUM LE NUM
    | NUM LE ID
    | ID GE ID
    | ID GE NUM
    | NUM GE NUM
    | NUM GE ID

1 个答案:

答案 0 :(得分:2)

您决定输入是否可接受,然后从exit(0)的缩减操作中调用S -> ST。这种减少可以在解析器注意到它不在输入结束之前发生。 (这是大多数LALR解析器生成器实现的解析表优化。)

因此解析器识别if(a<b);观察到它无法转移};观察到它可以将其减少到ST然后再减少到S;并且永远不会有机会抛出语法错误,因为您的减少操作立即声称成功。

在减少操作中退出解析几乎绝不是一个好主意,而且肯定不是明确返回或调用exit。如果在还原操作中检测到​​错误,则可以使用YYABORT宏导致解析失败。

还有一个YYACCEPT宏可以让我立即获得成功,但它通常会让您遇到与此处遇到的完全相同的问题。 (但它至少会干净地终止解析,释放解析器和词法扫描器正在使用的任何资源。)

几乎总是最好让解析继续,直到它检测到成功或检测到错误。您可以告诉解析成功,因为yyparse将返回0表示成功。