Я новичок в Xtext, и я столкнулся с следующей проблемой: Под каждой строкой «error id:» я могу ожидать, что каждый печатный символ с пробелами/вкладками между ними. Мой язык основан на отступе, поэтому этот «терминал» не может начинаться с символа пробела.Перекрытие Xtext-терминалов
Редактировать /: Пример кода для этого языка будет выглядеть следующим образом:
package somepkg:
error UNKNOWN:
Unknown error.
error ZERO_DIVISION:
Do not divide by zero you {0} donkey!.
Ближайший я добраться до этой языковой спецификации заключается в следующем:
grammar com.example.lang.ermsglang.Ermsglang with org.eclipse.xtext.xbase.Xbase hidden(WS)
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate ermsglang "http://www.example.com/lang/ermsglang/Ermsglang"
Model:
{Model}
'package' name=ENAME ':'
(BEGIN
(expressions+=Error)+
END)?
;
Error:
{Error}
'error' name=ENAME ':'
(BEGIN
(expressions+=Anything)+
END)?
;
Anything:
(ENAME|EMSG|INT)
;
//Terminals must be disjunctive
terminal ENAME:
('_'|'A'..'Z') ('_'|'A'..'Z')*
;
terminal EMSG:
('!'..'/'|':'..'@'|'['..'~')+
;
terminal SL_COMMENT:
'#' !('\n'|'\r')* ('\r'? '\n')?
;
// The following synthetic tokens are used for the indentation-aware blocks
terminal BEGIN: 'synthetic:BEGIN'; // increase indentation
terminal END: 'synthetic:END'; // decrease indentation
Но все-таки, это позволяет либо ENAME или EMSG или INT, поэтому вы не можете смешивать, например, цифры с символами. Проблема в том, терминалы должны быть дизъюнктивной так, если я изменить правила «НИЧЕГО», как это:
terminal ANYTHING:
(ENAME|EMSG|INT)+
;
или
Anything:
(ENAME|EMSG|INT)+
;
будет проблема с лексического анализатора/синтаксический анализатор, который не может определить, какой терминал, который. Как справиться с этой ситуацией? Благодарю.
// Изменить: Спасибо Кристиану для работы пример, есть еще одна проблема с SL_COMMENT, в этом примере второе ключевое слово ошибки подсвечивается с сообщением
отсутствующего RULE_END на «ошибки»
package A :
error B :
a
#bopsa Akfkfndsfio
error A_C_S :
:aasdasdasd
почему наследоваться от Xbase или любой другой терминал. lexing является свободным от контекста, поэтому вам нужно недвусмысленно на уровне lexer. если вы наследуете от xbase, вы наследуете множество правил терминалов –
@ChristianDietrich, потому что без него специальные терминалы: 'terminal BEGIN: 'синтетический: BEGIN'; // увеличить отступ' 'терминал END: 'синтетический: END'; // уменьшить отступ' не работает. Лексинг не имеет контекста, но сам язык не является. Это зависит от контекста глубины углубления. – Smarty77
можете ли вы указать на ошибку. если вы наследуете, тогда вы должны добавить идентификатор, INT и т. д. в свое правило AllStuff, а также переопределить их к тому, что никогда не произойдет в моделях, например. '' ''@@@@@@@@@@@@@@@@@@@@@@@@' '' '' –