关键字和标识符之间的有效区分

时间:2012-02-04 18:31:22

标签: performance compiler-construction lexical-analysis

我正在构建编译器并在词法分析器阶段:

最初在符号表中安装保留字。符号表条目的字段表示这些字符串从不是普通的标识符,并告诉它们代表哪个标记。我们假设这种方法在图3.14中使用。当我们找到一个标识符时,对installID的调用将它放在符号表中(如果它还不存在)并返回一个找到的lexeme的符号表条目。当然,在词法分析期间符号表中的任何标识符都不能是保留字,因此其标记为id。函数getToken检查找到的lexeme的符号表条目,并返回该lexeme表示id或最初安装在表中的一个关键字标记的符号tablesays的任何标记名称。

但是现在每当我识别出关键字时,我都必须通过整个符号表,就像比较每个关键字/ Id识别的'​​n'元素一样。 不要太低效。我还能做什么?

请帮助。

3 个答案:

答案 0 :(得分:3)

如果你构建一个有限状态自动机来识别词位,那么它的终端状态应该与语言词汇相对应。

您可以将关键字保留在FSA之外,并且对于看起来像标识符的字符串,您最终只会使用单个终端状态。这是手动编码FSA时的常见实现。你现在遇到了问题。作为符号表的实际问题,无论您使用关键字做什么,您都需要非常快速的标识符查找,这几乎表明您需要哈希解决方案。如果你有这个,那么你可以快速查找并检查你的“它必须是一个关键字”位。存在大量良好的哈希方案;像往常一样,Wikipedia on hash functions是一个非常好的起点。这是一个实用的解决方案;我在我的PARLANSE编译器中使用它(参见我的bio),它在几十秒内处理百万行文件。

这不是最快的解决方案。最好在FSA中包含关键字(这往往会鼓励使用词法分析器生成器,因为将所有关键字添加到手动编码的FSA中是不方便的,但并不难)。如果您这样做,并且您的关键字看起来像标识符,例如转到,则会有终端状态实际上表明您已识别出恰好拼写为特定关键字的标识符。

您如何解释最终状态取决于您。一个明显的选择是这样的结束状态表明你找到了一个关键字。无需哈希表查找。

答案 1 :(得分:0)

您可以将哈希表用于关键字列表。它使您的搜索O(1)复杂性

答案 2 :(得分:0)

您可以使用与perfect hash一起生成的gperf