如何在 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
;

对于代码生成,我不得不从内容字符串中删除一些内容,但其他一切正常。