Xtext-带有合成标记的类似Python的DSL
我正在做我的dsl项目。但当我想让它像python(支持空白的语言)一样工作时,它会给我错误“输入不匹配”\t“需要规则\u BEGIN”。终端规则开始意味着什么?为什么下面的例子不起作用? 这是我的语法: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
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只有一行。
在简单的语法中,开始和结束规则可以起作用。但当我添加下一行规则时,它失败了