简体   繁体   English

xtext生成器表达式getLeft和getRight

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM