Если вы хотите удалить DOT
из дерева и оставить только токены a
, b
и c
из import a.b.c;
(с PACKAGE
как root, конечно), попробуйте:
qualifiedIdentifier
: IDENT (DOT IDENT)* -> IDENT+
;
или DOT
, просто удалите правило перезаписи:
qualifiedIdentifier
: IDENT (DOT IDENT)*
;
Кстати, в вашем packageDeclaration
есть ошибка:
packageDeclaration
: PACKAGE qualifiedIdentifier SEMI -> ^(PACKAGE qualifiedIdentifier+)
;
qualifiedIdentifier+
вместо qualifiedIdentifier
.
Кодер написал:
Я бы предпочел не изменять переписывание для квалифицированного идентификатора, а только для packageDeclaration.
Это невозможно.
Если вы не используете qualifiedIdentifier
внутри packageDeclaration
, в этом случае вы можете сделать что-то вроде:
packageDeclaration
: PACKAGE IDENT (DOT IDENT)* SEMI -> ^(PACKAGE IDENT+)
;
EDIT
По поводу ваших комментариев:
Кодер написал:
Я немного запутался в значении + в правиле перезаписи. В документации здесь antlr.org/wiki/display/ANTLR3/Tree+construction говорится, что вы можете разбивать деревья на последовательности «a: (^ (ID INT)) + -> INT + ID +; // разбивать деревья на последовательности».
Из правила:
a
: (^(ID INT))+ -> INT+ ID+
;
(^(ID INT))+
означает, что есть один или несколько ID
и еще один INT
, и только тогда вы можете использовать +
в правиле перезаписи (все справа от ->).
С другой стороны, у вас есть:
packageDeclaration
: PACKAGE qualifiedIdentifier SEMI
;
там только один qualifiedIdentifier
, так что вы можете использовать только этот сингл qualifiedIdentifier
в своем правиле перезаписи (нет +
!)
Кодер написал:
Меня также смущает различие между указанием псевдонима в правиле перезаписи, например, в "PACKAGE identifier: qualIdentifier -> $ identifier" и использовании quanlifiedIdentifier против $ quanlifiedIdentifier
Псевдоним можно использовать, если неясно, что неясно, какое правило должно быть размещено где-то в дереве, или если вы хотите больше контролировать то, как размещаются дочерние элементы. Например, учитывая правило:
name
: ID '.' ID
;
и вы хотите, чтобы первый ID
стал правильным ребенком. Выполнение:
name
: ID '.' ID > ^(NAME ID ID)
;
поместит первый идентификатор в качестве левого ребенка. Чтобы сделать это правильным ребенком, сделайте:
name
: a=ID '.' b=ID > ^(NAME $b $a)
;
РЕДАКТИРОВАТЬ II
Кодер написал:
В результате я получаю вложенные токены, как в:
(СНИП)
Каждый токен представлен как ...
Хорошо, я понимаю, что вы имеете в виду. Вы должны понимать, что парсер "кормит" лексера. Лексер прерывает ввод символов и создает токены из этих символов (IDENT
такой токен, как и DOT
). Эти токены затем передаются парсеру. Парсер не может просто создавать или объединять токены. Таким образом, ответ таков: то, что вы хотите, нелегко сделать, это, конечно, невозможно сделать в «синтаксисе ANTLR» внутри вашей грамматики.