2013-08-06 73 views
2

我正在使用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因爲a4將作爲治療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=0x00bk=0xaab有效,但k=0x00b不是。

有什麼建議嗎?

回答

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; 

將原始語法中的Date規則視爲字符串。

關於規則名(規則:ANTLR的語法=> XTEXT語法)

  • 解析器規則:開始用小寫=>用大寫(每個將是一個Java類)開始
  • 終端規則的規則:開始用大寫字母=>使用所有大寫與terminal前綴
  • 片段終端規則:fragment ID =>terminal fragment ID

在一TLR的參數的列表被這樣定義:

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)* 
; 

現在它按預期工作。

+1

嗨,如果你使用終端INTEGER返回ecore :: EInt:' - '? DIGIT +;',你是如何處理負數計算的?因爲它會將'1-2'視爲'TOKEN'1和TOKEN'-2'。 –

3

如何定義一個帶符號的整數?

  • 把它當作兩個分開的令牌'-'INT,和使用解析器規則,而不是一個詞法規則。

如何定義帶符號的浮點數?

  • 把它當作兩個分開的令牌'-'FLOAT,和使用解析器規則,而不是一個詞法規則。

如何定義日期規則?

  • 將它視爲五個單獨的標記,並使用解析器規則而不是詞法分析器規則。

我不知道最後一個問題的答案,因爲這是在Xtext中,而不是ANTLR。

+0

感謝您的部分解決方案! –