Как указать AST в качестве входных данных при тестировании грамматики дерева с помощью ANTLRWorks?
Вам не нужно предоставлять 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 + G , а затем сгенерируйте обходчик дерева, открыв ASTDemoWalker.g
и нажатие CTRL + SHIFT + G .
Теперь на панели редактора ASTDemoWalker.g
запустите отладчик, нажав CTRL + D и вставьте следующий источник в текстовую область:
42 * ((a + 3) / -3.14)
и нажмите OK .
Теперь вы можете пройти через процесс отладки, и в конце вы можете увидеть, что AST сгенерировал парсер:
![enter image description here](https://i.stack.imgur.com/ULVFn.png)
и как ходил по деревьям сказал АСТ:
![enter image description here](https://i.stack.imgur.com/DVnRM.png)
Если вы теперь допустили «случайную» ошибку в грамматике дерева, скажем, вместо ^('*' expression expression)
вы определяете ^('*' expression)
. Если вы снова отладите грамматику дерева, вы увидите, что она не прошла после прохождения узла 42
:
![enter image description here](https://i.stack.imgur.com/7OFNq.png)
В AST есть другой узел после узла 42
, в то время как обходчик дерева ожидал только 1 единственный узел (42
) после корневого узла *
.
Конечно, это простая грамматика, но даже если вы знакомы с ANTLR, иногда @ @ & вызывает боль в поиске ошибок в древовидной грамматике! :)