Как преобразовать вызовы метода в постфиксную нотацию? - PullRequest
1 голос
/ 11 декабря 2010

Я пишу компилятор для языка, похожего на 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).

Есть ли простой способ справиться с такими хитрыми ситуациями?

Ответы [ 2 ]

0 голосов
/ 05 марта 2011

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

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

0 голосов
/ 14 января 2011

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

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

--artem

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...