语法分析和语义分析
Posted
技术标签:
【中文标题】语法分析和语义分析【英文标题】:Syntax analysis and semantic analysis 【发布时间】:2013-10-05 04:37:52 【问题描述】:我想知道是如何工作的。
我已经完成了我的解释器的词法分析器和语法构造。
现在我要为这个语法实现一个递归下降(自上而下)解析器
例如,我有以下语法:
<declaration> ::= <data_type> <identifier> ASSIGN <value>
所以我这样编码(在 java 中):
public void declaration()
data_type();
identifier();
if(token.equals("ASSIGN"))
lexer(); //calls next token
value();
else
error();
假设我有三种数据类型:Int、String 和 Boolean。由于每种数据类型的值不同,(例如,仅在布尔值中为真或假)我如何确定它是否正确适合数据类型?我的代码的哪一部分会确定这一点?
我想知道我应该把代码放在哪里:
1.) call the semantic analysis part of my program.
2.) store my variables into the symbol table.
是否同时发生? 还是我需要先完成语法分析,然后再进行语义分析?
我真的很困惑。请帮忙。
谢谢。
【问题讨论】:
【参考方案1】:您可以同时进行语法分析(解析)和语义分析(例如,检查<data_type>
和<value>
之间的一致性)。例如,当declaration() 调用data_type() 时,后者可以返回一些东西(称为DT),指示声明的类型是Int、String 还是Boolean。类似地, value() 可以返回一些东西 (VT),指示解析的类型。然后 declaration() 将简单地比较 DT 和 VT,如果它们不匹配,则会引发错误。 (或者,value() 可以接受一个参数来指示声明的类型,并且 it 可以进行检查。)
但是,您可能会发现将这两个阶段完全分开会更容易。为此,您通常需要在解析阶段构建一个解析树(或抽象语法树)。因此,您的顶层将调用(例如)program() 来解析整个程序,该程序将返回表示程序(的语法)的树,并且您将该树传递给语义分析()例程,该例程将遍历树,提取相关信息并执行语义约束。
【讨论】:
【参考方案2】:简短的回答是:这取决于您的编程语言的定义。而且,由于您只指定了一种派生规则和三种原生类型,因此无法知道。例如,如果您的编程语言允许像下面的 c++ 代码这样的前向声明,那么处理函数声明 (foo) 的派生规则是在不知道变量序列的类型的情况下完成的
class Tree
public:
int foo(void)
return serial;
int serial;
;
确实,现代编译器将语法分析阶段与语义分析阶段分开。首先执行语法分析阶段,确保输入程序与语言的上下文无关语法一致。此外,还产生一个A抽象S语法Tree (AST)。请注意 AST 和解析树之间的区别,正如 in this SO post 所讨论的那样。语义分析阶段然后遍历 AST 并检查类型不匹配等。
话虽如此,玩具编程语言有时可以将语义和语法分析结合在一起。当使用递归下降解析器时, 您应该让相关的递归调用返回一个类型。
【讨论】:
以上是关于语法分析和语义分析的主要内容,如果未能解决你的问题,请参考以下文章