Нет, вы не должны использовать древовидную грамматику.Древовидная грамматика используется после , когда парсер создал AST.Просто удалите из него ключевое слово tree
.
Несколько других замечаний:
- вы хотите сопоставить один или несколько разделенных запятыми
type
s внутри скобок, но вы использовалиtype (SEP type)?
, что соответствует одному или двум type
с.Вместо этого вам понадобится type (SEP type)*
; - вы не учитываете
.
внутри type
s; - вы должны отбрасывать буквальные пробелы в лексере.
Нечто подобное поможет, скорее всего:
grammar XmlTypeName;
options {
language=CSharp2;
}
prog
: type EOF
;
type
: name (RPAREN type (SEP type)* LPAREN)?
;
name
: ID (DOT ID)*
;
RPAREN
: '('
;
LPAREN
: ')'
;
SEP
: ','
;
DOT
: '.'
;
ID
: ('a'..'z'|'A'..'Z'|'0'..'9'|'_')+
;
SPACE
: (' '|'\t')+ {Skip();} // if 'Skip()' doesn't work, try 'skip()'
;
Однако вышеприведенное просто создает плоский список токенов.Если вы хотите создать правильный AST, вам нужно «сообщить» ANTLR, какие узлы / токены являются корневыми токенами, а какие отбрасывать (например, запятая, скобка, ...).
grammar XmlTypeName;
options {
output=AST;
language=CSharp2;
}
tokens {
TYPE;
NAME;
}
prog
: type EOF -> type
;
type
: name (RPAREN type (SEP type)* LPAREN)? -> ^(TYPE name type*)
;
name
: ID (DOT ID)* -> ^(NAME ID+)
;
RPAREN
: '('
;
LPAREN
: ')'
;
SEP
: ','
;
DOT
: '.'
;
ID
: ('a'..'z'|'A'..'Z'|'0'..'9'|'_')+
;
SPACE
: (' '|'\t')+ {skip();}
;
который создает следующий AST:
Подробнее о создании AST с помощью ANTLR: Как вывести AST, построенный с использованием ANTLR?