Даже IE 11 дает мне «загогулины» для этого. Переход на static
дал мне желаемое поведение.
Chrome фактически предлагает его как приемлемое свойство в раскрывающемся списке
ANTLR более или менее не имеет отношения к вашей проблеме.
Класс в PHP - это, по сути, отображение строк в атрибуты. Каждый атрибут может быть публичным, частным, защищенным. Каждый атрибут также содержит значение, которое может быть статической переменной или методом. Методы - это функции, которые (в PHP) принимают неявный параметр $ this. Таким образом, вы можете думать о классе как о необычном объекте массива в PHP.
Когда вы создаете объект, вы даете ему указатель на ваш объект класса PHP. Когда вы вызываете метод этого объекта, вы ищите метод через объект класса, который вы получаете через этот указатель.
Надеюсь, это поможет.
Я обнаружил, что лучший метод в компиляторе сверху вниз, лучший метод - обрабатывать классы в целом так же, как функции, в том смысле, что они являются просто узлами без необходимости оценивать аргументы перед спуском в дерево.
Различия заключаются в исполнителе, который должен создать область выполнения, в которой можно инкапсулировать методы и переменные, составляющие узел класса.
Я бы предложил использовать JavaCC (или вилку FreeCC) для синтаксического анализа и построения вашего AST. JavaCC генерирует синтаксический анализатор, который не имеет зависимостей во время выполнения. Трудно написать парсер меньшего размера / более быстрый, чем код, который генерирует JavaCC.
Возможно, вам понадобятся какие-нибудь структуры для интерпретации, которые немного более удалены от исходной грамматики? Я мало что знаю о PHP, но похоже, что вы действительно спрашиваете, как структурировать модель программы таким образом, чтобы это было удобно для интерпретации. Я бы посчитал AST, сгенерированный через ANTLR, слишком близким к источнику для того, что вы хотите.
Взгляните на абстрактную грамматику phc , это делает именно это. (Между прочим, похоже, что использование внешнего интерфейса phc может быть лучше, чем изобретать колесо.)
Class_def ::= Class_mod CLASS_NAME extends:CLASS_NAME? implements:INTERFACE_NAME* Member* ;
Class_mod ::= "abstract"? "final"? ;
Interface_def ::= INTERFACE_NAME extends:INTERFACE_NAME* Member* ;
Member ::= Method | Attribute ;
Method ::= Signature Statement*? ;
Signature ::= Method_mod is_ref:"&"? METHOD_NAME Formal_parameter* ;
Method_mod ::= "public"? "protected"? "private"? "static"? "abstract"? "final"? ;
Formal_parameter ::= Type is_ref:"&"? var:Name_with_default ;
Formal_parameter ::= Type is_ref:"&"? var:Name_with_default ;
Type ::= CLASS_NAME? ;
Name_with_default ::= VARIABLE_NAME Expr? ;
Attribute ::= Attr_mod vars:Name_with_default* ;
Attr_mod ::= "public"? "protected"? "private"? "static"? "const"? ;