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