2012-04-25 64 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