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