raj*_*uja 2 compiler-construction parsing lexical-analysis
词法分析器和解析器上的大多数资源都说明了使用流来在它们之间进行通信(或者我理解).
解释了解析器要求下一个令牌,比如通过调用一个函数getNextToken(),并且词法分析器通过返回下一个令牌来响应它.我们是否应该将它们视为在同一程序中交互的两个对象或通过流交互的两个不同程序?
此外,我还无法理解为什么没有选择串行方法,即词法分析器一直运行到提供的源的末尾,然后解析器才使用词法分析器的输出进行解析.确切地说,如果词法分析器仅在解析器请求下一个令牌时读取下一个词法,那么如何处理错误?特别是如果在文件末尾发生错误,解析器完成的所有计算都可能由于错误而浪费(假设一个非常基本的解析器没有任何错误处理功能).最近的输出缓存了吗?
我在下面的回答是仅参考Flex-Bison(或Lex-Yacc)编译模型.我对其他模型知之甚少.
我认为词法分析器/解析器组合是同一程序中的两个协作模块.当您使用Flex with Bison时,您会看到后者调用yylex()前者提供的函数(yylex()相当于getNextToken()您问题中的函数).因此,将它们视为单个程序中的协作单元而不是两个不同的程序更有意义.此外,如果词法分析器和解析器是 2个不同的程序,则必须处理进程间通信,共享内存和相关问题,这进一步使手头的任务复杂化.
回答你的第二个问题:我可以想到在词法分析器读完所有输入后解析器开始行动可能产生的一个重要问题:即使是中等大小的程序,内存使用量也会很大,因为你必须存储数据每个令牌的结构,在内存中(想想令牌,和=占用内存中的多个字节,你会很快发现它为什么不可扩展).
至于错误处理:如果词法分析器不能匹配任何正则表达式的输入,那么yylex()应该使用flex规则向解析器返回-1,如下所示:
. { return -1; }
Run Code Online (Sandbox Code Playgroud)
(注意第一列中几乎不可见的时期,它与任何输入符号匹配,除外\n)
(注意:此规则应该是出现在Flex文件中的最后一条规则,因为规则的顺序决定了优先级:Flex使用flex文件中的第一个可能规则来匹配标记.)
词法分析器返回-1表示标记化错误,Bison解析器通过调用yyerror(char *)(理想情况下由您定义)自动处理它; 否则,如果输入遇到解析错误,解析器再次调用yyerror(char *).
此外,如果您想在遇到错误时显示错误的代码段,您必须有一种方法来访问给定有缺陷令牌的相关源代码,这意味着完全读取输入的方法然后解析将除非你在标记化时将相关的源代码与每个令牌存储在一起,否则它根本就无法工作,实质上是使编译器成为一个内存巨头.
| 归档时间: |
|
| 查看次数: |
2457 次 |
| 最近记录: |