![]() |
|
Navigation |
Synopsis Defines a concrete syntax for Exp with layout.
Description In Rascal, the major difference between lexical syntax and non-lexical syntax is that:
Exp in Exp/Concrete/NoLayout with a layout definition:
module demo::lang::Exp::Concrete::WithLayout::Syntax layout Whitespace = [\t-\n\r\ ]*;Using the layout definition (![]() Whitespace non-terminal is used in between every symbol of the syntax productions in the current module.
And now we can use spaces in our definition of the eval function as well: module demo::lang::Exp::Concrete::WithLayout::Eval import demo::lang::Exp::Concrete::WithLayout::Syntax; import String; import ParseTree; public int eval(str txt) = eval(parse(#Exp, txt)); public int eval((Exp)`<IntegerLiteral l>`) = toInt("<l>"); public int eval((Exp)`<Exp e1> * <Exp e2>`) = eval(e1) * eval(e2); public int eval((Exp)`<Exp e1> + <Exp e2>`) = eval(e1) + eval(e2); public int eval((Exp)`( <Exp e> )`) = eval(e); public value main(list[value] args) { return eval("2+3"); }Note that Rascal:PatternMatching will ignore all trees in layout positions, such that the parse tree of "1 + \n1" will match against <Exp e1> + <Exp e2> . The same goes for equality on parse trees.
For the above example Rascal will insert the Whitespace non-terminal that is defined at ![]() Exp . Moreover, for the start production (See Exp/Concrete/NoLayout) Whitespace will be added before and after the Exp .
Examples The effect of the layout definition is that before parser generation the following grammar is derived for
Exp :
syntax Exp = IntegerLiteral | bracket "(" Whitespace Exp Whitespace ")" > left Exp Whitespace "*" Whitespace Exp > left Exp Whitespace "+" Whitespace Exp ; syntax start[Exp] = Whitespace Exp top Whitespace;To put this all to the test: rascal>import demo::lang::Exp::Concrete::WithLayout::Syntax; ok rascal>import demo::lang::Exp::Concrete::WithLayout::Eval; ok rascal>eval("2 + 3"); int: 5 rascal>eval("2 + 3*4"); int: 14 rascal>eval("( 2+3 )* 4"); int: 20
Pitfalls
![]() |