2012-04-25 95 views
1

我試圖從我的輸入程序中將某些令牌的文本替換爲特定的格式化文本。我使用C#作爲輸出語言。輸入替換ANTLR中的令牌文本

例子:

time#1m2s 

我該輸入法語法:

fragment 
DIGIT : '0'..'9' 
     ; 

CTE_DURATION 
    : ('T'|'t'|'TIME'|'time') '#' '-'? (DIGIT ('d'|'h'|'m'|'s'|'ms') '_'?)+ 
    ; 

輸出標記文本,我想從輸入例如獲得:

0.0:1:2.0 

這表示:0天,0小時,1分鐘,2秒和0毫秒。

有什麼建議嗎?先謝謝你。

+0

我不明白你的問題,你可以更具體嗎?你的問題是你希望你的語法只接受這種格式的輸入:0.0:1:2.0? – sm13294 2012-04-25 10:51:32

+0

我的lex語法接受「time#1m2s」並創建一個CTE_DURATION標記,其文本是「time#1m2s」。我想要我的lex規則來更改CTE_DURATION標記文本(在我的示例中,我想將標記文本更改爲「0.0:1:2.0」)。 – 2012-04-25 11:14:33

回答

1

這裏有一個辦法做到這一點(這是在Java中,但不應該是很難移植到C#):

grammar Test; 

parse 
: CTE_DURATION EOF 
; 

CTE_DURATION 
: ('T' 'IME'? | 't' 'ime'?) '#' minus='-'? 
    (d=DIGITS 'd')? (h=DIGITS 'h')? (m=DIGITS 'm')? (s=DIGITS 's')? (ms=DIGITS 'ms')? 
    { 
    int days = $d == null ? 0 : Integer.valueOf($d.text); 
    int hours = $h == null ? 0 : Integer.valueOf($h.text); 
    int minutes = $m == null ? 0 : Integer.valueOf($m.text); 
    int seconds = $s == null ? 0 : Integer.valueOf($s.text); 
    int mseconds = $ms == null ? 0 : Integer.valueOf($ms.text); 
    setText(($minus == null ? "" : "-") + days + "." + hours + ":" + minutes + ":" + seconds + "." + mseconds); 
    } 
; 

fragment DIGITS : '0'..'9'+; 

解析輸入time#1m2s結果在下面的分析樹:

enter image description here

請注意,該語法現在也接受time#(導致其生成0.0:0:0.0),但如果輸入無效,則可以輕鬆地從詞法分析規則中產生一個例外。

+0

謝謝你的回答。這解決了我的問題。我不得不在目標C#中使用「$ text」而不是「setText()」。我怎樣才能將減號(' - ')加到我的輸出中(減號是可選的)? – 2012-04-25 13:05:17

+0

@JoseEsperon,看到我編輯的答案爲可選減號。 – 2012-04-25 13:17:16

+0

我在寫評論之前就試過了。這總是以' - '產生輸出。編輯:我有可選的減去添加新的lex規則的解決方案:「片段MINUS \t:' - ';」。我在CTE_DURATION規則中使用了MINUS。謝謝。 – 2012-04-25 15:19:03