5

我想知道语法分析和语义分析是如何工作的。

我已经完成了我的解释器的词法分析器和语法构造。

现在我将为这个语法实现一个递归下降(自上而下)解析器

例如,我有以下语法:

<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.

语法分析和语义分析是否同时发生?还是我需要先完成语法分析,然后再进行语义分析?

我真的很困惑。请帮忙。

谢谢你。

4

2 回答 2

3

可以同时进行语法分析(解析)和语义分析(例如,检查 和 之间的一致性<data_type><value>。例如,当declaration() 调用data_type() 时,后者可以返回一些东西(称为DT),指示声明的类型是Int、String 还是Boolean。类似地, value() 可以返回一些东西 (VT),指示解析的类型。然后 declaration() 将简单地比较 DT 和 VT,如果它们不匹配,则会引发错误。(或者, value() 可以接受一个指示声明类型的参数,可以进行检查。)

但是,您可能会发现将这两个阶段完全分开更容易。为此,您通常需要在解析阶段构建解析树(或抽象语法树)。因此,您的顶层将调用(例如)program() 来解析整个程序,该程序将返回表示程序(的语法)的树,并且您将该树传递给语义分析()例程,该例程将遍历树,提取相关信息并执行语义约束。

于 2013-10-02T18:38:58.743 回答
2

简短的回答是:这取决于您的编程语言的定义。而且,由于您只指定了一种派生规则和三种原生类型,因此无法知道。例如,如果您的编程语言允许像下面的 c++ 代码这样的前向声明,则在不知道变量 serial 的类型的情况下处理函数声明 (foo) 的派生规则

class Tree {
public:
    int foo(void)
    {
        return serial;
    }
    int serial;
};

事实上,现代编译器将语法分析阶段与语义分析阶段分开。首先执行语法分析阶段,确保输入程序与语言的上下文无关语法一致。此外,还生成了一个抽象语法树( AST )。请注意 AST 和解析树之间的区别,如这篇 SO post 中所讨论的。语义分析阶段然后遍历 AST 并检查类型不匹配等。

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

于 2017-10-27T05:27:12.323 回答