解析AST < O(exp(n))吗?

12

摘要问题描述:

在我看来,unparsing 的意思是从 AST 中创建一个标记流,当再次解析时,会产生相等的 AST。

因此,parse(unparse(AST)) = AST 成立。

这相当于找到一个有效的解析树,该解析树将产生相同的 AST。

该语言使用 context free S-attributed 语法来描述,使用 eBNF 变体。

所以,非解析器必须在遍历的节点中找到一条有效的“路径”,其中所有语法约束都成立。这基本上意味着要找到一个有效的AST节点分配给语法制作规则。这通常是一个约束满足问题(CSP),可以通过回溯在O(exp(n))中解决,就像解析一样。
幸运的是,对于解析来说,可以使用GLR(或更好地限制语法)以O(n³)的速度完成。因为AST结构与语法制作规则结构非常接近,所以我真的很惊讶看到一个实现,其中运行时比解析更糟糕:XText使用ANTLR进行解析和回溯进行非解析。

问题

  1. 上下文无关的S-属性文法是解析器和还原器之间需要共享的全部内容,还是还有其他限制,例如解析技术/解析器实现方面的限制?
  2. 我觉得这个问题通常情况下不是O(exp(n)) - 能否有天才帮我解决一下?
  3. 这基本上是一个上下文敏感文法吗?

示例1:

Area    returns AnyObject   -> Pedestrian | Highway
Highway returns AnyObject   -> "Foo" Car
Pedestrian  returns AnyObject   -> "Bar" Bike
Car     returns Vehicle     -> anyObjectInstance.name="Car"
Bike    returns Vehicle     -> anyObjectInstance.name="Bike" 

所以,如果我有一个包含AnyObject -> AnyObject -> Vehicle [name="Car"]的AST,并且我知道根可以是Area,那么我可以将其解析为
Area    -> Highway  -> Car

所以(高速公路|行人)的决策取决于子树决策。当一个叶节点乍一看可能是几种类型之一,但后来必须成为特定类型才能形成有效路径时,问题会变得更加严重。
例如2:
如果我的S属性规则返回未分类的对象,只分配一些属性,例如:
A -> B C   {Obj, Obj}
X -> Y Z   {Obj, Obj}
B -> "somekeyword"  {0}
Y -> "otherkeyword" {0}
C -> "C" {C}
Z -> "Z" {Z}

因此,如果AST包含

   Obj
  /  \
"0"  "C"

我可以将其解析为

   A
  / \
 B   C

我刚刚能够将"C"解析为C。

在遍历AST时,从语法中生成的所有约束条件都对规则A和X均满足,直到遇到"C"。这意味着对于

A -> B | C 
B -> "map"  {MagicNumber_42}
C -> "foreach" {MagicNumber_42}

树的两个解决方案

     Obj
      |
 MagicNumber_42

这些是有效的,且被认为具有相同的语义,例如语法糖。

更多信息:


1
我想我不理解。对于语法分析树的深度优先中序遍历应该按照它们原始顺序访问标记叶子节点。AST与语法分析树差异太大,无法进行这样的遍历吗? - phs
是的,解析树是“强类型”的,因此您基本上知道生成某个节点所使用的特定语法规则。对于一般的AST,这些信息会丢失并需要重建。因此,为了解析AST,只需构造一个有效的解析树即可生成该AST。请注意,可能会有几个解析树,但这并不重要,因为它们中的任何一个都具有相同的含义(语法糖)。问题不在于遍历AST,而在于标记已访问节点的有效语法生成规则序列。 - Stefan K.
将语法树转换为AST的转换是应用程序相关的;因为听起来像您想要反转的步骤,所以您必须告诉我们具体的应用程序(语言)。 - phs
使用特定的eBNF语法,例如ANTLR所使用的语法,例如r [int a,String b]返回[int c,String d]:a ='class' b = ID ... {$ c = $ a; $ d = $ b;}。因此,AST构建是自动化的,并受合成属性的限制。 - Stefan K.
如果您在SE:SO上没有得到满意的答案,请尝试SE:CS - Guy Coder
1个回答

1
问题1:不,语法本身可能不足够。以模棱两可的语法为例。如果你最终得到了一个给定字符串的唯一左(右)导出(AST),你必须知道解析器如何消除歧义。只需考虑具有表达式的天真语法“E:= E + E | E * E | ...”的字符串'a + b * c'。
问题3:您提供的所有语法示例都不是上下文相关的。产生式的左侧是单个非终端符号,没有上下文。

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