Можно ли определить тип объекта в режиме онлайн за один проход, включая макросы? - PullRequest
2 голосов
/ 17 июня 2019

У меня очень простой синтаксический анализатор, который предоставляет небольшой раздел языка Си; он смотрит на правильно сформированную единицу перевода и, с помощью одного прохода и онлайн, определяет, какие глобальные символы и типы (функция, структура, объединение, переменная), если кто-то не пытается обмануть его. Однако у меня возникают проблемы с определением, является ли это struct или функцией в этом примере,

#define CAT_(x, y) x ## y
#define CAT(x, y) CAT_(x, y)
#define F_(thing) CAT(foo, thing)

static struct F_(widget) { int i; }

F_(widget);

static struct F_(widget) a(void) { int i;
    return i = 42, F_(widget).i = i, F_(widget); }

int main(void) {
    a();
    return 0;
}

Предполагается, что скобка является функцией, и анализирует это следующим образом,

[ID<stati>, ID<struc>, ID<F_>, LPAR<(>, ID<widge>, RPAR<)>, LBRA<{>, RBRA<}>].
[ID<F_>, LPAR<(>, ID<widge>, RPAR<)>, SEMI<;>].
[ID<stati>, ID<struc>, ID<F_>, LPAR<(>, ID<widge>, RPAR<)>, ID<a>, LPAR<(>, ID<void>, RPAR<)>, LBRA<{>, RBRA<}>].
[ID<int>, ID<main>, LPAR<(>, ID<void>, RPAR<)>, LBRA<{>, RBRA<}>].

На самом деле, то, что она считает функцией вверху, на самом деле является объявлением struct, а две верхние должны быть объединены. Какой самый простой способ узнать, что это?

  • Двухпроходный, эмулирующий то, что действительно происходит при замене макроса; Я должен был бы построить подмножество препроцессора C;
  • как хакерский лексер , кроме макросов;
  • возврат с точкой с запятой в конце; это кажется трудным;
  • каким-то образом распознает разницу в начале (вероятно, от меня потребуется добавить struct в мою таблицу символов).

1 Ответ

1 голос
/ 17 июня 2019

Как уже упоминалось в комментариях, если вы хотите иметь возможность обрабатывать макросы препроцессора, вам необходимо реализовать (или заимствовать) препроцессор.

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

(Это зависит от того, как вы определяете «проход», я полагаю, но в моем использованииоднопроходный парсер читает входные данные только один раз, не создавая и не перечитывая временный файл. И это, безусловно, выполнимо.)

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