Rewrite Action Problem [message #1067534] |
Tue, 09 July 2013 09:04 |
|
Hi,
I want to define a Java like language with classes containing fields or
methods. In a simple grammar, this could be written as
// version A
Member: Field | Method;
Field: type=Type name=ID ';';
Method: type=Type name=ID '(' pl=ParamList ')' ";";
Unfortunately, my "Type" rule is rather complicated. This leads to the
following error in the generated antlr grammar:
[fatal] rule ruleMember has non-LL(*) decision due to recursive rule
invocations reachable from alts 1,2. Resolve by left-factoring or using
syntactic predicates or using backtrack=true option.
Now, I do not want to enable backtracking. Also, I'm not sure how to
solve that problem with syntactic predicates. The problem is that both,
Field and Method, start with the type and the name. In general, that
seems to be a perfect candidate for a rewrite action. And as a matter of
fact, the following code is working:
// version B
Member:
Type
(
({Field.type=current} name=ID)
|
({Method.type=current} name=ID '(' pl=ParamList ')')
)
";";
So, instead of backtracking, the found type (current) is set as the type
of the field or method. Unfortunately, when the grammar is generated,
this leads to a weird class hierarchy, as Member becomes a super type of
Type. I could remove that generalization in a post processing step, but
in the long run I want to import the ecore model instead of generating
it. Now, with an imported ecore model and with the generalization
removed, the grammar snippet above creates an error:
"Cannot add supertype 'Member' to sealed type 'Type'."
So, what can I do? What I basically need is a rewrite action that could
rewrite even if a "current" is already created. E.g.,
// version C
Member:
type=Type
(
({Field} name=ID)
|
({Method} name=ID '(' pl=ParamList ')')
)
";";
Well, this is not working as explained above (current is already created).
Conclusion: The problem is not a grammar problem, but only a model
problem. My solution (version B) is working from a grammar point of
view, but it relies on a wrong model. Is there a way to solve that problem?
Could that problem be solved with syntactic predicates? I know that the
non-LL(*) decision problem is cased by some constructs defined in my
Type rule---however, it works with version B and w/o syntactic
predicates. I already tried to introduce syntactic predicates, but that
didn't really help.
Regards,
Jens
|
|
|
|
Re: Rewrite Action Problem [message #1067576 is a reply to message #1067534] |
Tue, 09 July 2013 12:06 |
|
Hi Jens,
On 09.07.13 12:32, Jens Kuenzer wrote:> Left factor Type might help,
something like this:
>
> Member: Type ( {Fiels.type=current} name=ID ';' )
> | ( {Method.type=current} name=ID '(' pl=ParamList ')'
";" );
Well, that is my solution version B, isn't it? The problem about that is
the wrong type hierarchy: Member becomes a super type of Type, which is
weird.
Regards,
Jens
|
|
|
|
Re: Rewrite Action Problem [message #1067922 is a reply to message #1067534] |
Thu, 11 July 2013 09:11 |
|
Hi,
ok, Sebastian Xtext-Wizard-Zarnekow told me how the problem can be
solved with syntactic predicates:
Member: Field | Method;
Field: type=Type name=IDENTIFIER;
Method: =>(type=Type name=IDENTIFIER "(") (pl=ParamList ")";
NB the parentheses of the syntactic predicate!
Regards,
Jens
|
|
|
Powered by
FUDForum. Page generated in 0.03359 seconds