![]() |
|
Navigation |
Synopsis Parse Func program from string or file and convert to an abstract syntax tree.
Description To simplify later processing, Func programs are converted to an abstract syntax tree.
Examples The concrete syntax for Func is described in Func/ConcreteSyntax and its
abstract syntax in Func/AbstractSyntax.
Rather than manually writing conversion rules from Func parse trees to Func abstract syntax trees
we use our secret weapon: Rascal:implode that performs the mapping for us.
As you see when you compare the concrete and abstract syntax, the ground work has already been done
by appropriately labelling concrete rules with constructor names of the abstract syntax.
Here is the code for the load funcion:
module demo::lang::Func::Load import demo::lang::Func::Func; import demo::lang::Func::AST; import demo::lang::Func::Parse; import ParseTree; public demo::lang::Func::AST::Prog implode(demo::lang::Func::Func::Prog p) = implode(#demo::lang::Func::AST::Prog, p); public demo::lang::Func::AST::Prog load(loc l) = implode(parse(l)); public demo::lang::Func::AST::Prog load(str s) = implode(parse(s));This looks simple but also slightly intimidating due to the many qualified names. The issue is that the names in the concrete and abstract syntax are (on purpose) overloaded. A name like Prog can be the one from the concrete syntax(i.e., demo::lang::Func::Func::Prog )
or the one from the abstract syntax (i.e., demo::lang::Func::AST::Prog ).
For instance, the local version of implode defined here get a concrete Prog as argument and returns an abstract one.
Both load function return an abstract Prog .
Let's try this on example F0 :
fact(n) = if n <= 1 then 1 else n * fact(n-1) end rascal>import demo::lang::Func::Load; ok rascal>import demo::lang::Func::programs::F0; ok rascal>load(F0); Prog: prog([func( "fact", ["n"], cond( leq( var("n")[ @location=|file://-|(13,1,<1,13>,<1,14>), @comments=() ], nat(1)[ @location=|file://-|(18,1,<1,18>,<1,19>), @comments=() ])[ @location=|file://-|(13,6,<1,13>,<1,19>), @comments=() ], nat(1)[ @location=|file://-|(38,1,<2,13>,<2,14>), @comments=() ], mul( var("n")[ @location=|file://-|(70,1,<4,13>,<4,14>), @comments=() ], call( "fact", [sub( var("n")[ @location=|file://-|(79,1,<4,22>,<4,23>), @comments=() ], nat(1)[ @location=|file://-|(81,1,<4,24>,<4,25>), @comments=() ])[ @location=|file://-|(79,3,<4,22>,<4,25>), @comments=() ]])[ @location=|file://-|(74,9,<4,17>,<4,26>), @comments=() ])[ @location=|file://-|(70,13,<4,13>,<4,26>), @comments=() ])[ @location=|file://-|(10,87,<1,10>,<5,13>), @comments=() ])[ @location=|file://-|(0,97,<1,0>,<5,13>), @comments=() ]])[ @location=|file://-|(0,97,<1,0>,<5,13>), @comments=() ]We get the original program and its abstract syntax tree of type Prog back.
In case of doubt, compare this with the result in Func/Parse where we did obtain a parse tree.
Next, we try the same from a file:
rascal>load(|std:///demo/lang/Func/programs/F0.func|);
Prog: prog([func(
"fact",
["n"],
cond(
leq(
var("n")[
@location=|std:///demo/lang/Func/programs/F0.func|(13,1,<1,13>,<1,14>),
@comments=()
],
nat(1)[
@location=|std:///demo/lang/Func/programs/F0.func|(18,1,<1,18>,<1,19>),
@comments=()
])[
@location=|std:///demo/lang/Func/programs/F0.func|(13,6,<1,13>,<1,19>),
@comments=()
],
nat(1)[
@location=|std:///demo/lang/Func/programs/F0.func|(38,1,<2,13>,<2,14>),
@comments=()
],
mul(
var("n")[
@location=|std:///demo/lang/Func/programs/F0.func|(70,1,<4,13>,<4,14>),
@comments=()
],
call(
"fact",
[sub(
var("n")[
@location=|std:///demo/lang/Func/programs/F0.func|(79,1,<4,22>,<4,23>),
@comments=()
],
nat(1)[
@location=|std:///demo/lang/Func/programs/F0.func|(81,1,<4,24>,<4,25>),
@comments=()
])[
@location=|std:///demo/lang/Func/programs/F0.func|(79,3,<4,22>,<4,25>),
@comments=()
]])[
@location=|std:///demo/lang/Func/programs/F0.func|(74,9,<4,17>,<4,26>),
@comments=()
])[
@location=|std:///demo/lang/Func/programs/F0.func|(70,13,<4,13>,<4,26>),
@comments=()
])[
@location=|std:///demo/lang/Func/programs/F0.func|(10,87,<1,10>,<5,13>),
@comments=()
])[
@location=|std:///demo/lang/Func/programs/F0.func|(0,97,<1,0>,<5,13>),
@comments=()
]])[
@location=|std:///demo/lang/Func/programs/F0.func|(0,97,<1,0>,<5,13>),
@comments=()
]
![]() |