我正在开展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
答案 0 :(得分:2)
您决定输入是否可接受,然后从exit(0)
的缩减操作中调用S -> ST
。这种减少可以在解析器注意到它不在输入结束之前发生。 (这是大多数LALR解析器生成器实现的解析表优化。)
因此解析器识别if(a<b)
;观察到它无法转移}
;观察到它可以将其减少到ST
然后再减少到S
;并且永远不会有机会抛出语法错误,因为您的减少操作立即声称成功。
在减少操作中退出解析几乎绝不是一个好主意,而且肯定不是明确返回或调用exit
。如果在还原操作中检测到错误,则可以使用YYABORT
宏导致解析失败。
还有一个YYACCEPT
宏可以让我立即获得成功,但它通常会让您遇到与此处遇到的完全相同的问题。 (但它至少会干净地终止解析,释放解析器和词法扫描器正在使用的任何资源。)
几乎总是最好让解析继续,直到它检测到成功或检测到错误。您可以告诉解析成功,因为yyparse
将返回0表示成功。