Parsing 句法分析与语义分析

Parsing 句法分析与语义分析,parsing,syntax,compiler-construction,semantics,recursive-descent,Parsing,Syntax,Compiler Construction,Semantics,Recursive Descent,我想知道语法分析和语义分析是如何工作的 我已经完成了我的翻译的词法和语法结构 现在,我将为该语法实现一个递归下降(自上而下)解析器 例如,我有以下语法: <declaration> ::= <data_type> <identifier> ASSIGN <value> 假设我有三种数据类型:Int、String和Boolean。由于每个数据类型的值都不同(例如,布尔值中的true或false),如何确定它是否正确地适合数据类型?我的代码的哪

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

我已经完成了我的翻译的词法和语法结构

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

例如,我有以下语法:

<declaration>  ::=   <data_type> <identifier> ASSIGN <value>
假设我有三种数据类型:Int、String和Boolean。由于每个数据类型的值都不同(例如,布尔值中的true或false),如何确定它是否正确地适合数据类型?我的代码的哪一部分会决定这一点

我想知道我应该把代码放在哪里:

1.) call the semantic analysis part of my program. 
2.) store my variables into the symbol table.
语法分析和语义分析是同时进行的吗? 或者我需要先完成语法分析,然后再进行语义分析吗

我真的很困惑。请帮忙


谢谢。

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


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

简短的回答是:它取决于编程语言的定义。而且,由于您只指定了一个派生规则和三个本机类型,因此无法知道。例如,如果您的编程语言允许以下声明(如下面的C++代码),那么处理函数声明(FO)的派生规则是“<强> >不知道< /强>变量序列< /P>的类型。
class Tree {
public:
    int foo(void)
    {
        return serial;
    }
    int serial;
};
事实上,现代编译器将语法分析阶段与语义分析阶段分开。首先执行语法分析阶段,确保输入程序符合语言的上下文无关语法。此外,产生一个AbstractSyntaxTree(AST)。注意AST和解析树之间的区别,如前所述。语义分析阶段然后遍历AST并检查类型不匹配等情况

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

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