%%
%% Module with statements introduced in version 5
%%
%% @author Eric Bouwers
module languages/php/version5/Statements
imports
languages/php/common/Statements
languages/php/common/Expressions
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' -> VarModifier {cons("Public")}
'protected' -> VarModifier {cons("Protected")}
'private' -> VarModifier {cons("Private")}
'static' -> VarModifier {cons("Static")}
'final' -> VarModifier {cons("Final")}
'abstract' -> VarModifier {cons("Abstract")}
%% 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")}
sorts ClassConstantDecl ClassConstantDeclList
context-free syntax
%% There is also support for class constants
String "=" StaticScalar -> ClassConstantDecl {cons("ClassConstantDecl")}
'const' { ClassConstantDecl "," }+ ";" -> ClassConstantDeclList {cons("ClassConstantDeclList")}
ClassConstantDeclList -> ClassMember
ClassConstantDeclList -> InterfaceMember
sorts ClassMethodBody
context-free syntax
"{" TopStatement* "}" -> ClassMethodBody {cons("MethodBody")}
";" -> ClassMethodBody {cons("AbstractMethodBody")}
context-free syntax
%% Within classes, a function _can_ have modifiers. So we add a new FunctionDecl with modifers as ClassMember
VarModifiers 'function' String "("{Param ","}* ")" ClassMethodBody -> ClassMember {cons("FunctionDecl")}
VarModifiers 'function' "&" String "("{Param ","}* ")" ClassMethodBody -> ClassMember {cons("FunctionDeclRef")}
%% 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
VarModifiers? 'function' String "("{Param ","}* ")" ";" -> InterfaceMember {cons("InterfaceFunction")}
VarModifiers? '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}