У меня следующая грамматика
GUID : GUIDBLOCK GUIDBLOCK '-' GUIDBLOCK '-' GUIDBLOCK '-' GUIDBLOCK
'-'
GUIDBLOCK GUIDBLOCK GUIDBLOCK;
SELF : 'self(' GUID ')';
fragment
GUIDBLOCK: [A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9];
atom : SELF# CurrentGuid
Это мой гость
@Override
public String visitCurrentGuid(CalcParser.CurrentRecordContext ctx) {
System.out.println("Guid is : " + ctx.getText());
System.out.println("Guid is : " + ctx.getChild(0));
return ctx.getText();
}
С вводом "self (5827389b-c8ab-4804-8194-e23fbdd1e370)"
Есть только один дочерний элемент, который представляет собой весь ввод «self (5827389b-c8ab-4804-8194-e23fbdd1e370)»
Как мне получить часть руководства?
Насколько я понимаю, если моя грамматическая структура построена как AST, я смогу распечатать дерево.
Как мне обновить грамматику?
Спасибо




Фрагменты вообще не появляются в AST - они в основном обрабатываются так, как если бы вы написали их содержимое непосредственно в правиле лексера, которое их использует. Таким образом, перемещение кода во фрагменты упрощает чтение кода, но никак не влияет на сгенерированный AST.
Правила лексера, которые используются другими правилами лексера, также рассматриваются как фрагменты в этом контексте. То есть, если правило лексера использует другое правило лексера, оно все равно будет создавать один токен без вложенной структуры - точно так же, как если бы вы использовали фрагмент. Тот факт, что это правило лексера, а не фрагмент, имеет значение только тогда, когда шаблон возникает сам по себе, не являясь частью более крупного шаблона.
Ключ в том, что правило лексера всегда производит один токен, а у токенов нет подтекенов. Это листья AST. Узлы с потомками генерируются из правил парсера.
Единственное правило парсера, которое у вас есть - atom. atom вызывает только одно другое правило SELF. Таким образом, сгенерированное дерево будет состоять из atom, который содержит в качестве своего единственного дочернего элемента токен SELF, и, как указывалось ранее, токены являются листами, так что это конец дерева.
Что вы, вероятно, захотите сделать, чтобы получить полезное дерево, так это сделать GUIDBLOCK правилом лексера (фактически, вашим единственным правилом лексера) и превратить все остальное в правила парсера. Это также означало бы, что вы можете избавиться от atom (возможно, переименовав SELF в atom, если хотите).
Тогда вы получите дерево, состоящее из узла self (или atom, если вы его переименовали), которое содержит в качестве своих дочерних элементов токен 'self(', узел guid (которому вы, возможно, захотите присвоить имя для легкого доступа) и ). токен. Узел guid, в свою очередь, будет содержать последовательность токенов GUIDBLOCK и '-'. Вы также можете добавлять blocks+= перед каждым использованием GUIDBLOCK, чтобы получить список, содержащий только токены GUIDBLOCK без дефисов.
Также может иметь смысл превратить 'self(' в два токена (например, 'self' '(') - особенно если вы когда-нибудь захотите добавить правило для игнорирования пробелов.
Спасибо за объяснение :)