Ответ 1
В существующем вопросе о переносе пространств имен на псевдо-именный код Я уже представил инструмент преобразования я написаны как часть более крупного проекта. С тех пор я не поддерживал этот проект, но, насколько я помню, замена пространства имен действительно сработала. (Я могу переопределить этот проект с помощью соответствующего парсера в какой-то момент. Работа с простыми токенами оказалась довольно утомительной задачей.)
Вы найдете мою реализацию пространства имен → разрешение псевдопространства в namespace.php. Я основывал реализацию на правилах разрешения пространства имен, которые, вероятно, также помогут вам.
Чтобы сделать это менее вопиющим ответом readmycodez, вот основные шаги, которые выполняет код:
- Получить идентификатор, который будет разрешен, и убедиться, что он не является объявлением класса, интерфейса, функции или константы (они разрешены в registerClass и registerOther, просто добавив текущее пространство имен, где ns-разделители заменены символами подчеркивания).
- Определите тип идентификатора: класс, функция или константа. (Поскольку они нуждаются в разной разрешающей способности.)
- Убедитесь, что мы не разрешаем классы
self
иparent
, а также константыtrue
,false
иnull
. - Разрешить псевдонимы (
use
list):- Если идентификатор квалифицирован, получите часть перед первым разделителем пространства имен и проверьте, существует ли псевдоним с этим именем. Если это так, замените первую часть на псевдонимы (теперь идентификатор будет полностью квалифицирован). В противном случае добавьте текущее пространство имен.
- Если идентификатор неквалифицирован и тип идентификатора
class
, проверьте, является ли идентификатор псевдонимом, и если он есть, замените его на класс с псевдонимом.
- Если идентификатор полностью квалифицирован, снимите главный разделитель пространства имен и замените все остальные разделители пространства имен на символы подчеркивания и завершите этот алгоритм.
- В противном случае:
- Если мы находимся в глобальном пространстве имен, дальнейшее разрешение не требуется, поэтому завершите этот алгоритм.
- Если тип идентификатора
class
добавляет текущее пространство имен, замените все разделители NS на символы подчеркивания и завершите этот алгоритм. - В противном случае:
- Если функция/константа определена глобально, оставите идентификатор как есть и закончите этот алгоритм. (Это предполагает, что глобальные функции не переопределены в пространстве имен! В моем коде я не делаю этого предположения, поэтому я вставляю динамический код разрешения.)
- В противном случае добавьте текущее пространство имен и замените все разделители пространств имен символами подчеркивания. (Похоже, что у меня есть ошибка в моем коде здесь: я не делаю этого, даже если установлен флаг
assumeGlobal
. Вместо этого я всегда вставляю динамический код отправки.)
Дополнительное примечание: не забывайте, что можно также написать namespace\some\ns
. Я разрешаю эти конструкции в функции NS
(которая также отвечает за поиск деклараций пространства имен).