在编译器中进行语义分析的形式化方法

时间:2015-01-15 07:04:11

标签: compiler-construction semantics context-sensitive-grammar

我知道有一种称为属性语法的形式主义,以及一种称为语法导向翻译的非形式主义方法,但第一种方法效率低下,后者很难实现自动化。

最近是否存在其他关于语义分析的形式主义?

1 个答案:

答案 0 :(得分:0)

OP建议"属性语法"效率低下,语法导向的翻译难以自动化。我提供了一个证明点,以其他方式显示,列出其他一些语义系统,并建议如何将它们集成在下面。

我们DMS Software Reengineering Toolkit支持这两项活动等。

它提供完整上下文无关语法的解析器,以及使用任意数据和操作定义,编译和执行并行属性语法的能力,以及跨语法节点的任意流。可以使用这样的属性语法来计算度量,构建符号表或计算语义分析。

给定(DMS)语法规则:

  LHS = RHS1 ... RHSN ;

为命名属性语法计算 Pass1 写一个DMS属性语法规则(出于实际原因,可能有许多不同的传递,有些甚至建立彼此的结果) :

  <<Pass1>>:  {  LHS.propertyI=fn1(RHSx.propertyY,...);
                 ...
                 RHSa.propertyB=fn2(RHSp.propertyQ,...);
                 ...
              }

用于与语法规则的左侧或右侧相关联的每个语法元素的一组(任意类型)属性,使用在所涉及的类型上定义的任意函数 fnI ,在DMS的底层(并行)语言PARLANSE。 DMS计算规则集中的数据流,并确定实现计算的部分顺序(并行)计算,并将其编译为PARLANSE代码以供执行。属性计算的结果是用计算属性修饰的树。

小心,一旦能够定义由属性语法计算的语言的denotational semantics。 DS中的一个关键概念是&#34;环境&#34;,它将标识符映射到类型和可能的符号值。 (前者传统上称为符号表)。在引入新范围的AST节点上,可以编写一个属性函数,通过将父环境与新引入的标识符相结合来创建新环境,并将其从AST节点传递给其子节点,例如,用于规则

exp = 'let' ID '=' exp1 'in' exp2;

可以编写属性语法规则:

<<Denotation>>: {
     exp2.env = augment_environment(exp.env,
                                    new_variable_and_value_pair(name(ID.),
                                                                exp1.value));
     exp.value=exp2.value;
               }

我不确定OP的含义(属性语法是什么)&#34;低效&#34; 我们使用DMS属性语法来计算语义属性( 所有的C ++ 14的名称和类型解析。 虽然这种定义在大多数学术论文标准中都是巨大的,但正是这样,因为C ++ 14本身就是巨大而且令人惊讶的混乱(&#34;委员会的骆驼&#34;)。尽管如此,我们的属性语法似乎运行得很好。更重要的是,它足以让一个非常小的团队来构建它(与#34;团队&#34;支持Clang的规模相比)。

DMS还提供了使用源和目标(如果不同于源)语言的表面语法对表格进行编码(&#34;重写&#34;)的能力,#34> ;如果您看到 this ,请将其替换为 &#34;。这些重写应用于解析树以提供修改后的树;然后,DMS提供的prettyprinter(&#34;反解析器&#34;)可以重新生成目标语言的源代码。如果一个人限制自己重写那个完全平铺原始AST就会得到#34;语法导向翻译&#34;。 OP可能声称这(语法导向翻译)难以自动化;我同意,但工作已经完成并可用。 OP必须决定她想要定义和执行的规则。

DMS重写规则采用以下形式:

 rule rule_name(parameter1:syntax_category1, ... parameterN...)
   :  source_syntax_category -> target_syntax_category
   "  <text in source language>  "
  ->
   "  <text in target language> "
  if  condition_of_matched_source_pattern;

其中参数是语法类型子树的占位符,规则映射 source_syntax_category类型的树 - &gt; target_syntax_category(通常是同一个), 和#34; ...&#34;是包含表面语法的元引号,带有&#34; \&#34; - 标记的嵌入式转义符,用于所需的参数。元引用的代码片段被解释为树的规范(使用读取源代码的相同解析引擎);这不是字符串匹配。一个例子:

  rule simplify_if_then_else(c:condition,t:then_clause,e:else_clause)
     statement->statement
  =  " if \c then \t else \e "
  -> " \t "
  if c == "true";

(以上纯语法)检查的概括)更多&#34;语义&#34;会是

  ...
  if can_determine_is_true(c);

假设自定义谓词参考其他DMS可派生结果以确定实例化条件在找到它的位置始终为真(匹配树c带有它的源位置,因此隐含上下文)。可以为所需语言构建控制和数据流,并使用结果数据流来确定到达条件c的值,然后可能总是变为&#34; true&#34;以一种非常重要的方式。

我假设了DMS定义的支持谓词&#34; can_determine_if_true&#34;。这只是一些自定义PARLANSE代码。

然而,由于重写将一棵树变换为另一棵树,因此可以将一组任意长/复杂的变换规则重复应用于整个树。这使DMS重写了Post(字符串[generalized to tree])重写系统的功能,因此具有图灵功能。您可以在技术上通过足够的变换生成原始树的任意变换。通常使用DMS的其他功能来使编码变换更容易;例如,重写规则可以查询特定属性语法计算的结果,以便轻松地&#34;使用远离树木的信息&#34; (个人重写规则总是有固定的,最大的&#34;半径&#34;)。

DMS提供了许多额外的支持机制,以帮助构建控制流图和/或使用高效的并行求解器计算数据流。 DMS还有各种各样的可用前端,适用于各种语言,如C,C ++ 14,Java1.8,IBM Enterprise COBOL,......可以让工具工程师专注于构建她想要的工具,而不是努力从头开始构建解析器(只发现一个人必须活Life After Parsing)。

如果OP对最近关于另一种(结构化操作)语义的概述感兴趣,他可以参考 Semantics of Programming Languages的课程说明。我们声称这些论文中的技术可以在DMS之上实现,如果有人喜欢的话。

可以列出一长串实施(部分)这些想法的各种学术工具。他们中的大多数是研究工具,并不成熟。一个这样的研究系统JastAdd是一个属性语法评估系统,我听说它在能力和性能方面很突出,但我没有具体的经验。