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

+0

Моя лексическая грамматика принимает «время # 1m2s» и создает токен CTE_DURATION, текст которого «время # 1m2s». Я хочу, чтобы мое правило lex меняло токен CTE_DURATION (в моем примере я хочу изменить токены на «0.0: 1: 2.0»). –

ответ

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), но вы можете легко создать исключение из правила lexer в случае, если такой ввод недействителен.

+0

Благодарим вас за ответ. Это решает мою проблему. Я должен был использовать «$ text» вместо «setText()» в целевом C#. Как добавить символ минус ('-') к моему выводу (минус необязательно)? –

+0

@JoseEsperon, см. Мой отредактированный ответ для необязательного минуса. –

+0

Я пробовал этот путь, прежде чем писать свой комментарий. Это всегда производит вывод с помощью «-». EDIT: у меня есть решение для необязательного минуса, добавляющего новое правило lex: «фрагмент MINUS \t: '-';". Я использовал MINUS внутри правила CTE_DURATION. Спасибо. –