Xtext-带有合成标记的类似Python的DSL

Xtext-带有合成标记的类似Python的DSL,python,xtext,synthetic,Python,Xtext,Synthetic,我正在做我的dsl项目。但当我想让它像python(支持空白的语言)一样工作时,它会给我错误“输入不匹配”\t“需要规则\u BEGIN”。终端规则开始意味着什么?为什么下面的例子不起作用? 这是我的语法: grammar org.pythonDSL.PythonDSL hidden(WS) generate pythonDSL "http://www.pythonDSL.org/PythonDSL" import "http://www.eclipse.or

我正在做我的dsl项目。但当我想让它像python(支持空白的语言)一样工作时,它会给我错误“输入不匹配”\t“需要规则\u BEGIN”。终端规则开始意味着什么?为什么下面的例子不起作用? 这是我的语法:

grammar org.pythonDSL.PythonDSL

hidden(WS)

generate pythonDSL "http://www.pythonDSL.org/PythonDSL"

import "http://www.eclipse.org/emf/2002/Ecore" as ecore

PythonDSL:
    (elements+=AbstractElement)*;
 
AbstractElement:
    type=(Stmt|Config);
 
QualifiedName:
    ID ('.' ID)*;
    
Comment:
    name=(ML_COMMENT|SL_COMMENT);

Import:
    'import' importedNamespace=QualifiedNameWithWildcard;

Config:
    {Config} 'config' configs=Dictionary;

KeyValue:
    name=QualifiedValue ':' value=QualifiedValue;

QualifiedNameWithWildcard:
    QualifiedName '.*'?;

QualifiedIndex:
INT|STRING;

Dictionary:
    {Dictionary} '{' (elements+=KeyValue)+ '}';

Set:
    {Set} '{' (elements+=QualifiedValue)* '}';

List:
    {List} '[' (elements+=QualifiedValue)* ']';

QualifiedValue:
STRING|'True'|'False'|INT;

VarDec:
name=ID('['index=QualifiedIndex']')? '=' value=QualifiedValue;

Stmt:
 type=(Exp|Import) NEXT_LINE | type=If | type=Comment;

If:
    'if' (not='not')? condition=Exp ':' NEXT_LINE?
     (BEGIN ( ifStmts+=Stmt)* END)
    (=> elseIfClause+=ElseIf)*
    (=> elseClause=Else)?;

ElseIf:
    'elif'  condition=Exp ':' NEXT_LINE?
     (BEGIN ( elseIfStmts+=Stmt)* END);

Else:
    {Else} 'else' NEXT_LINE? (BEGIN ( elseStmts+=Stmt)* END);

Exp:
    left=Equal;

Ret:
    'return' name=ID;

Var:
    name=ID;


Val:
    name=QualifiedValue | type=(Dictionary|List|Set);

Dot returns Exp:
    left=Array ({Dot.left=current} op='.'right=Array)*
;

Array returns Exp:
    left=Primary ({Array.left=current} op='['right=Primary']')*
;

Primary returns Exp:
   op='(' left=Equal ')' |left=Var|left=Val|left=FuncCall;

ArgList:
    {ArgList} (args+=Equal)? (',' args+=Equal)*;

FuncCall:
    name=Var (op='(' right=ArgList ')');

Equal returns Exp:
    left=AddAndSub ({Euqal.left=current} op='=' right=AddAndSub)*;

AddAndSub returns Exp:
    left=MulAndDiv ({AddAndSub.left=current} op=('+'|'-') right=MulAndDiv)*;

MulAndDiv returns Exp:
    left=Dot ({MulAndDiv.left=current} op=('*'|'/') right=Dot)*;

terminal BEGIN: 'synthetic:BEGIN';  // increase indentation
terminal END: 'synthetic:END';      // decrease indentation

terminal ID:
    '^'?('a'..'z'|'A'..'Z'|'_')('a'..'z'|'A'..'Z'|'_'|'0'..'9')*;
 
terminal INT returns ecore::EInt:
    ('0'..'9')+;
 
terminal STRING:
    '"' ( '\\'('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') | !('\\'|'"') )* '"' |
    "'" ( '\\'('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') | !('\\'|"'") )* "'";
 
terminal ML_COMMENT:
    "'''" -> "'''";
 
terminal SL_COMMENT:
    '#' !('\n'|'\r')* ('\r'? '\n')?;
 
terminal WS:
    (' ')+;
/*    
terminal TAB:
    ('\t')+;
    */
terminal NEXT_LINE:
    ('\n'|'\r')+;

terminal ANY_OTHER:
    .;

这是我的例子:

a = b
if a.b:
    el.click()
elif c:
    '''les '''
    e.go()
elif m:
    if lake:
        pik()
else:
    e1.click()
主要问题是if-else子句,该子句需要检测缩进。 我需要下一行规则来确保一个stmt只有一行。 在简单的语法中,开始和结束规则可以起作用。但当我添加下一行规则时,它失败了