eclipse - 引用实例或文字值的 Xtext 语法
问题描述
我正在尝试对基于 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 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 }
任何想法它如何适用于字符串?
解决方案
通过改变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 }
推荐阅读
- java - 我需要在单击按钮时录制音频,然后将该录音保存在外部存储中
- javascript - 无法导出带有 DIV 元素的 c3.js 图表
- sql - MS Access 2010:SQL WHERE 字符串 LIKE 字段
- c# - 头孢夏普铬。如何创建自定义项目?
- android - 由慢速测量/布局传递引起的片段过渡卡顿
- c# - 在 UWP 下,GetRectFromCharacterIndex 不返回调整为控件样式的值
- sql-server - 在 SQL Server 中恢复 .bak 错误循环冗余检查
- ethereum - 智能合约众筹
- google-visualization - Google Visualization 以点的形式提供一条线
- javascript - 为什么此 JavaScript 代码的输出“未声明”?