【问题标题】:Xtext grammar with either reference to instance or literal value引用实例或文字值的 Xtext 语法
【发布时间】:2021-12-12 22:36:43
【问题描述】:

我正在尝试为基于 XML 的宏建模

<macro name="dummy" parameters="elemName elemValue">
    <element name=${elemName} /> <!--reference to parameter elemName-->
    <element name="elem1" />
    <anotherElement name="elem2" value=6 />
    <anotherElement name="elem3" value=${elemValue} />
</macro>

稍后这个宏将​​被实例化:

<dummy elemName="elem0" elemValue=3 />

但在我可以为宏建模之前,我尝试为元素属性分配一个值(字符串/整数)或参数引用

这是我目前掌握的 Xtext 语法

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

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

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

Model:
    parameters+=Parameter*
    intParameters+=IntParameter*
    elements+=Element*
    otherElements+=AnotherElement*
    ;

Parameter returns Parameter:
    StringParameter | IntParameter
;

StringParameter returns StringParameter:
    {StringParameter}
    'StringParameter'
    name=EString
    '{'
        ('value' value=EString)?
    '}';
    
IntParameter returns IntParameter:
    {IntParameter}
    'IntParameter'
    name=EString
    '{'
        ('value' value=DECINT)?
    '}';

Element returns Element:
    'Element'
    '{'
        'name' name=[StringParameter|EString]
    '}';
    
AnotherElement returns AnotherElement:
    'AnotherElement'
    '{'
        'value' value=[IntParameter|EString]
    '}';

EString returns ecore::EString:
    STRING | ID;
    
terminal fragment DIGIT: '0'..'9';
terminal DECINT: '0' | ('1'..'9' DIGIT*) | ('-''0'..'9' DIGIT*) ;

上述语法只允许引用现有参数。如何直接为元素赋值?

StringParameter test { value "hello" }
IntParameter dummy { value 4 }

Element { name test } // works 
Element { name blah } // ERROR: Couldn't resolve reference to StringParameter 'blah'.   

AnotherElement { value dummy } // works
AnotherElement { value 7 } // ERROR: no viable alternative at input '7'
                           // ERROR: Couldn't resolve reference to IntParameter '7'.

编辑1:基于Xtext grammar variable definition/reference中的例子,我修改了我的语法:

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

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

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

Model:
    parameters+=StringParameter*
    elements+=Element*;

Element returns Element:
    'Element'
    '{'
        'name' value=StringValue
    '}';

StringValue:
    StringLiteral | StringRefParameter;

StringRefParameter:
    ref=[StringParameter|EString];

StringLiteral:
    value=EString;

StringParameter returns StringParameter:
    {StringParameter}
    'StringParameter'
    name=EString
    '{'
        ('value' value=EString)?
    '}';

EString returns ecore::EString:
    STRING | ID;

但是生成器失败了

1212 [main] INFO  text.xtext.generator.XtextGenerator  - Generating common infrastructure
1237 [main] ERROR mf.mwe2.launch.runtime.Mwe2Launcher  - Problems running workflow org.xtext.example.mydsl.GenerateMyDsl: 
[ERROR]: GeneratorException: (Element: -UNKNOWN-; Reported by: XtextGenerator)
     org.eclipse.xtext.util.RuntimeIOException: java.io.FileNotFoundException: /home/user/ws/org.xtext.example.mydsl/../org.xtext.example.mydsl/src-gen/org/xtext/example/mydsl/parser/antlr/internal/InternalMyDslLexer.java (No such file or directory)

编辑 2:该语法适用于整数

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

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

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

Model:
    parameters+=IntParameter*
    elements+=Element*
    ;

Element returns Element:
    'Element'
    '{'
        'name' value=IntValue
    '}';

IntValue:
    ref=[IntParameter] | value=DECINT
;

IntParameter returns IntParameter:
    {IntParameter}
    'IntParameter'
    name=EString
    '{'
        ('value' value=DECINT)?
    '}';

EString returns ecore::EString:
    STRING | ID;
    
terminal fragment DIGIT: '0'..'9';
terminal DECINT: '0' | ('1'..'9' DIGIT*) | ('-''0'..'9' DIGIT*) ;

以下代码有效

IntParameter dummy { value 4 }

Element { name dummy }
Element { name 5 }

任何想法它如何适用于字符串?

【问题讨论】:

    标签: eclipse xtext eclipse-emf


    【解决方案1】:

    通过将StringValue 更改为

    StringValue:
        ref=[StringParameter|EString] | value=EString
    

    StringValue:
        ref=[StringParameter] | value=EString
    

    为我工作。语法现在看起来像:

    grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
    
    generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
    
    import "http://www.eclipse.org/emf/2002/Ecore" as ecore
    
    Model:
        stringParameters+=StringParameter*
        elements+=Element*
        ;
    
    Element returns Element:
        'Element'
        '{'
            'name' value=StringValue
        '}';
    
    StringValue:
        ref=[StringParameter] | value=EString
    ;
    
    StringParameter returns StringParameter:
        {StringParameter}
        'StringParameter'
        name=EString
        '{'
            ('value' value=EString)?
        '}';
    
    EString returns ecore::EString:
        STRING | ID;
    

    代码是

    StringParameter test { value hello }
    
    Element { name "world" }
    Element { name test }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-14
      • 2015-09-23
      • 2012-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      • 2012-05-13
      相关资源
      最近更新 更多