我正在尝试通过Xtext编写DSL,我可以使用它来自定义SQL。首先,我想要一个我的查询的字符串表示。在那里我被卡在表情上。我在这个例子后创建了它们:…
鉴于以下简化语法
grammar org.xtext.example.mydsl1.MyDsl with org.eclipse.xtext.common.Terminals generate myDsl "http://www.xtext.org/example/mydsl1/MyDsl" Model: (expressions+=Expression ";")*; Expression returns Expression: OrExpression; OrExpression returns Expression: PrimaryExpression ({OrExpression.left=current} name="OR" right=PrimaryExpression)*; PrimaryExpression returns Expression: '(' Expression ')' | {Negation} "NOT" expr=Expression | {IntLiteral} value=INT | {StringLiteral} value=STRING | {Variable} name=ID;
输入 NOT x or y 可以用两种方式解析:
NOT x or y
Or(Negation(Variable("x")), Variable("y"))
或者作为
Negation(Or(Variable("x"), Variable("y")))
在编译Xtext语法时,它告诉你(有点模糊)警告这样:
warning(200): ../org.xtext.example.mydsl1/src-gen/org/xtext/example/mydsl1/parser/antlr/internal/InternalMyDsl.g:195:3: Decision can match input such as "'OR'" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input
这里的重要部分是: [...]alternative(s) 2 were disabled for that input 。因此,你的语法部分是死代码并被有效忽略。
[...]alternative(s) 2 were disabled for that input
解决方案:放 的 所有 强> 运算符正确地进入优先级层次结构。做 的 不 强> 把任何复杂的东西放入 PrimaryExpression 。事实上 ( Expression ) 应该是 的 只要 强> 在层次结构中调用更高规则的地方。结果是这样的无冲突语法:
PrimaryExpression
( Expression )
OrExpression returns Expression: IsNullExpression ({OrExpression.left=current} name="OR" right=IsNullExpression)*; IsNullExpression returns Expression: CompareExpression ({IsNullExpression.expr=current} 'IS' not?='NOT'? 'NULL')?; CompareExpression returns Expression: NegationExpression ({CompareExpression.left=current} name=("NOT"| "=" | "!=") right=NegationExpression)*; NegationExpression returns Expression: {NegationExpression} name=("NOT" | "-") expr=PrimaryExpression | PrimaryExpression; PrimaryExpression returns Expression: '(' Expression ')' | {IntLiteral} name=INT | {StringLiteral} name=STRING | {Variable} name=ID;
请注意,尽管在不同的地方多次使用了多个关键字,但这种语法是无冲突的(例如, NOT , - )。
NOT
-