编写编译器时,如何检查标记?

When writing a compiler, how are tokens checked?

如果遇到某个关键字,编译器在决定做什么时是否使用 if 语句?编写编译器的人是否应该在检查代码时将它们用于大多数操作?或者有没有更有效的方法?例如,当我针对符号 table 测试一个符号并且它作为有效的 "token" 返回时,我是否必须使用 if 语句来确定对每个关键字执行的操作,因为它似乎相当低效,例如伪代码:

/*Each keyword/token in my compiler has a numerical representation which is what the symbol table returns back for example #define IF 0 and so on*/  
if(Token == IF){
  //This will be done to generate the AST representation for IF statements
}else if(Token == ELSE){
  //This will be done to generate the AST representation of an if statement
}else if(Token == INT){
  //This will be done to generate the AST represnetation of an integer
}

你指的是哪种编译器? 如果性能很重要,你可能想要回调之类的东西,这样,使用关键字作为键,回调函数作为值,所以伪代码如下所示:

func *fp = funcTbl.get(Token);
if (fp) { fp(); }

你也可以试试递归下降。与关键字相关的函数在预期的位置被调用。

最后一点,你写的也不错

假设您已经将源语言从字符串表示拆分为一系列词汇标记,下一步是使用 parser 从中构建 AST你的代币。

编译的解析阶段实现了两个主要目标:

  • 它会检查您的语言的句法正确性,如果您的输入无法根据您的语法结构进行解析,则会抛出错误。
  • 它生成源代码的 AST 表示

Does a compiler use if statements when deciding what to do if a certain keyword is encountered?

不,您的解析器应该分析词法标记系列并根据您的语言语法结构检查它们。

解析是计算机科学中一个很好理解的主题,可以通过不同的方式来处理。它不能在您上面提供的示例代码片段中简单地实现。在现实的编程语言中,您需要考虑到语法可能是模棱两可的,并且一个简单的预测解析器适用于所有语法,并且需要某种回溯。如果你不理解这个概念,我建议你为此使用Parser生成器,例如Bison.

此图显示了最重要的编译阶段的简单概述,可以帮助您了解其管道结构。

许多学者几十年来一直在完善这个过程,以研究如何最好地 'divide and conquer' 这样一项艰巨的任务。我强烈建议您遵循它。

如需进一步阅读,请查看 Modern Compiler Implementation in Java by Andrew Appel