嗨,我知道这太愚蠢了。
我已经在Ulman et.al的编译器设计原理中学到了,并且网上解释器与编译器不同。 编译器的阶段是 lexical-> parser-> semantics->(然后)中间代码生成器。但是我的编译器设计课程讲师坚持告诉我们,我们通过以下几个阶段来设计编译器: lexical-> parser-> semantics->解释器。这可能吗? 解释语义的输出?我是否错过了有关设计编译器的一些主题? 非常感谢你
答案 0 :(得分:1)
鉴于你学习了厄尔曼,我认为你正在尝试一种小型的命令式语言。任何语言翻译任务,解释或编译的前几个阶段始终是相同的:标记化输入流(lexing),构建语法树(解析)然后进行一些语义分析。
当您遇到lexing时,如果遇到您的语言字符集中不允许的字符,则会出错。考虑一种在ASCII字母表中定义的语言,其中包含非ASCII UTF-8字符。
类似地,当您进行解析时,如果您无法根据您的语言规则(即语法错误)构建正确的树,则会出现错误。一个例子是声明
if = 5;
看起来像是一项作业,但在大多数语言中,如果'是一个保留字...所以当解析器看到令牌时,如果'它决定要查看“如果/其他”#39;声明,而不是等号。
假设您已完成解析。现在你知道你有一个语法正确的程序。但是,根据您的语言定义语义,这可能在语义上不正确。例如:
int x = 3;
float x = 3.1415;
会导致C中的(冲突类型)错误。程序在语法上是正确的(对于无上下文语法有效)但在语义上不是。 '语义检查的作用'是为了清除这些程序,因此您可以定义从语义正确的语法树到目标机器(解释器或代码生成器)的转换,而不必考虑语义错误的输入。换句话说,语义检查会丢弃一些你不想翻译的程序,因为它可能含糊不清或其他什么。语义阶段只添加语法树的信息(即装饰)。
一旦你知道你的装饰语法树形式的输入程序在你的语言语法和语义方面是正确的,你可以做任何你喜欢的事情:编译(翻译)到机器代码(或抽象机器或字节代码) )或解释它。可以解释语法树,但通常更容易解释它的平面表示,如三个地址代码。
执行回答:是的,您的教师希望您解释富含语义信息的解析器的结果。