使用 yacc 和 lex 编写文本分析器
2008-11-13 08:32:06 来源:WEB开发网全局/Header 定义与 lex/flex 文件中所使用的定义相同,如果您在分析和处理输出时使用了特殊的函数,那么它们都是必需的。
标记定义不仅描述了预期的标记,还描述了分析处理过程中的优先级。通过迫使 yacc 按照特定的顺序检查标记,这可以调整 yacc 对规则的处理方式,并且还影响到在与规则进行比较时如何对表达式进行处理。
例如,您通常可以定义 + 标记具有左优先级,也就是说,首先对这个标记左边的任何表达式进行匹配,这样一来,表达式 4+5+6 首先会计算 4+5,然后计算 9+6。
然而,您可能希望为一些标记指定右优先级,例如,计算逻辑 NOT,(例如,! (expr))您可能希望先计算 expr,然后对通过 ! 标记对其表达式的值取反。
除了控制规则之间的优先级关系之外,还可以指定标记的优先级,这样您就可以精确地控制如何对输入进行计算。
有三种主要的标记类型,%token(没有优先级差别),%left(标记左侧的输入具有优先级)和 %right(标记右侧的输入具有优先级)。例如,清单 10 根据适当的优先级定义了若干标记:
清单 10. 根据适当的优先级定义若干标记
%token EQUALS POWER
%left PLUS MINUS
%left MULTIPLY DIVIDE
%right NOT
请注意,以自上而下优先级递增的顺序指定标记的优先级,并且同一行中的标记具有相同的优先级。在清单 10 所示的示例中,MULTIPLY 和 DIVIDE 具有相同的优先级,该优先级要高于 PLUS 和 MINUS 的优先级。
请注意,如果在规则中使用这里没有定义的任何标记,则将引发一个错误。
自定义初始化和错误
您将要定义的两个关键的函数是 main() 函数(可以将自定义的初始化和其他的处理放在这个函数中),以及 yyerror() 函数(当对于输入信息无法找到一条分析规则时将打印出一个错误)。由 yacc 生成的进行实际分析工作的函数称为 yyparse()。自定义函数的典型定义如清单 11 所示。
更多精彩
赞助商链接