Little PHP


Summary

This article demonstrates the definition of a simple PHP language in XMF.


Example

parserImport PHP;

context Root
@Operation count(elements)
elements.size()
end

context Root
@PHP
function printCollection($collection) {
for($i=0;$i<count($collection);$i++) {
echo $collection[$i]
}
}
end

A transcript of use:

[1] XMF> printCollection(Seq{1,2,3});
1
2
3
true
[1] XMF>

Language Definition

parserImport XOCL;
parserImport Parser::BNF;

import OCL;

context Root

@Class PHP

@Grammar

PHP ::= Function 'end'.

Function ::= 'function' name = Name '(' params = Params ')' body = Body {
Operation(name,params,NamedType(),body)
}.

Params ::= par = Para params = (',' Para)* {
Seq{par | params}
}.

Para ::= name = PHPName { Varp(name) }.

Body ::= '{' statements = Statement* '}' {
statements->iterate(s e = [| self |] | [| <e> ; <s> |])
}.

Statement ::= For | Echo.

For ::= 'for' '(' v = PHPName '=' e1 = Exp ';' condition = Exp ';' e2 = Exp ')' body = Body {
[|
let <v> = <e1>
in
@While <condition>
do
<body>;
<e2>
end
end
|]
}.

Echo ::= 'echo' exp = Exp {
[| format(stdout,"~S~%",Seq{<exp>}) |]
}.

PHPName ::= '$' name = Name.

// Expression definition

Exp ::= head = SimpleExp ( tail = ExpTail^(head) | { head } ).

SimpleExp ::= atom = Atom ( tail = SimpleExpTail^(atom) | { atom } ).

Atom ::= Var | Const | FunCall | ArrayRef.

SimpleExpTail(atom) ::= '++' {
[| <atom> := <atom> + 1 |]
}.

ExpTail(left) ::= '=' right = Exp { [| <left> = <right> |] }
| '<' right = Exp { [| <left> < <right> |] }.

FunCall ::= name = Name '(' args = Args ')' {
[|
let A = <SetExp("Seq",args)>
in
<Var(name)>.invoke(self,A)
end
|]
}.

Args ::= arg = Arg args = (',' Arg)* {
Seq{arg | args}
}.

Arg ::= name = PHPName {
Var(name)
}.

Var ::= name = PHPName {
Var(name)
}.

Const ::= int = Int { IntExp(int) } | str = Str { StrExp(str) }.

ArrayRef ::= var = Var '[' index = Exp ']' {
[| <var>.at(<index>) |]
}.

end

end