2013-12-16 2 views
1

Я пытаюсь понять предикаты ANTLR. С этой целью У меня есть простой лексер и парсер, показанный ниже.ANTLR - использовать предикаты для ввода токена

То, что я хотел бы сделать, это использовать предикат для вставки слова «fubar» каждый раз, когда он видит «foo», за которым следует пробел, а затем «bar». Я хочу сделать это, сохраняя ту же основную структуру. Бонусные баллы за это в лексере. Дополнительные бонусные баллы, если я могу это сделать, не ссылаясь на основной язык вообще. Но при необходимости это C#.

Например, если входной является строка:

programmers use the words foo bar and bar foo class 

выход будет

programmers use the words foo fubar bar and bar foo class 

Лексер:

lexer grammar TextLexer; 

@members 
{ 
    protected const int EOF = Eof; 
    protected const int HIDDEN = Hidden; 
} 

FOO: 'foo'; 
BAR: 'bar'; 
TEXT: [a-z]+ ; 

WS 
    : ' ' -> channel(HIDDEN) 
    ; 

Parser:

parser grammar TextParser; 

options { tokenVocab=TextLexer; } 

@members 
{ 
    protected const int EOF = Eof; 
} 

file: words EOF; 

word:FOO 
|BAR 
|TEXT; 

words: word 
| word words 
; 

compileUnit 
    : EOF 
    ; 

ответ

1

Лексеру ANTLR3, возможно, в этом случае понадобился предикат, но лексер ANTLR4 намного «умнее». Вы можете сопоставить «foo bar» в одном правиле lexer и изменить его внутренний текст с помощью setText(...):

FOO_BAR 
: 'foo' [ \t]+ 'bar' {setText("fubar");} 
; 

TEXT 
: [a-z]+ 
; 

WS 
: ' ' -> channel(HIDDEN) 
;