Compiler construction 编译器中的语义规则

Compiler construction 编译器中的语义规则,compiler-construction,Compiler Construction,我对语法导向定义(SDD)和语法导向翻译(SDT)中使用的语义规则感到困惑 我们如何获得语义规则?它是否像开发人员需要为该语言指定的语法一样。好吧,为了不让您感到困惑,您必须从头开始 您已经知道,为了在词汇和语法层面上指定一种语言,您必须使用不同的构造,这些构造是标记(主要由正则表达式实现),用于指定某些代码的词汇结构,以及(无上下文)语法,它在语法级别上指定了某些代码的结构(为编译器的后续阶段提供了一种更易于处理的表示形式——抽象语法树——同时进行语法健全性检查,即确保输入有效且没有语法错误)

我对语法导向定义(SDD)和语法导向翻译(SDT)中使用的语义规则感到困惑


我们如何获得语义规则?它是否像开发人员需要为该语言指定的语法一样。

好吧,为了不让您感到困惑,您必须从头开始

您已经知道,为了在词汇和语法层面上指定一种语言,您必须使用不同的构造,这些构造是
标记
(主要由正则表达式实现),用于指定某些代码的词汇结构,以及
(无上下文)语法
,它在语法级别上指定了某些代码的结构(为编译器的后续阶段提供了一种更易于处理的表示形式——
抽象语法树
——同时进行语法健全性检查,即确保输入有效且没有语法错误)

例如,假设您有以下小代码段:

int c = a + 5;
然后在词法分析结束时,您拥有以下标记(假设在您的语言规范中有实际的标记定义,但现在让我们保持简单):

然后传递给解析器,解析器创建以下语法树:

     =
    / \
   /   \
  c     +
       / \
      a   5
到目前为止,您已经认识到这种语言结构是有效的,并且格式良好,但是您没有做任何事情来推导它的含义。
+
运算符代表什么?
a
代表什么?
=
代表什么(作为动作)?该操作在语义上是否有效(即您没有添加字符和数字)

因此,还需要为语言指定
语义规则

正是在这一点上,我们得到了
语法导向定义
(也称为
属性语法
)。
语法导向定义
是我们之前用来进行语法分析的
上下文无关语法
(既然我们已经有了一个很好的符号来完成我们的工作,为什么还要发明一个新的符号呢),但是要用附加在
语法符号
上的
属性来增强它,以及附加到产品的
语义规则

例如,包含上述代码的语言的上下文无关语法可能作为生产规则:

E --> E1 + T
E --> <identifier>
T --> <number>
E-->E1+T
E-->
T-->
在这种情况下,我们的语法导向定义(使用合成属性)如下:

E --> E1 + T       { E.val = E1.val + T.val; }
E --> <identifier> { E.val = identifier.val; }
T --> <number>     { T.val = number.val; }
E-->E1+T{E.val=E1.val+T.val;}
E-->{E.val=identifier.val;}
T-->{T.val=number.val;}

这表示最终表达式将通过添加第一个表达式的值以及加号运算符右侧的项的值来获得其值,并指定如何获取标识符表达式和项因子的值的规则。

这是编译器在该过程中创建的合成属性吗?
E --> E1 + T       { E.val = E1.val + T.val; }
E --> <identifier> { E.val = identifier.val; }
T --> <number>     { T.val = number.val; }