%%
%% Module with statements introduced in version 5
%%
%% @author Eric Bouwers
module languages/php/version5/Statements
imports
languages/php/common/Statements
exports
context-free syntax
%% Varion 5 allow references in foreach vars
"&" CVar -> ForEachVar {cons("Ref")}
sorts ImplementsClause
context-free syntax
%% The real class declaration
ClassType String ExtendsClause? ImplementsClause? "{" ClassMember* "}" -> ClassDecl {cons("Class")}
%% Classes can implement multiple interfaces
'implements' { Name "," }+ -> ImplementsClause {cons("Implements")}
sorts ClassType VarModifiers VarModifier Public
context-free syntax
%% Classes in version 5 are more involved
%% Two more types of classes besides the normal type
'abstract' 'class' -> ClassType {cons("AbstractClass")}
'final' 'class' -> ClassType {cons("FinalClass")}
%% Class variables can have modifiers
%% Public is special, we need it at interfaces
'public' -> Public {cons("Public")}
Public -> VarModifier
'protected' -> VarModifier {cons("Protected")}
'private' -> VarModifier {cons("Private")}
'static' -> VarModifier {cons("Static")}
'final' -> VarModifier {cons("Final")}
%% Notice that 'public protected' is parsed, but raises a fatal error afterwards
%% This also holds for 'final abstract'
VarModifier+ -> VarModifiers {cons("Modifiers")}
context-free syntax
%% Version 5 also supports modified instance variables
VarModifiers {InstanceVariable ","}+ ";" -> ClassMember {cons("InstanceVariable")}
context-free syntax
%% There is also support for class constants
'const' String "=" StaticScalar ";" -> ClassMember {cons("ClassConstantDecl")}
context-free syntax
%% Within classes, a function _can_ have modifiers. So we add a new FunctionDecl with modifers as ClassMember
VarModifiers 'function' String "("{Param ","}* ")" "{" TopStatement* "}" -> ClassMember {cons("FunctionDecl")}
VarModifiers 'function' "&" String "("{Param ","}* ")" "{" TopStatement* "}" -> ClassMember {cons("FunctionDeclRef")}
'abstract' VarModifier* 'function' String "("{Param ","}* ")" ";" -> ClassMember {cons("AbstractFunction")}
'abstract' VarModifier* 'function' "&" String "("{Param ","}* ")" ";" -> ClassMember {cons("AbstractFunctionRef")}
%% Version 5 supports interfaces, try catch clauses and some type hinting
sorts InterFaceExtendsClause InterfaceMember InterfaceDecl Name
context-free syntax
%% Some support for interfaces
'interface' String InterFaceExtendsClause? "{" InterfaceMember* "}" -> InterfaceDecl {cons("InterfaceDecl")}
'extends' { Name "," }+ -> InterFaceExtendsClause {cons("InterfaceExtends")}
%% function should be public, so this is the only one parsed
Public? 'function' String "("{Param ","}* ")" ";" -> InterfaceMember {cons("InterfaceFunction")}
Public? 'function' "&" String "("{Param ","}* ")" ";" -> InterfaceMember {cons("InterfaceFunctionRef")}
InterfaceDecl -> TopStatement
sorts Body Catch Try
context-free syntax
%% try - catch support
"{" TopStatement* "}" -> Body {cons("Body")}
'catch' "(" String TVariable ")" Body -> Catch {cons("Catch")}
'try' Body Catch* -> Try {cons("Try")}
Try -> Statement
context-free syntax
%% Throw is also a statement.
'throw' Expr ";" -> Statement {cons("Throw")}
'throw' -> FunctionName {reject}
sorts TypeHint
context-free syntax
%% Version 5 supports type hinting for functions. This includes a String before a function
%% Note that the constant parameter cannot be type-hinted
TypeHint TVariable -> Param{cons("Param")}
TypeHint "&" TVariable -> Param{cons("ParamRef")}
TypeHint TVariable "=" StaticScalar -> Param{cons("ParamDefault")}
%% Minor problem. One can typehint or have a constant parameter.
%% So 'const' should not be considered a typehint
String -> TypeHint
'const' -> TypeHint {reject}