我正在使用xtext 2.4。 我想要做的是類似於SQL的語法。 讓我困惑的是我不確定哪些事情應該被視爲終端/數據類型/解析器規則。到目前爲止,我與MyTerm
語法是:xtext中的終端/數據類型/解析器規則
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
之前還是之後,antlr都會提出The following token definitions can never be matched because prior tokens match the same input: RULE_HEX,RULE_MYBOOLEAN
。此問題也發生在k=0x00b
。 k=0xaab
有效,但k=0x00b
不是。
有什麼建議嗎?
嗨,如果你使用終端INTEGER返回ecore :: EInt:' - '? DIGIT +;',你是如何處理負數計算的?因爲它會將'1-2'視爲'TOKEN'1和TOKEN'-2'。 –