如何在 Xtext 语法中允许一行 Java 代码
How to allow a line of Java Code in a Xtext grammar
问题: 我想在我的语法中有一个执行块,它允许任何有效的 java 行(或者只是任何行,这样就可以了,也)在其边界内:
Execution:
{Execution} 'execute {'
(lines+=(JavaLine | Referral))*
'}'
;
Referral:
inReferal | outReferal
;
inReferal:
name=ID '<=' port=ID
;
outReferal:
name=ID '=>' port=ID
;
JavaLine:
{JavaLine}(words+=ID)* ';' // this doesn't fit quite its needs, no . - { etc allowed
;
这是语法的相关部分,我将如何构建 JavaLine 以获得任何行?
奖金问题:我有其他规则,如 OutPort 或 Parameter,如何防止它们在我的执行块中使用? (我的 java 行中的关键字语法突出显示)
Model:
stages+=Stage*;
Stage:
'stage' name=ID (('implements' interfaces=List)? & ('extends' extension=ID)?) '{'
lines+=StageItems*
'}';
List: items+=ID (',' items+=ID)*;
StageItems:
InPort | OutPort | Parameter | Execution
;
Parameter:
'param' type=ID name=ID
;
InPort:
'in' type=ID name=ID
;
OutPort:
'out' type=ID name=ID
;
第一个问题:
一种将其定义为字符串而不是列表词(带 ID)的可能性。您可以稍后在生成过程中将字符串转换为 Java 代码。
JavaLine:
{JavaLine}(words=STRING)* ';'
;
第二题:
如果你对问题一使用我的建议,那么第二个问题应该已经过时了。
Java 代码未按行组织。从技术上讲,几乎任何行都可以作为 Java 源代码,因为您可以在 Java 源代码中放置 /* */
多行注释。
如果您摆脱了 行 概念,您可以使用 Java Grammar (Java7) or Java Grammar (Java8) 解析 Java 来源 - 这是一项相当大的工作。
如果您只实现 Block 语法 (see here) 可能会更容易 - 它表示 Java 中的可执行块。这样工作就少了。
如果只允许一行 Java 代码(保留 line 概念),您可以关注 Statement 级别,选择允许的语句类型(例如,没有子类定义,没有标签等)
我最终使用了这个:
Execution:
content=JAVA_LINE
;
terminal JAVA_LINE:
'execute'
'{'->'}' // TODO: this doesn't fit quite its needs
;
对于代码生成,我不得不从内容字符串中删除一些内容,但其他一切正常。
问题: 我想在我的语法中有一个执行块,它允许任何有效的 java 行(或者只是任何行,这样就可以了,也)在其边界内:
Execution:
{Execution} 'execute {'
(lines+=(JavaLine | Referral))*
'}'
;
Referral:
inReferal | outReferal
;
inReferal:
name=ID '<=' port=ID
;
outReferal:
name=ID '=>' port=ID
;
JavaLine:
{JavaLine}(words+=ID)* ';' // this doesn't fit quite its needs, no . - { etc allowed
;
这是语法的相关部分,我将如何构建 JavaLine 以获得任何行?
奖金问题:我有其他规则,如 OutPort 或 Parameter,如何防止它们在我的执行块中使用? (我的 java 行中的关键字语法突出显示)
Model:
stages+=Stage*;
Stage:
'stage' name=ID (('implements' interfaces=List)? & ('extends' extension=ID)?) '{'
lines+=StageItems*
'}';
List: items+=ID (',' items+=ID)*;
StageItems:
InPort | OutPort | Parameter | Execution
;
Parameter:
'param' type=ID name=ID
;
InPort:
'in' type=ID name=ID
;
OutPort:
'out' type=ID name=ID
;
第一个问题:
一种将其定义为字符串而不是列表词(带 ID)的可能性。您可以稍后在生成过程中将字符串转换为 Java 代码。
JavaLine:
{JavaLine}(words=STRING)* ';'
;
第二题:
如果你对问题一使用我的建议,那么第二个问题应该已经过时了。
Java 代码未按行组织。从技术上讲,几乎任何行都可以作为 Java 源代码,因为您可以在 Java 源代码中放置 /* */
多行注释。
如果您摆脱了 行 概念,您可以使用 Java Grammar (Java7) or Java Grammar (Java8) 解析 Java 来源 - 这是一项相当大的工作。
如果您只实现 Block 语法 (see here) 可能会更容易 - 它表示 Java 中的可执行块。这样工作就少了。
如果只允许一行 Java 代码(保留 line 概念),您可以关注 Statement 级别,选择允许的语句类型(例如,没有子类定义,没有标签等)
我最终使用了这个:
Execution:
content=JAVA_LINE
;
terminal JAVA_LINE:
'execute'
'{'->'}' // TODO: this doesn't fit quite its needs
;
对于代码生成,我不得不从内容字符串中删除一些内容,但其他一切正常。