2016-04-01 2 views
0

Я новичок в 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 
+0

почему наследоваться от Xbase или любой другой терминал. lexing является свободным от контекста, поэтому вам нужно недвусмысленно на уровне lexer. если вы наследуете от xbase, вы наследуете множество правил терминалов –

+0

@ChristianDietrich, потому что без него специальные терминалы: 'terminal BEGIN: 'синтетический: BEGIN'; // увеличить отступ' 'терминал END: 'синтетический: END'; // уменьшить отступ' не работает. Лексинг не имеет контекста, но сам язык не является. Это зависит от контекста глубины углубления. – Smarty77

+0

можете ли вы указать на ошибку. если вы наследуете, тогда вы должны добавить идентификатор, INT и т. д. в свое правило AllStuff, а также переопределить их к тому, что никогда не произойдет в моделях, например. '' ''@@@@@@@@@@@@@@@@@@@@@@@@' '' '' –

ответ

0

follwoing грамматика работает для меня

grammar org.xtext.example.mydsl3.MyDsl hidden (WS, SL_COMMENT) 

generate myDsl "http://www.xtext.org/example/mydsl3/MyDsl" 

import "http://www.eclipse.org/emf/2002/Ecore" as ecore 

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') ('_'|'A'..'Z'|'a'..'z')* 
; 
terminal INT returns ecore::EInt: ('0'..'9')+; 

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 

terminal WS   : (' '|'\t'|'\r'|'\n')+; 

terminal ANY_OTHER: .; 
+0

Здравствуйте, спасибо за ваш ответ, похоже, что он работает без xbase. Мне удалось реализовать его в соответствии с вашим примером грамматики. Я все еще исследую одну проблему tho (это даже в этом примере), и это SL_COMMENT, которая вызывает ошибку. См. Например, редактирование. – Smarty77

+0

Хорошо, это проблема (в этом примере) в диапазоне символов ''! '..'/'', который включал символ« # », и это противоречило определению терминалов SL_comment. – Smarty77