Xtext:递归规则信息

时间:2014-03-10 15:32:49

标签: grammar xtext

我正在尝试构建一种可以声明方法和字段的语言,并对泛型有内在的支持。我希望能够使用像String这样的原始类型,并声明我自己的类。

这应该是有效的语法:

String somePrimitive

class MyClass { }
MyClass someObject;

class List { }
List<String> stringList;
List<MyClass> objectList;

List<String> getNames() { }

我有一个支持这些操作的语法:

Model:
    (members+=ModelMembers)*;

ModelMembers:
    Class | Field | MethodDeclaration
;

Class:
    'class' name=ID '{' '}'
;

Field:
    type=Type
    name=ID
;

enum PrimitiveType: STRING="String" | NUMBER="Number";

Type:
    (
        {TypeObject} clazz=[Class] ("<" a+=Type ("," a+=Type)* ">")? 
        |
        {TypePrimitive} type=PrimitiveType 
    )
;

MethodDeclaration:
    returnType=Type name=ID "(" ")" "{"

    "}"
;

但它包含错误:

[fatal] rule rule__ModelMembers__Alternatives has non-LL(*) decision due to recursive rule invocations reachable from alts 2,3.  Resolve by left-factoring or using syntactic predicates or using backtrack=true option.

问题似乎源于Type规则是递归的,并且可以匹配为MethodDeclarationField的开头。

但是,可以找出正在构建的规则,因为该方法在名称后面会有() { }

真正让我困惑的是,如果我用简单[Class]替换递归规则,例如Field: type=[Class] name=ID(和MethodDeclaration相同)语法有效。

当我看到Type的实例时,我发现存在一些歧义,因为它可能导致方法或字段....但是当我用[Class]替换时,这完全相同。类的实例可以引导到方法或字段。

如何使用Type模糊不清,但使用[Class]时不明确?

2 个答案:

答案 0 :(得分:1)

这不是您问题的直接答案,但您是否考虑过使用Xbase而不是简单的Xtext?使用Xbase,您可以简单地使用符合您所需要的预定义规则:

  • 带有泛型的Java类型
  • 表达式
  • 注解

还有更多。

以下是一些有用的链接:

如果Xbase不适合您,那么您可以从中学习Xbase-Xtext-Grammar

答案 1 :(得分:1)

这个语法解析示例代码而不会抛出错误(布局是Terence Parr所青睐的,ANTLR人。我发现它有很大帮助):

Model
  : (members+=ModelMembers)*
  ;    

ModelMembers
  : Class 
  | MethodDeclaration
  | Field
  ;

Class
  : 'class' name=ID '{' '}'
  ;

Field
  : type=Type name=ID ';'
  ;

PrimitiveType
  : ("String" |"Number")
  ;

TypeReferenceOrPrimitive
  : {TypeClass} type=[Class]
  | {TypePrimitive} PrimitiveType
  ;

Type
  : {TypeObject} clazz=[Class] ("<" a+=TypeReferenceOrPrimitive ("," a+=TypeReferenceOrPrimitive)* ">")?
  | {TypePrimitive} type=PrimitiveType   
  ;

MethodDeclaration
  : returnType=Type name=ID "(" ")" "{"  "}"
  ;

我不是Xtext专家所以可能有更好的方法。我的'诀窍'是 define TypeReferenceOrPrimitive 。为了获得更容易处理的AST,您可能需要更多地使用语法。