我正在使用xtext 2.4。
我想要做的是类似SQL的语法。
令我困惑的是我不确定哪些东西应该被视为终端/数据类型/解析器规则。到目前为止,我与MyTerm
相关的语法是:
Model:
(terms += MyTerm ';')*
;
MyTerm:
constant=MyConstant | variable?='?'| collection_literal=CollectionLiteral
;
MyConstant
: string=STRING
| number=MyNumber
| date=MYDATE
| uuid=UUID
| boolean=MYBOOLEAN
| hex=BLOB
;
MyNumber:
int=SIGNINT | float=SIGNFLOAT
;
SIGNINT returns ecore::EInt:
'-'? INT
;
SIGNFLOAT returns ecore::EFloat:
'-'? INT '.' INT;
;
CollectionLiteral:
=> MapLiteral | SetLiteral | ListLiteral
;
MapLiteral:
'{' {MapLiteral} (entries+=MapEntry (',' entries+=MapEntry)* )? '}'
;
MapEntry:
key=MyTerm ':' value=MyTerm
;
SetLiteral:
'{' {SetLiteral} (values+=MyTerm (',' values+=MyTerm)* )+ '}'
;
ListLiteral:
'[' {ListLiteral} ( values+=MyTerm (',' values+=MyTerm)* )? ']'
;
terminal MYDATE:
'0'..'9' '0'..'9' '0'..'9' '0'..'9' '-'
'0'..'9' '0'..'9' '-'
'0'..'9' '0'..'9'
;
terminal HEX:
'a'..'h'|'A'..'H'|'0'..'9'
;
terminal UUID:
HEX HEX HEX HEX HEX HEX HEX HEX '-'
HEX HEX HEX HEX '-'
HEX HEX HEX HEX '-'
HEX HEX HEX HEX '-'
HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX
;
terminal BLOB:
'0' ('x'|'X') HEX+
;
terminal MYBOOLEAN returns ecore::EBoolean:
'true' | 'false' | 'TRUE' | 'FALSE'
;
几个问题:
如何用符号定义整数?如果我定义另一个终端规则terminal SIGNINT: '-'? '0'..'9'+;
,antlr会抱怨INT无法访问。因此,我将其定义为数据类型规则SIGNINT: '-'? INT;
这是正确的方法吗?
如何用符号定义浮点数?我做了与使用符号SIGNFLOAT: '-'? INT '.' INT;
定义整数完全相同的做法,不确定这是否正确。
如何定义日期规则?我想使用解析器规则在字段中存储年/月/日信息,但将其定义为MyDate: year=INT '-' month=INT '-' date=INT;
antlr会抱怨Decision can match input such as "RULE_INT '-' RULE_INT '-' RULE_INT" using multiple alternatives: 2, 3
As a result, alternative(s) 3 were disabled for that input
我还有一些其他规则,如
以下
RelationCompare:
name=ID compare=COMPARE term=MyTerm
;
但a=4
不是有效RelationCompare
,因为a
和4
将被视为HEX
。我找到了这个,因为如果我将关系改为j=44
那么它就可以了。在这个post中,它表示终端规则定义的预告片将影响后面定义的那些。但是,如果我在语法中重新定义terminal ID
,无论是在terminal HEX
之前还是在The following token definitions can never be matched because prior tokens match the same input: RULE_HEX,RULE_MYBOOLEAN
之后,antlr都会归结为k=0x00b
。此问题也发生在k=0xaab
中。 k=0x00b
有效,但{{1}}不是。
有什么建议吗?
答案 0 :(得分:3)
如何定义带符号的整数?
'-'
和INT
,并使用解析器规则而不是词法分析器规则。如何定义带符号的浮动?
'-'
和FLOAT
,并使用解析器规则而不是词法分析器规则。如何定义日期规则?
我不知道最后一个问题的答案,因为这是在Xtext而不是ANTLR。
答案 1 :(得分:3)
后来我找到了我想要做的原始antlr语法,因此我只是将antlr语法翻译成xtext语法。以下是我定义这些基本类型的方法:
terminal fragment A: 'a'|'A';
...
terminal fragment Z: 'z'|'Z';
terminal fragment DIGIT: '0'..'9';
terminal fragment LETTER: ('a'..'z'|'A'..'Z');
terminal fragment HEX: ('a'..'f'|'A'..'F'|'0'..'9');
terminal fragment EXPONENT: E ('+'|'-')? DIGIT+;
terminal INTEGER returns ecore::EInt: '-'? DIGIT+;
terminal FLOAT returns ecore::EFloat: INTEGER EXPONENT | INTEGER '.' DIGIT* EXPONENT?;
terminal BOOLEAN: T R U E | F A L S E;
原始语法中的日期规则被视为字符串。
关于规则名称(规则:Antlr Grammar => xtext语法)
terminal
前缀fragment
ID => terminal fragment
ID 在antlr中,参数列表定义如下:
functionArgs
: '(' ')'
| '(' t1=term ( ',' tn=term )* ')'
;
相应的xtext语法是:
FunctionArgs
: '(' ')'
| '(' ts+=Term (',' ts+=Term )* ')'
;
对于那些带有由[
]
properties[PropertyDefinitions props]
: property[props] (K_AND property[props])*
;
大部分时间他们都可以移到左侧
Properties
: props+=Property (K_AND props+=Property)*
;
现在它按预期工作了。