> Статический анализатор в PHP настолько беспомощен, что не может понять, что в функции содержится вызов exit или бросает исключение и поэтому надо переложить написание лишних подсказок на плечи разработчика?Если ты вызываешь из кода php функцию на C, которая прерывает выполнение программы, то статистический анализатор должен каким-то магическим образом знать об этом свойстве внешней функции? Или может у него должна быть база данных всех внешних функций? Или может, всё же, проще добавить в синтаксис возможность задекларировать функцию как никогда не завершающуюся?
> А синтаксис перечисления нельзя было взять из Си или TypeScipt?
Нет. У них внутри определения типа могут быть объявлены методы. В том числе и внутри enum'а. php, как я понимаю, следит за тем, чтобы синтаксис был бы легко парсящимся, в смысле чтобы не требовалось бы расчехлять весь опыт pattern-matching'а, чтобы определить что следующий statement из себя представляет. Например, функция начинается с ключевого слова function. Класс со слова class. Вариант enum'а со слова case. Они не совсем успешны в следовании этой идеи, и функция реально может начинаться с public static, но тем не менее, такие штуки очень помогают держать синтаксис непротиворечивым и избегать сложностей распутывания контекстных зависимостей.
Люди недооценивают важность таких вещей, но чем проще синтаксис, тем проще с ним работать программно, тем проще создавать тулзы для работы с сорцами. Это, кстати, мысль, которую Вирт не смог донести до окружающих. Он делал свои паскали очень простыми с точки зрения парсинга, но в качестве аргументов к тому, почему это нужно, он невнятно мямлил про скорость компиляции и простоту освоения языка. Но сегодня, когда статистические анализаторы внешние, по отношению к компилятору, и тулзы для рефакторинга, и поддержка редактором синтаксиса языка и поддержка им задач редактирования кода стали обыденностью, простота синтаксиса для программного парсинга стала очень важна.
Чтобы парсить C и тем более C++, тебе потребуется llvm. В принципе, C можно парсить и при помощи sparse. Либо ты будешь парсить регекспами, смиряясь с тем, что ты твой парсер никогда не поймёт, что означает * в данном контексте: слово "указатель" в названии типа? разадресацию указателя? умножение? Да блин, ты замучаешься отличить декларацию переменной, от умножения: "a * b" может быть умножением a и b, а может быть объявлением переменной b с типом "указатель на тип a".