#c #class #bison #reentrancy
#c #класс #bison #повторный вход
Вопрос:
Я пишу компилятор для игрушечного OO-языка. Я пишу его на C, используя Flex и Bison.
Рассмотрим следующий синтаксис:
class MyClass {
int m_n;
void MyFunc(int b) {
m_n = 5;
m_p = b;
}
int m_p;
}
Мой текущий код будет жаловаться на то, что в myFunc m_p еще не объявлен (и на то есть веские причины). Итак, я пришел к выводу, что мне нужна техника многоходового синтаксического анализа — что-то вроде:
1-й проход — объявления переменных процесса
2-й проход — определения функций процесса
Во-первых, это лучший способ решить проблему? Существуют ли другие методы, на которые мне следует обратить внимание? Во-вторых, если это благоприятное решение, могу ли я реализовать его с помощью повторно вводимого лексера / синтаксического анализатора?
Спасибо
Ответ №1:
Недавно я написал компилятор для языка OO, у нас было несколько проходов (в зависимости от сложности языка, конечно):
- Соберите все классы
- Построение иерархии суперклассов
- Соберите все методы и поля
- Сбор переменных внутри методов и т.д.
Есть причины, по которым нам пришлось разделить весь процесс на 4 прохода:
- Вы не можете создать иерархию суперклассов, если еще не все классы были обработаны (привело к 2. pass)
- Вы не можете проверить унаследованные методы (возвращаемое значение, параметры и т.д.), Когда суперкласс неизвестен (привело к 2. pass)
- Вы не можете обрабатывать переменные, если еще не все поля были собраны (привело к 4. pass)
Вы можете не использовать второй проход, если, конечно, у вас нет наследования в вашем языке.
Когда я смотрю на это сейчас, должно было быть возможно объединить проход 2 и 3, поскольку все данные должны быть доступны для прохода 3.
Мы реализовали это, просто пройдясь по AST и снабдив его необходимыми таблицами символов.
Комментарии:
1. Вы можете взглянуть на проект: svn.c0demonkey.com /… (проходы выполняются в semant.c — хотя довольно сложный код 🙂