| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 | 
							- // a simple recognizer, produces no useful value
 
- ometa L {
 
-   number   = digit+,
 
-   addExpr  = addExpr '+' mulExpr
 
-            | addExpr '-' mulExpr
 
-            | mulExpr,
 
-   mulExpr  = mulExpr '*' primExpr
 
-            | mulExpr '/' primExpr
 
-            | primExpr,
 
-   primExpr = '(' expr ')'
 
-            | number,
 
-   expr     = addExpr
 
- }
 
- L.matchAll('6*(4+3)', 'expr')
 
- // a recognizer that also interprets
 
- ometa Calc {
 
-   digit    = ^digit:d                 -> d.digitValue(),
 
-   number   = number:n digit:d         -> (n * 10 + d)
 
-            | digit,
 
-   addExpr  = addExpr:x '+' mulExpr:y  -> (x + y)
 
-            | addExpr:x '-' mulExpr:y  -> (x - y)
 
-            | mulExpr,
 
-   mulExpr  = mulExpr:x '*' primExpr:y -> (x * y)
 
-            | mulExpr:x '/' primExpr:y -> (x / y)
 
-            | primExpr,
 
-   primExpr = '(' expr:x ')'           -> x
 
-            | number,
 
-   expr     = addExpr
 
- }
 
- Calc.matchAll('6**(4+3)', 'expr')
 
- // parser and simple interpreter combo
 
- ometa CalcParser {
 
-   digit    = ^digit:d                 -> d.digitValue(),
 
-   number   = number:n digit:d         -> (n * 10 + d)
 
-            | digit,
 
-   addExpr  = addExpr:x '+' mulExpr:y  -> ['add', x, y]
 
-            | addExpr:x '-' mulExpr:y  -> ['sub', x, y]
 
-            | mulExpr,
 
-   mulExpr  = mulExpr:x '*' primExpr:y -> ['mul', x, y]
 
-            | mulExpr:x '/' primExpr:y -> ['div', x, y]
 
-            | primExpr,
 
-   primExpr = '(' expr:x ')'           -> x
 
-            | number:n                 -> ['num', n],
 
-   expr     = addExpr
 
- }
 
- tree = CalcParser.matchAll('6*(4+3)', 'expr') 
 
- ometa CalcInterpreter {
 
-   interp = ['num' anything:x]        -> x
 
-          | ['add' interp:x interp:y] -> (x + y)
 
-          | ['sub' interp:x interp:y] -> (x - y)
 
-          | ['mul' interp:x interp:y] -> (x * y)
 
-          | ['div' interp:x interp:y] -> (x / y)
 
- }
 
- CalcInterpreter.match(tree, 'interp')
 
- // we can write a "compiler" instead
 
- ometa CalcCompiler {
 
-   comp    = ['num' anything:x]    -> x.toString()
 
-           | ['add' comp:x comp:y] -> ('(' + x + '+' + y + ')')
 
-           | ['sub' comp:x comp:y] -> ('(' + x + '-' + y + ')')
 
-           | ['mul' comp:x comp:y] -> ('(' + x + '*' + y + ')')
 
-           | ['div' comp:x comp:y] -> ('(' + x + '/' + y + ')')
 
- }
 
- code = CalcCompiler.match(tree, 'comp')
 
- eval(code)
 
-  
 
- // spice things up with ML-like syntax
 
- ometa CalcCompiler {
 
-   comp ['num' anything:x]    -> x.toString(),
 
-   comp ['add' comp:x comp:y] -> ('(' + x + '+' + y + ')'),
 
-   comp ['sub' comp:x comp:y] -> ('(' + x + '-' + y + ')'),
 
-   comp ['mul' comp:x comp:y] -> ('(' + x + '*' + y + ')'),
 
-   comp ['div' comp:x comp:y] -> ('(' + x + '/' + y + ')')
 
- }
 
- code = CalcCompiler.match(tree, 'comp')
 
- eval(code)
 
-  
 
- // a neat trick: dispatch on node tags using higher-order rule "apply"
 
- ometa CalcCompiler {
 
-   comp [anything:t apply(t):ans] -> ans,
 
-   num  anything:x                -> x.toString(),
 
-   add  comp:x comp:y             -> ('(' + x + '+' + y + ')'),
 
-   sub  comp:x comp:y             -> ('(' + x + '-' + y + ')'),
 
-   mul  comp:x comp:y             -> ('(' + x + '*' + y + ')'),
 
-   div  comp:x comp:y             -> ('(' + x + '/' + y + ')')
 
- }
 
- code = CalcCompiler.match(tree, 'comp')
 
- eval(code)
 
 
  |