Как реализовать переводчик компьютерного языка с использованием двух отдельных грамматик

Я хочу создать переводчик компьютерного языка между двумя языками LANG1 и LANG2. Более конкретно, я хочу перевести код, написанный на LANG1, в исходный код на LANG2.

У меня есть грамматика BNF для LANG1 и LANG2.

LANG1 — это небольшой DSL, который я написал сам, и, по сути, «более простая» версия LANG2.

Я хочу иметь возможность генерировать операторы в LANG2 из входных операторов, написанных в LANG1.

Я нахожусь в процессе компиляции для LANG1, но я не знаю, что делать дальше (чтобы преобразовать операторы LANG1 в операторы LANG2).

Я понимаю следующие шаги:

1. BNF for my DSL (LANG1)                                  DONE
2. Reverse engineered the BNF for LANG2                    DONE
3. Learning how to generate a compiler for LANG1           TODO
4. Translate LANG1 statements to LANG2 statements          ???

Какие шаги предпринимаются для генерации операторов LANG2 из операторов LANG1?

Моя кодовая база находится на C ++, поэтому я могу использовать Parser, сгенерированный либо на C, либо на C ++.

PS: я буду использовать ANTLR3 для генерации компилятора для LANG1

3

Решение

В самом общем случае вам нужно перевести каждый возможный раздел грамматики из LANG1 в нечто подходящее для LANG2, или вам нужно разобраться в простейших возможных примитивах обоих языков, таких как ассемблер или комбинаторы. Это немного отнимает много времени и не очень весело.

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

РЕДАКТИРОВАТЬ: Так как я только что перечитал ваш вопрос, понял, что вы хотите переводить только одним способом, вам нужно только беспокоиться о том, чтобы форма дерева подходила для LANG1 и просто иметь функцию перевода для LANG2. Но я надеюсь, что мой пример полезен в любом случае.

Пример построения дерева:

Вот две разные грамматики ANTLR, которые производят один и тот же чрезвычайно простой AST:

Грамматика 1

Первый — это стандартный способ выражения сложения:

grammar simpleAdd;

options {output=AST;}

tokens {
PLUS = '+';
}

expression : addition EOF!;
addition   : NUMBER (PLUS NUMBER)+ -> ^(PLUS NUMBER*);

NUMBER     :'0'..'9'+;
WHITESPACE : ( '\t' | ' ' | '\r' | '\n')+    { $channel = HIDDEN; } ;

Это примет два или более целых числа и создаст дерево с узлом PLUS и всеми числами в списке, которые будут добавлены вместе. Например.,

1 + 1 + 2 + 3 + 5

Грамматика 2

Вторая грамматика принимает менее элегантную форму:

grammar horribleAdd;

options {output=AST;}

tokens {
PLUS = '+';
PLUS_FUNC = 'plus';
COMMA = ',';
LEFT_PARENS ='(';
RIGHT_PARENS=')';
}

expression : addition EOF!;
addition   : PLUS_FUNC LEFT_PARENS NUMBER (COMMA NUMBER)+ RIGHT_PARENS -> ^(PLUS NUMBER*);

NUMBER     :'0'..'9'+;
WHITESPACE : ( '\t' | ' ' | '\r' | '\n')+    { $channel = HIDDEN; } ;

В этой грамматике ожидаются числа, присвоенные функции (да, я знаю, что функции на самом деле не работают так, я просто стараюсь сделать пример как можно более ясным). Например.,

plus(1, 1, 2, 3, 5)

Он создает точно такое же дерево, что и первая грамматика (узел PLUS с числами, как у детей).

Теперь вам не нужно беспокоиться о том, с какого языка пришли ваши инструкции, вы можете выводить их в любой форме. Все, что вам нужно сделать, это написать функцию, которая может конвертировать этот AST обратно на язык по вашему выбору.

4

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

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

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector