1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
lex-comment. =
extends $(Lexer)
declare lex
declare rule
level = 0
other: .
lex()
term: $'[*][)]'
if $(not $(eq $(level), 0))
level = $(sub $(level), 1)
lex()
next: $'[(][*]'
level = $(add $(level), 1)
lex()
eof: $"\'"
eprintln(Unterminated comment)
lexer1. =
extends $(Lexer)
declare lex
declare rule
other: .
eprintln(Illegal character: $0)
lex()
white: $'[[:space:]]+'
lex()
comment: $'[(][*]'
lex-comment.lex-channel($(channel))
lex()
op: $'[-+*/()]'
switch $0
case +
Token.unit(plus)
case -
Token.unit(minus)
case *
Token.unit(mul)
case /
Token.unit(div)
case $'('
Token.unit(lparen)
case $')'
Token.unit(rparen)
number: $'[[:digit:]]+'
Token.pair(exp, $(int $0))
eof: $"\'"
Token.unit(eof)
parser1. =
extends $(Parser)
declare rule
#
# Use the main lexer
#
lexer = $(lexer1)
#
# Precedences, in ascending order
#
left(plus minus)
left(mul div)
right(uminus)
#
# A program
#
start(prog)
prog: exp eof
value $1
#
# Simple arithmetic expressions
#
exp: minus exp :prec: uminus
neg($2)
exp: exp plus exp
add($1, $3)
exp: exp minus exp
sub($1, $3)
exp: exp mul exp
mul($1, $3)
exp: exp div exp
div($1, $3)
exp: lparen exp rparen
value $2
println(Test1: should print 48)
println(Parsed $(parser1.parse-file prog, Test.input1))
lexer2. =
extends $(lexer1)
declare rule
lsl: $"<<"
Token.unit(lsl)
lsr: $">>>"
Token.unit(lsr)
asr: $">>"
Token.unit(asr)
parser2. =
extends $(parser1)
declare rule
left(plus, lsl lsr asr)
lexer = $(lexer2)
exp: exp lsl exp
lsl($1, $3)
exp: exp lsr exp
lsr($1, $3)
exp: exp asr exp
asr($1, $3)
println(Test2: should print 256)
println(Parsed $(parser2.parse-file prog, Test.input2))
|