Контекстуальные условия при построении программы AST для C
Я пишу интерпретатор для C (подмножество) в Javascript (я хочу обеспечить визуализацию выполнения программы в браузере).
В качестве первого шага я хочу создать дерево AST для пользовательской программы. Для этого я использую Jison, который похож на комбинацию flex/bizon.
Сейчас я просто токенизирую программу и анализирую ее, чтобы проверить, соответствует ли она грамматике, данной стандартом (оставим в стороне проблему неоднозначности, введенную typedef).
Однако соответствие C грамматике не гарантирует, что программа имеет какой-либо смысл, например
int main() {
x = ("jklfds" || "jklgfd")(2, imlost);
}
соответствует грамматике, хотя x не объявлено, ("jklfds" || "jklgfd") не является указателем на функцию - типы не проверяются. Вообще есть много контекстных условий, которые не проверяются.
Мне интересно, сколько я должен проверять при построении дерева AST. Например, теоретически в этот момент было бы легко полностью рассчитать и проверить константное выражение. Однако большая часть другой проверки требует контекста. Можно ли, например, во время синтаксического анализа узнать, что некоторые идентификаторы ссылаются на структуры, объявленные ранее в программе?
Как насчет построения дерева AST как есть и проверки контекстных ограничений путем многократного анализа / преобразования AST, доказывающего, что все больше и больше условий являются правильными? Будет ли это легче / сложнее, чем проверка при разборе?
Я ищу самое дружелюбное решение, мне нет дела до его скорости.