语法分析和语义分析

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】:

可以同时进行语法分析(解析)和语义分析(例如,检查&lt;data_type&gt;&lt;value&gt; 之间的一致性)。例如,当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 并检查类型不匹配等。

话虽如此,玩具编程语言有时可以将语义和语法分析结合在一起。当使用递归下降解析器时, 您应该让相关的递归调用返回一个类型。

【讨论】:

以上是关于语法分析和语义分析的主要内容,如果未能解决你的问题,请参考以下文章

编译原理系列 实验四语义分析与中间代码生成

编译原理系列 实验四语义分析与中间代码生成

语义分析的语言?

为啥我们在语义分析中需要属性语法?

编译原理复习总结-耗子尾汁

编译原理复习总结-耗子尾汁