Xtext-Error: rule ruleReference has non-LL(*) decision due to recursive rule invocations... [message #891882] |
Tue, 26 June 2012 08:30  |
Eclipse User |
|
|
|
I get the following error in my Grammar 2:
error(211): ../org.lunifera.metamodel.dsl.jpa/src-gen/org/lunifera/metamodel/dsl/jpa/parser/antlr/internal/InternalJpa.g:323:1: [fatal] rule ruleReference has non-LL(*) decision due to recursive rule invocations reachable from alts 1,3. Resolve by left-factoring or using syntactic predicates or using backtrack=true option.
I have a Grammar with 2 files.
Grammar 1
grammar org.lunifera.metamodel.dsl.entity.Entity with org.eclipse.xtext.xbase.annotations.XbaseWithAnnotations
generate entity "http://www.lunifera.org/metamodel/dsl/entity/Entity"
import "http://www.eclipse.org/xtext/xbase/Xbase" as xbase
import "http://www.eclipse.org/Xtext/Xbase/XAnnotations"
EntityModel:
package=Package & elements+=AbstractElement*;
Package:
'package' name=QualifiedName ';';
AbstractElement:
Import | Entity;
Import:
'import' importedNamespace=QualifiedNameWithWildCard ';';
Entity:
'entity' name=ValidID ('extends' superType=JvmTypeReference)? '{'
features+=AbstractFeature* '}';
AbstractFeature:
Property | Reference | Operation;
Reference:
RefContains | RefEmbedds | RefRefers;
Property:
'var' type=JvmTypeReference name=ValidID ';';
RefRefers:
'ref' type=JvmTypeReference name=ValidID ('[' lowerBound=BoundLiteral '..' upperBound=BoundLiteral ']')
';';
RefContains:
'contains' type=JvmTypeReference name=ValidID ('[' lowerBound=BoundLiteral '..' upperBound=BoundLiteral ']')
';';
RefEmbedds:
'embedds' type=JvmTypeReference name=ValidID
';';
Operation:
(operationAnnotation+=XAnnotation)* (modifier=Modifier)? 'def' type=JvmTypeReference name=ValidID '('
(params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)? ')' body=MyBlockExpression;
Modifier:
final?='final'? & static?='static'? & visibility=Visibility;
enum Visibility:
PACKAGE='package' | PRIVATE='private' | PROTECTED='protected' | PUBLIC='public';
enum RefType:
CONTAINS='contains' | EMBEDDS='embedds' | REFERS='refers';
enum BoundLiteral:
ONE='1' | MANY='n';
QualifiedNameWithWildCard:
QualifiedName ('.' '*')?;
MyBlockExpression returns xbase::XExpression:
{xbase::XBlockExpression} '{' (expressions+=XExpressionInsideBlock ';')* '}';
Grammar 2
grammar org.lunifera.metamodel.dsl.jpa.Jpa with org.lunifera.metamodel.dsl.entity.Entity
generate jpa "http://www.lunifera.org/metamodel/dsl/jpa/Jpa"
import "http://www.eclipse.org/xtext/xbase/Xbase" as xbase
import "http://www.eclipse.org/xtext/xbase/Xtype" as xtype
import "http://www.eclipse.org/xtext/common/JavaVMTypes" as types
import "http://www.eclipse.org/Xtext/Xbase/XAnnotations"
JModel:
jmodel=EntityModel;
Entity:
(annotations+=JpaEntityAnnotation)*
'entity' name=ValidID ('extends' superType=JvmTypeReference)? '{'
features+=AbstractFeature* '}';
Property:
(annotations+=JpaPropertyAnnotation)*
varType='var' type=JvmTypeReference name=ValidID ';';
RefRefers:
(annotations+=JpaReferenceAnnotation)*
'ref' type=JvmTypeReference name=ValidID ('[' lowerBound=BoundLiteral '..' upperBound=BoundLiteral ']')
';';
RefContains:
(annotations+=JpaReferenceAnnotation)*
'contains ref' type=JvmTypeReference name=ValidID ('[' lowerBound=BoundLiteral '..' upperBound=BoundLiteral ']')
';';
RefEmbedds:
(annotations+=JpaReferenceAnnotation)*
'embedds ref' type=JvmTypeReference name=ValidID
';';
JpaAnnotation:
JpaEntityAnnotation | JpaPropertyAnnotation | JpaReferenceAnnotation;
JpaEntityAnnotation:
EmbeddableAnnotation | CachableAnnotation;
JpaPropertyAnnotation:
IdAnnotation | NullableAnnotation;
JpaReferenceAnnotation:
ManyToManyAnnotation;
EmbeddableAnnotation:
{EmbeddableAnnotation}
'@' name='Embeddable';
CachableAnnotation:
{CachableAnnotation}
'@' name='Cachable';
IdAnnotation:
{IdAnnotation}
'@' name='ID';
NullableAnnotation:
{NullableAnnotation}
'@' name='Nullable';
ManyToManyAnnotation:
{ManyToManyAnnotation}
'@' name='ManyToMany' ('(' (('targetEntity=' targetEntity=JvmParameterizedTypeReference) ', '
'mappedBy='
mappedBy=ValidID)?
')')?;
I get the error in Grammar 2.
Please help me why I get this error in Grammar 2.
|
|
|
Re: Xtext-Error: rule ruleReference has non-LL(*) decision due to recursive rule invocations... [message #892473 is a reply to message #891882] |
Thu, 28 June 2012 07:27  |
Eclipse User |
|
|
|
Hi,
the problem is here:
ManyToManyAnnotation:
{ManyToManyAnnotation}
'@' name='ManyToMany' ('(' (('targetEntity='
targetEntity=JvmParameterizedTypeReference) ', '
'mappedBy='
mappedBy=ValidID)?
')')?;
And the fact that you have three differnent rules like this one here:
RefRefers:
(annotations+=JpaReferenceAnnotation)*
Because of that and the Structure of the Rule JvmParameterizedTypeReference:
JvmParameterizedTypeReference:
type=[JvmType|QualifiedName] (=>'<'
arguments+=JvmArgumentTypeReference (','
arguments+=JvmArgumentTypeReference)* '>')?;
The AST can grow to both sides. LEFT_RECURSION.
The easiest fix is to introduce a keyword in from of the list. ;-) But
that is really ugly.
RefRefers:
'annotations1' (annotations+=JpaReferenceAnnotation)*
'ref' type=JvmTypeReference name=ValidID ('['
lowerBound=BoundLiteral '..' upperBound=BoundLiteral ']')
';';
RefContains:
'annotations2'(annotations+=JpaReferenceAnnotation)*
'contains ref' type=JvmTypeReference name=ValidID ('['
lowerBound=BoundLiteral '..' upperBound=BoundLiteral ']')
';';
RefEmbedds:
'annotations3'(annotations+=JpaReferenceAnnotation)*
'embedded ref' type=JvmTypeReference name=ValidID
';';
If you do not really need a ParameterizedTypeReference you can use a
JvmType directly.
ManyToManyAnnotation:
{ManyToManyAnnotation}
'@' name='ManyToMany' ('(' (('targetEntity='
targetEntity=[types::JvmType|QualifiedName]) ', '
'mappedBy='
mappedBy=ValidID)?
')')?;
Do the whole grammar would look like this:
grammar org.lunifera.metamodel.dsl.jpa.Jpa with
org.lunifera.metamodel.dsl.entity.Entity
generate jpa "http://www.lunifera.org/metamodel/dsl/jpa/Jpa"
import "http://www.eclipse.org/xtext/xbase/Xbase" as xbase
import "http://www.eclipse.org/xtext/xbase/Xtype" as xtype
import "http://www.eclipse.org/xtext/common/JavaVMTypes" as types
import "http://www.eclipse.org/Xtext/Xbase/XAnnotations"
JModel:
jmodel=EntityModel;
Entity:
(annotations+=JpaEntityAnnotation)*
'entity' name=ValidID ('extends' superType=JvmTypeReference)? '{'
features+=AbstractFeature* '}';
Property:
(annotations+=JpaPropertyAnnotation)*
varType='var' type=JvmTypeReference name=ValidID ';';
RefRefers:
(annotations+=JpaReferenceAnnotation)*
'ref' type=JvmTypeReference name=ValidID ('['
lowerBound=BoundLiteral '..' upperBound=BoundLiteral ']')
';';
RefContains:
(annotations+=JpaReferenceAnnotation)*
'contains ref' type=JvmTypeReference name=ValidID ('['
lowerBound=BoundLiteral '..' upperBound=BoundLiteral ']')
';';
RefEmbedds:
(annotations+=JpaReferenceAnnotation)*
'embedded ref' type=JvmTypeReference name=ValidID
';';
JpaAnnotation:
JpaEntityAnnotation | JpaPropertyAnnotation | JpaReferenceAnnotation;
JpaEntityAnnotation:
EmbeddableAnnotation | CachableAnnotation;
JpaPropertyAnnotation:
IdAnnotation | NullableAnnotation;
JpaReferenceAnnotation:
ManyToManyAnnotation;
EmbeddableAnnotation:
{EmbeddableAnnotation}
'@' name='Embeddable';
CachableAnnotation:
{CachableAnnotation}
'@' name='Cachable';
IdAnnotation:
{IdAnnotation}
'@' name='ID';
NullableAnnotation:
{NullableAnnotation}
'@' name='Nullable';
ManyToManyAnnotation:
{ManyToManyAnnotation}
'@' name='ManyToMany' ('(' (('targetEntity='
targetEntity=[types::JvmType|QualifiedName]) ', '
'mappedBy='
mappedBy=ValidID)?
')')?;
Cheers,
Holger
|
|
|
Powered by
FUDForum. Page generated in 0.25635 seconds