ANTLR — сохранить блок без изменений

Я новичок в ANTLR, и мне нужно изменить существующую и сложную грамматику.

Я хочу создать правило, чтобы сохранить блок без разбора с другими правилами.
Чтобы быть более понятным, мне нужно вставить код, написанный на c ++, в интерпретируемый код.


Изменить 11/02/2013

После многих тестов, вот моя грамматика, мой тест, результат, который я имею, и результат и хочу:

cppLiteral
: cppBegin cppInnerTerm cppEnd
;
cppBegin
:  '//$CPP_IN$'
;
cppEnd
: '//$CPP_OUT$'
;
cppInnerTerm
: ( ~('//$CPP_OUT$') )*
;
//$CPP_IN$
txt1 txt2
//$CPP_OUT$
cppLiteral ->
cppBegin = '//$CPP_IN$'
cppInnerTerm = 'txt1' 'txt2'
cppEnd = '//$CPP_OUT$'
cppLiteral ->
cppBegin = '//$CPP_IN$'
cppInnerTerm = 'txt1 txt2'
cppEnd = '//$CPP_OUT$'

(Извините, я не могу опубликовать изображение AST, потому что у меня нет 10 репутаций)

Три токена «cppBegin», «cppInnerTerm» и «cppEnd» могут быть в одном токене, например так:

cppLiteral
: '//$CPP_IN$'( ~('//$CPP_OUT$') )*'//$CPP_OUT$'
;

чтобы получить этот результат:

cppLiteral = '//$CPP_IN$\n txt1 txt2\n //$CPP_OUT$'

2

Решение

Я хочу создать правило, чтобы сохранить блок без разбора с другими правилами.

Разобрать его как многострочный комментарий, например /* foobar */, Ниже приведен небольшой пример использования ключевых слов, указанных в вашем вопросе.

Обратите внимание, что большая часть работы выполняется с помощью правил лексера (те, которые начинаются с заглавной буквы). Каждый раз, когда вы хотите иметь дело с блоками текста, особенно если вы хотите избежать других правил, как в этом случае, вы, вероятно, думаете о правилах лексера, а не правилах парсера.

CppBlock.g

grammar CppBlock;

document: CPP_LITERAL* EOF;fragment CPP_IN:'//$CPP_IN$';
fragment CPP_OUT:'//$CPP_OUT$';

CPP_LITERAL:  CPP_IN .* CPP_OUT
{
String t = getText();
t = t.substring(10, t.length() - 11); //10 = length of CPP_IN, 11 = length of CPP_OUT
setText(t);
}
;
WS: (' '|'\t'|'\f'|'\r'|'\n')+ {skip();};

Вот простой тестовый пример:

вход

//$CPP_IN$
static const int x = 0; //magic number
int *y; //$CPP_IN$ <-- junk comment
static void foo(); //forward decl...
//$CPP_OUT$

//$CPP_IN$
//Here is another block of CPP code...
const char* msg = ":D";
//The end.
//$CPP_OUT$

Выходные токены

[CPP_LITERAL :
static const int x = 0; //magic number
int *y; //$CPP_IN$ <-- junk comment
static void foo(); //forward decl...
]
[CPP_LITERAL :
//Here is another block of CPP code...
const char* msg = ":D";
//The end.
]

правило CPP_LITERAL сохраняет переводы строк в начале и конце ввода (после //$CPP_IN$ и раньше //$CPP_OUT$). Если вы не хотите, просто обновите действие, чтобы удалить их. В противном случае, я думаю, что эта грамматика делает то, что вы просите.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]