我正在实现一个小外壳,并使用 lex&yacc 来解析命令。Lex 从 读取命令stdin
, yacc 在 之后执行命令yyparse
。
问题是,当出现语法错误时,yacc 会提示错误并从头开始解析。在这种情况下,cmd1 >>> cmd2
会导致运行,cmd2
因为>>>
是语法错误。
我的问题是在遇到语法错误后如何丢弃当前命令的其余部分?
我正在实现一个小外壳,并使用 lex&yacc 来解析命令。Lex 从 读取命令stdin
, yacc 在 之后执行命令yyparse
。
问题是,当出现语法错误时,yacc 会提示错误并从头开始解析。在这种情况下,cmd1 >>> cmd2
会导致运行,cmd2
因为>>>
是语法错误。
我的问题是在遇到语法错误后如何丢弃当前命令的其余部分?
如果您想编写一种交互式语言,其提示允许用户输入表达式,那么在整个输入流上简单地使用 yacc 是个坏主意。Yacc 可能会对一行中的某些内容感到困惑,然后误解后续行。例如,用户可能在第一行有一个不平衡的括号。或未关闭的字符串文字,然后 yacc 将继续使用输入的后续行,以关闭构造。
最好从用户那里收集输入行,然后将其解析为一个单元。就 Yacc 而言,行尾只是输入的结束。
如果您使用的是 lex,有一些方法可以重定向 lex 以从内存中的缓冲区而不是FILE *
流中读取字符。查找有关YY_INPUT
宏的文档,您可以在 Lex 文件中定义这些文档,以基本上指定 Lex 用于获取输入字符的代码。
类比时间:使用 lex/yacc 开发的扫描仪直接处理交互式用户输入有点像使用scanf
处理用户输入。而将一行捕获到缓冲区然后解析它更像是使用sscanf
. 引用:
用 sscanf 解析字符串是非常合适的(只要检查了返回值),因为它很容易重新获得控制,重新开始扫描,如果输入不匹配则丢弃等等。 [comp.lang.c FAQ , 12.20]。