使用 ANTLRWorks 测试树语法时,如何将 AST 指定为输入?
您不需要自己提供 AST,只需要生成 AST 的解析器。
给定以下产生 AST 的语法:
grammar ASTDemo;
options {
output=AST;
}
tokens {
ROOT;
U_MIN;
}
parse
: expression EOF -> ^(ROOT expression)
;
expression
: addition
;
addition
: multiplication (('+' | '-')^ multiplication)*
;
multiplication
: unary (('*' | '/')^ unary)*
;
unary
: '-' atom -> ^(U_MIN atom)
| atom
;
atom
: ID
| NUMBER
| '(' expression ')' -> expression
;
ID : ('a'..'z' | 'A'..'Z')+;
NUMBER : '0'..'9'+ ('.' '0'..'9'*)?;
SPACE : (' ' | '\t' | '\r' | '\n')+ {skip();};
以下将是上述语法生成的 AST 的树语法:
tree grammar ASTDemoWalker;
options {
output=AST;
tokenVocab=ASTDemo;
ASTLabelType=CommonTree;
}
parse
: ^(ROOT expression)
;
expression
: ^('+' expression expression)
| ^('-' expression expression)
| ^('*' expression expression)
| ^('/' expression expression)
| ^(U_MIN expression)
| atom
;
atom
: ID
| NUMBER
;
请务必将两者ASTDemo.g
和ASTDemoWalker.g
放在同一个文件夹中。在 ANTLRWorks 中打开这两个语法,并ASTDemo.g
首先通过按CTRL++生成词法分析器和解析器,然后通过打开并按SHIFT++生成树遍历器。GASTDemoWalker.g
CTRLSHIFTG
现在,在编辑器面板中,通过按+ASTDemoWalker.g
启动调试器并将以下源代码粘贴到文本区域:CTRLD
42 * ((a + 3) / -3.14)
并按OK。
您现在可以逐步完成调试过程,最后,您可以看到解析器生成的 AST:

以及树行者是如何走过 AST 的:

如果你现在在树语法中犯了一个“意外”错误,比如说,而不是^('*' expression expression)
你定义^('*' expression)
. 42
如果你再次调试树语法,你会看到它在传递节点后失败:

在 AST 中,该节点之后还有另一个节点42
,而 Tree walker 预计根节点之后只有 1 个单个节点 ( 42
) *
。
当然,这是一个简单的语法,但即使您熟悉 ANTLR,在 @$& 中查找树语法中的错误有时也会很痛苦!:)