语法分析和语义分析

5

我希望你能翻译有关IT技术的内容。以下是需要翻译的内容:

我想知道语法分析和语义分析是怎样工作的。

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

现在我打算为这个语法实现一个递归下降(自顶向下)解析器。

例如,我有以下语法:

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

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

我真的很困惑,请帮忙。

谢谢。

2个回答

3
您可以同时进行语法分析 (解析) 和语义分析 (例如,检查 <data_type><value> 之间的一致性)。例如,当声明 (declaration()) 调用数据类型(data_type()) 时,后者可能会返回一个指示所声明类型是 Int、String 还是 Boolean 的内容(称其为 DT)。同样,值(value()) 可以返回一个指示解析内容类型的内容(VT)。然后声明(declaration()) 将简单地比较 DT 和 VT,如果它们不匹配,则引发错误。(或者 value() 可以接受一个指示已声明类型的参数,并且它可以进行检查。)
但是,您可能会发现完全分离这两个阶段更容易。要这样做,通常可以将解析阶段构建成一个解析树(parse tree)(或抽象语法树)。因此,您的顶层代码将调用 program() 来解析整个程序,该函数将返回代表程序语法的树形结构,然后您将把该树传递给 semantic_analysis() 函数,该函数将遍历该树,提取相关信息并强制执行语义约束。

2

简短的回答是:这取决于您所定义的编程语言。而且,由于您只指定了一个推导规则和三种本地类型,所以无法知道具体情况。例如,如果您的编程语言允许前向声明,就像下面的c++代码一样,那么处理函数声明(foo)的推导规则可以在不知道变量serial的类型的情况下完成。

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

现代编译器将语法分析阶段与语义分析阶段分开。首先执行语法分析阶段,确保输入程序符合语言的上下文无关文法,并生成抽象语法树(AST)。请注意,AST和解析树之间的差异,如此SO帖子中所讨论的。然后,语义分析阶段遍历AST并检查类型不匹配等问题。尽管如此,玩具编程语言有时会将语义和语法分析耦合在一起。当使用递归下降解析器时,应该使相关的递归调用返回一个类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接