如何仅在Bison中到达文件结尾时打印语句?
为了简化原始问题,假设我想要解析一个左括号和右括号字符串。flex文件将具有令牌如何仅在Bison中到达文件结尾时打印语句?,bison,flex-lexer,Bison,Flex Lexer,为了简化原始问题,假设我想要解析一个左括号和右括号字符串。flex文件将具有令牌 "(" return LPAREN ")" return RPAREN 而野牛档案会有这些作品 completedparse: pair {printf("Success!\n");} ; pair: LPAREN pair RPAREN | LPAREN RPAREN pair | LPAREN RPAREN ; 如果给定字符串“(())”或“(())”,它将成功 我的问题是“(())”会在失
"(" return LPAREN
")" return RPAREN
而野牛档案会有这些作品
completedparse: pair {printf("Success!\n");}
;
pair: LPAREN pair RPAREN
| LPAREN RPAREN pair
| LPAREN RPAREN
;
如果给定字符串“(())”或“(())”,它将成功
我的问题是“(())”会在失败之前立即打印成功声明。我知道野牛创造了生产
$accept: completedparse $end
这就是bison接受或拒绝字符串的方式。如果我能写我自己的$accept产品,并在该产品中包含任何打印语句,我的所有问题都会消失。但是根据3.0.2手册,语法中不能使用$accept
如果我可以修改yyparse()的返回值,我的问题也会消失(假设我需要的信息不仅仅是0=>success,1=>failure)。但我认为这是不可能的
如果您有任何见解,请回复,并感谢您的帮助 一个简单的解决方案:
completedparse: pair {printf("Success!\n");}
| pair error
;
错误
伪终端不会匹配所有错误,但它将匹配预期EOF和发现其他错误的错误。如果在其他上下文中遇到错误,则不会应用错误产品。一般来说,您应该使用yyerror
对语法错误执行操作;上述规则只是一种避免在输入末尾有垃圾的情况下调用completedparse
操作的方法
顺便说一下,您的语法与(())()
不匹配。您可能需要使用:
pair: /* EMPTY */
| '(' pair ')' pair
;
另外:
针对评论中的增编:
{YYABORT}
,以便立即返回(返回值为1,表示语法错误)。如果要打印一般错误消息,最好在yyerror
实现中这样做,因为任何语法错误都会调用它,而error
生成只会在某些错误上减少。您可以使用error
productions生成更具体的错误消息,但这需要做更多的工作$accept
伪产品。然而,上述技术或多或少是等效的yyparse
的返回类型或值(0成功,1语法错误,2分配错误)。但是,从解析(例如,AST)返回更多数据通常很有用。“传统”的解决方案是只使用一个全局变量,但对于我们这些不喜欢全局变量的人来说,另一个解决方案是使用[%parse param][1]
声明添加一个或多个附加参数;通常,开始生产将设置这些参数指向的对象的值。如果执行此操作,则在依赖其他返回信息之前,应始终检查yyparse
的返回值,因为即使在出现错误的情况下,也可能会对开始生产进行评估这个语法与实际作业不接近,我创建的真正语法除了错误问题外是正确的。@CullenS:是的,我想,但如果其他人发现这个问题,我认为值得修复。这个语法与实际作业不接近,我创建的真正语法除了错误问题外是正确的。我知道错误标记,但是如果我包括它,那么yyparse返回的值不是0表示成功,不是1吗?但是,如果我在“pairerror”生成之后放一个print错误语句,那就不会有问题了。需要明确的是,定制$accept生产和/或更改yyparse的返回值是不可能的?顺便说一句,非常感谢你的帮助。非常感谢你的帮助,非常有洞察力。