【问题标题】:Recursive Tree Rewrite ANTLR递归树重写 ANTLR
【发布时间】:2012-12-03 13:55:28
【问题描述】:

我有一个包含简单令牌列表的 AST...

我只是想将成对的平衡参数分组到嵌套树中。

我一直在尝试各种规则,但我无法完全理解......

bottomup : findParams;

findParams
: ^(LIST left+=expression* LPARAM inner? RPARAM right+=expression*)
-> ^(LIST  $left* ^(PARAMS inner?) $right*);

inner : (left+=expression* LPARAM inner? RPARAM right+=expression*)
-> $left* ^(PARAMS inner?) $right*) | (a+=expression* -> $a*);

fragment expression = INT;

这有点像 dyck 语言,但在树上而不是在源上。另外,我无法使用远程调试来调试模式匹配树语法,这是一个障碍。

【问题讨论】:

  • 对不起,我刚刚发布了一个答案,然后明白了,它可能不是你需要的。请更详细地解释一下,你是什么意思:“......但是在树上而不是在源头上”。这是否意味着您只能使用某些树列表,而不能使用输入文本(字符串)?
  • 嗨,是的,我正在使用解析器生成的 AST,我想使用树语法来操作它以嵌套参数。上面的例子是一个可能的树的超级简单版本。我的实际语法要复杂得多,没有像 INT 甚至 LPARAM/RPARAM 这样简单的东西。尽管如此,这仍然是同样的问题。我想在解析器阶段这样做是可能的,而且要好得多,但是在树语法阶段要简单得多。
  • 好的。可能这是一个愚蠢的建议,但是......如果我试图解决这个问题,我会将输入的 AST 转换为简单的字符串,然后使用我自己的语法以方便的形式对其进行解析:)

标签: parsing tree antlr grammar abstract-syntax-tree


【解决方案1】:

您的方法是正确的,但是您将自上而下的方法与自下而上的方法混合在一起。自上而下有利于分解:“这个清单很大,分成一些更小的清单。”自下而上有助于打破事物:“这是最简单的东西,可能是一个列表,所以我将它变成一个。”

这是对节点进行分组的自下而上的解决方案:

bottomup
    : exit_list
    ;

exit_list
    : ^(LIST pre* LPAR reduced* RPAR post+=.*) -> ^(LIST pre* ^(LIST reduced*) $post*)
    ;

pre : INT
    | LPAR 
    | ^(LIST .*)
    ;   

reduced
    : INT
    | ^(LIST .*)
    ;    

对于每组不包含其他括号的括号,将该组的内容转换为一个新列表。重复此规则,直到没有括号为止。

例子:

输入

1(3(4))5

基线 AST

最终 AST

规则bottomup 被递归应用了两次:

applied to (4):    (LIST 1 '(' 3 '(' 4 ')' ')' 5) -> (LIST 1 '(' 3 (LIST 4) ')' 5)

applied to (3(4)): (LIST 1 '(' 3 (LIST 4) ')' 5) -> (LIST 1 (LIST 3 (LIST 4)) 5)

【讨论】:

  • 抱歉回复晚了。感谢您的建议,但我无法让它工作。我正在使用自定义 AST 节点类型,设置 ASTLabelType 并不断收到“无法投射...”异常。
  • 我改成CommonTree了,异常消失了,但是无法匹配嵌套参数。如果它们只包含 INT 或被 INT 包围,那么它可以工作,但递归位不起作用。
  • @DavidJamesBall ANTLR 对它在树中匹配的内容以及它从规则中产生的内容很挑剔,对规则进行小的更改也可以进行细微的更改。在我的示例中,如果您从规则pre 中删除| ^(LIST .*),它将按预期匹配其余部分,但它根本不会产生任何东西,只是null 节点不会出现在输出中。我的建议是将你的匹配明确地分解成他们自己的规则(例如,更喜欢规则 prepre+=.* 中的所有内容)。如果这不起作用,请考虑编写一个新问题,详细说明不匹配的内容。
  • 我认为将这种匹配合并到解析器阶段更容易,但是我仍然有一个小问题...stackoverflow.com/questions/13980501/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
  • 1970-01-01
  • 2021-07-10
相关资源
最近更新 更多