语法分析和语义分析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了语法分析和语义分析相关的知识,希望对你有一定的参考价值。
我想知道语法分析和语义分析是如何工作的。
我已经完成了我的翻译的词法分析器和语法结构。
现在我要为这个语法实现一个递归下降(自上而下)解析器
例如,我有以下语法:
<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。由于每种数据类型的值都不同(例如,仅在布尔值中为true或false)如何确定它是否正确匹配数据类型?我的代码的哪一部分会决定这一点?
我想知道我将把代码放在哪里:
1.) call the semantic analysis part of my program.
2.) store my variables into the symbol table.
语法分析和语义分析是否同时发生?或者我是否需要先完成语法分析,然后进行语义分析?
我真的很困惑。请帮忙。
谢谢。
您可以同时进行语法分析(解析)和语义分析(例如,检查<data_type>
和<value>
之间的协议)。例如,当declaration()调用data_type()时,后者可以返回一些东西(称之为DT),指示声明的类型是Int,String还是Boolean。类似地,value()可以返回指示解析类型的东西(VT)。然后,declaration()将简单地比较DT和VT,如果它们不匹配则引发错误。 (或者,value()可以采用指示声明类型的参数,并且可以进行检查。)
但是,您可能会发现将两个阶段完全分开会更容易。为此,您通常会在解析阶段构建一个解析树(或抽象语法树)。所以你的顶层会调用(例如)program()来解析一个整个程序,它会返回一个表示程序语法的树,你可以将那个树传递给一个semantic_analysis()例程,该例程将遍历树,提取相关信息并实施语义约束。
简短的回答是:它取决于您的编程语言的定义。而且,由于您只指定了一个派生规则和三个本机类型,因此无法知道。例如,如果您的编程语言允许前面的声明,如下面的c ++代码,那么处理函数声明(foo)的派生规则是在不知道变量序列的类型的情况下完成的。
class Tree {
public:
int foo(void)
{
return serial;
}
int serial;
};
实际上,现代编译器将语法分析阶段与语义分析阶段分开。首先执行语法分析阶段,确保输入程序与语言的上下文无关语法一致。此外,还生成一个抽象语法树(AST)。请注意AST和解析树之间的区别,如in this SO post所述。然后,语义分析阶段遍历AST并检查其他事物之间的类型不匹配。
话虽如此,玩具编程语言有时可以将语义和语法分析结合在一起。当使用递归下降解析器时,您应该让相关的递归调用返回一个类型。
以上是关于语法分析和语义分析的主要内容,如果未能解决你的问题,请参考以下文章