Daniel Schmidt
Daniel Schmidt

Reputation: 11921

How to allow a line of Java Code in a Xtext grammar

Question: I would like to have an execution block in my grammar, which allows any valid java line (or just any line, this would be okay, too) within its borders:

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
;    

This is the relevant part of the grammar, how would I have to build JavaLine in order to get any line?

Bonus Question: I have other rules like OutPort or Parameter, how can I prevent them from being used within my execute block? (I get syntax highlighted out keywords within my java lines)

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
;     

Upvotes: 1

Views: 160

Answers (3)

gaborsch
gaborsch

Reputation: 15758

Java code is not organized into lines. Technically almost any line is acceptable as a Java source code, because you can put /* */ multi-line comment in a Java source.

If you prescind from line concept, you can parse Java source using Java Grammar (Java7) or Java Grammar (Java8) - that's quite a big work.

Perhaps easier if you only implement Block grammar (see here) - that represents an executable block in Java. That's less work.

If you want to allow one-liner Java code only (preserving the line concept), you can focus to Statement level, picking the allowed statement-types (e.g. no subclass definition, no labels, etc.)

Upvotes: 1

Daniel Schmidt
Daniel Schmidt

Reputation: 11921

I ended up using this:

Execution:
  content=JAVA_LINE
;

terminal JAVA_LINE:
  'execute'
    '{'->'}' // TODO: this doesn't fit quite its needs
;

For the code generation I had to remove some content from the content string, but everything else works fine.

Upvotes: 0

Georg Leber
Georg Leber

Reputation: 3580

First Question:

One possibility to define it as String instead of list words (with ID). You can later transform the string to Java Code in the generation process.

JavaLine:
    {JavaLine}(words=STRING)* ';'
; 

Second Question:

If you use my suggestion for question one, the second problem should be obsolete.

Upvotes: 0

Related Questions