Анализ многопроходного класса Flex / Bison

#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, у нас было несколько проходов (в зависимости от сложности языка, конечно):

  1. Соберите все классы
  2. Построение иерархии суперклассов
  3. Соберите все методы и поля
  4. Сбор переменных внутри методов и т.д.

Есть причины, по которым нам пришлось разделить весь процесс на 4 прохода:

  1. Вы не можете создать иерархию суперклассов, если еще не все классы были обработаны (привело к 2. pass)
  2. Вы не можете проверить унаследованные методы (возвращаемое значение, параметры и т.д.), Когда суперкласс неизвестен (привело к 2. pass)
  3. Вы не можете обрабатывать переменные, если еще не все поля были собраны (привело к 4. pass)

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

Когда я смотрю на это сейчас, должно было быть возможно объединить проход 2 и 3, поскольку все данные должны быть доступны для прохода 3.

Мы реализовали это, просто пройдясь по AST и снабдив его необходимыми таблицами символов.

Комментарии:

1. Вы можете взглянуть на проект: svn.c0demonkey.com /… (проходы выполняются в semant.c — хотя довольно сложный код 🙂