引用实例或文字值的 Xtext 语法
Posted
技术标签:
【中文标题】引用实例或文字值的 Xtext 语法【英文标题】:Xtext grammar with either reference to instance or literal value 【发布时间】: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
任何想法它如何适用于字符串?
【问题讨论】:
【参考方案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
【讨论】:
以上是关于引用实例或文字值的 Xtext 语法的主要内容,如果未能解决你的问题,请参考以下文章