[英]xtext generator expression getLeft and getRight
I'm trying to write a DSL via Xtext with which I can customize SQL. 我正在尝试通过Xtext编写DSL,以便可以自定义SQL。 First I want to have a string representation of my query. 首先,我要查询的字符串表示形式。 There I got stuck on the expressions. 在那里,我陷入了表情。 I created them after this example: https://typefox.io/parsing-expressions-with-xtext . 我在以下示例之后创建了它们: https : //typefox.io/parsing-expressions-with-xtext 。
Expression returns Expression:
OrExpression;
OrExpression returns Expression:
AndExpression ({OrExpression.left=current} name="OR" right=AndExpression)*;
AndExpression returns Expression:
NotExpression({AndExpression.left=current} name="AND" right=NotExpression)*;
NotExpression returns Expression:
ComparisonExpression({NotExpression.left=current} name='NOT' right=ComparisonExpression)*;
ComparisonExpression returns Expression:
BitwiseOR({ComparisonExpression.left=current} name=cmpop right=BitwiseOR)*;
BitwiseOR returns Expression:
BitwiseAND ({BitwiseOR.left=current} name='|' right=BitwiseAND)*;
BitwiseAND returns Expression:
BitwiseXOR ({BitwiseAND.left=current} name='&' right=BitwiseXOR)*;
BitwiseXOR returns Expression:
Addition ({BitwiseXOR.left=current} name='^' right=Addition)*;
Addition returns Expression:
Substraction ({Addition.left=current} name='+' right=Substraction)*;
Substraction returns Expression:
Multiplication ({Substraction.left=current} name='-' right=Multiplication)*;
Multiplication returns Expression:
Division ({Multiplication.left=current} name='*' right=Division)*;
Division returns Expression:
Modulo ({Division.left=current} name='/' right=Modulo)*;
Modulo returns Expression:
Primary ({Modulo.left=current} name='%' right=Primary)*;
Primary returns Expression:
=> count=count
| => func=funccall
| {Bracket} '(' inner=Expression ')'
| (name=unop) expr=Expression
| (name=unop)? ID=Literal ('IS' 'NOT'? 'NULL')?;
/*Values that a Expression can have */
Literal returns Expression:
value=values;
I can manage to get to get a single value but im unable to get the left or the right side of a expression. 我可以设法获得一个值,但是我无法获得表达式的左侧或右侧。
My Generator (unfinished and with my testings looks like this) 我的生成器(未完成,并经过测试)
class TsqlGenerator extends AbstractGenerator {
StringBuilder st = new StringBuilder();
TimeConditionHandler tch = new TimeConditionHandler
ExpressionHandler exprH = new ExpressionHandler
String expression = ""
int fromIndex = 0;
int whereIndex
def clear() {
st.delete(0, st.length);
fromIndex = 0;
whereIndex =0;
}
override beforeGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) { clear() }
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
for (e : resource.allContents.toIterable.filter(ComplexSelect)) {
/*SELECT */
// TODO: String Value ohne Anführungszeichen?
st.append("SELECT ");
for (selectArgument : e.left.selectArguments.arguments) {
if (selectArgument.expr.name == null) {
//hier später in eine Liste speichern?
st.append(" " + selectArgument.expr.ID.value.name);
}else {
// TODO: Generate a Sting of the Expression!
}
}
/*FROM */
st.append(" FROM ")
//Hier ebenso in eine Liste speichern?
for (fromSource : e.left.from.sources) {
st.append(e.left.from.sources.get(fromIndex).name);
}
/*WHERE */
if (e.left.where !== null || e.left.timedef !== null) {
st.append(" WHERE");
if (e.left.where !== null) {
for (whereArgument : e.left.where.predicates.expr) {
if (whereIndex == 0) {
st.append(" " + whereArgument.ID.value.name);
} else {
st.append("AND " + whereArgument.ID.value.name);
}
whereIndex++;
}
}
/*TIMEINTERVALL
*TODO: timestamp as columname hardcoded*/
if (e.left.timedef !== null) {
if (whereIndex > 0) {
st.append(" AND")
}
st.append(tch.toIso8601(e.left.timedef))
//if (e.left.timedef.name != null) {
//st.append(" ").append(e.left.where.name);
}
}
fsa.generateFile("query.txt", st.toString());
}
}
Given the following simplified grammar 给出以下简化的语法
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;
the input NOT x or y
can be parsed in two ways: Either as 输入NOT x or y
可以通过两种方式解析:
Or(Negation(Variable("x")), Variable("y"))
or as 或作为
Negation(Or(Variable("x"), Variable("y")))
When compiling the Xtext grammer it tells you so (somewhat vaguely) with warnings likes this: 编译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
The important part here is: [...]alternative(s) 2 were disabled for that input
. 此处的重要部分是: [...]alternative(s) 2 were disabled for that input
。 So parts of your grammar are dead code and effectively ignored. 因此,语法的某些部分是无效代码,实际上已被忽略。
Solution: Put all operators into the precedence hierarchy properly. 解决方案:将所有运算符正确放入优先级层次结构。 Do not put anything complex into PrimaryExpression
. 不要把事情复杂到PrimaryExpression
。 In fact ( Expression )
should be the only place which calls a rule higher in the hierarchy. 实际上( Expression )
应该是在层次结构中调用规则更高的唯一位置。 The result is a conflict-free grammar like this: 结果是这样的无冲突语法:
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;
Note that this grammar is conflict free despite several keywords are used multiple times in distinct places (eg NOT
, -
). 请注意,尽管在不同的地方多次使用了多个关键字(例如NOT
, -
),但该语法没有冲突。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.