1

Я пишу компилятор для javascript как язык для удовольствия. иначе я узнаю о колесе, поэтому я делаю это для себя и пытаюсь все выяснить, но теперь я застрял.Как преобразовать вызовы метода в постфиксную нотацию?

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

Например: 2+3*a(3,5)+b(3,5) превращается в 2 3 <G> 3 5 a() * + <G> 3 5 b() +

(<G> охранник маркер, который помещается в стек он будет хранить адрес возврата и т.д. () является вызов команды, которая вызывает функцию на вершине стека что выдает необходимое количество аргументов и возвращает результат по возврату.)

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

Это работает до сих пор.

Но если я добавлю возможность иметь функции-члены, то оператор .. Все становится сложнее. Например, я хочу преобразовать a.b.c(12)+d.e.f(34). Я не могу отметить функции c и f, поскольку функции a.b.c и d.e.f являются функциями. Если я начну свой парсер с таким выражением, результатом будет a b . <G> 12 c() . d e . <G> 34 f() . Что явно неправильно. Я хочу, чтобы это было <G> 12 a b . c .() <G> 34 d e . f.() Что кажется правильным. Но проклятие я могу усложнить ситуацию, если я добавлю некоторые круглые скобки: (a.b.c)(). Или я делаю функцию, которая возвращает функцию, которую я вызываю снова: f(a,b)(c,d).

Есть ли простой способ справиться с этими сложными ситуациями?

ответ

0

Проблема вашего подхода заключается в том, что вы обрабатываете объект и его элемент как два отдельных токена, разделенных .. Алгоритм классического шунтирования ничего не знает о ООП и полагается на один токен для вызова функции. Итак, первый способ решить вашу проблему - использовать один токен для вызова члена объекта - т. Е. Весь a.b.c должен быть единственным токеном.

Вы также можете обратиться к генераторам автоматического анализатора для другого решения вашей проблемы. Они позволяют определять полную грамматику вашего целевого языка (JavaScript) как набор формальных правил и автоматически генерировать парсер. Список популярных инструментов включает инструменты, которые генерируют парсер на разных языках программирования: ANTLR, Bison + Lex, Lemon + Ragel.


--artem

+1

'.' - это как минимум один токен оператора как' + '. – delnan

+0

@ delnan - это правильно. Мы должны рассматривать точку так же, как обычный оператор. – mahdix

0

(я видел этот вопрос все еще жив. Я нашел решение для этого сам.)

Сначала я угроза выражения (...) и [...] как один знак и расширить их (рекурсивно), когда это необходимо. Затем я обнаруживаю вызовы функций и индексы массивов. Если перед маркером в скобках нет оператора infix, это вызов функции или индекс массива, поэтому я вставляю туда специальную функцию вызова или оператор доступа. С этой модификацией он работает как шарм.

Смежные вопросы