Xtext终端重叠

时间:2016-04-01 12:41:26

标签: editor grammar xtext

我是Xtext的新手,我正面临以下问题: 在每个"错误ID下:"我可以期待每个可打印的角色之间有空格/标签。我的语言是基于缩进的,所以这个"终端"不能以太空人物开始。

编辑/: 此语言的示例代码如下所示:

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终端,因此您不能将例如数字与字符混合。问题是终端必须是分离的,所以如果我修改规则" ANYTHING"像这样:

terminal ANYTHING:
    (ENAME|EMSG|INT)+
;

Anything:
   (ENAME|EMSG|INT)+
;

将是lexer / parser的问题,它无法确定哪个终端是哪个终端。如何应对这种情况?感谢。

//编辑:感谢Christian的工作示例,SL_COMMENT仍然存在一个问题,在此示例中,第二个错误关键字突出显示消息

  

在'错误'

中缺少RULE_END
package A : 
    error B :
        a
        #bopsa Akfkfndsfio
    error A_C_S :
        :aasdasdasd

1 个答案:

答案 0 :(得分:0)

下面的语法对我有用

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: .;