Compiler/syntax analyzer: Difference between revisions
m
J: simplify (tok_name and tok_type were basically redundant in this implementation)
(J: bugfix: no right associative operators (previous implementation: all binary operators were right associative)) |
m (J: simplify (tok_name and tok_type were basically redundant in this implementation)) |
||
Line 3,313:
Keyword_while Semicolon Comma Keyword_putc RightParen
Identifier String Integer
}}-.LF
Line 3,325 ⟶ 3,319:
tkPrec=: 13 13 13 12 12 10 10 10 10 9 9 5 4 (tkref i.tokenize'*/%+-<<=>>==!=&&||')} tkV<._1
tkPrec=: 14 (1 0+tkref i.tokenize'-!')} tkPrec
NB. proofread |:(<"1 tkV,.tkPrec)
ndRef=: tkref
Line 3,334 ⟶ 3,328:
}}-.LF
NB. proofread |:ndRef,:ndDisp
gettoken=: {{
Line 3,354 ⟶ 3,337:
ind=. tknames i.<tok_name
tok_text=: ind{::tkref
tok_valence=: ind{::tkV
tok_precedence=: ind{::tkPrec
node_display=: ndDisp{::~tktyp i.<tok_type▼
ndx=:ndx+1
}}
parse=: {{
Line 3,369 ⟶ 3,348:
gettok''
t=.a:
whilst.-.(a:-:t)+.
t=. Sequence make_node t stmt''
end.
Line 3,376 ⟶ 3,355:
stmt=:{{)v
t=. a:
select.
case.
s=. stmt e=. paren_expr gettok''
if.
do. S=. stmt gettok''
else. S=. a: end.
t=. If make_node e If make_node s S
case.
e=. paren_expr gettok''
t=. Putc make_node e a:
Putc expect
case.
'Print' expect
while.do.
if.
do. gettok e=. Prts make_node (String make_leaf tok_value) a:
else. e=. Prti make_node (expr 0) a: end.
t=. Sequence make_node t e
if.
do.Comma expect
else.break.end.
end.
'Print' expect
'Print' expect
case.
case.
gettok v=. Identifier make_leaf tok_value
Assign expect
t=. Assign make_node v e=. expr 0
Assign expect
case.
t=. While make_node e s=. stmt e=. paren_expr gettok''
case.
'
while.-.(<
t=. Sequence make_node t stmt''
end.
'
case.
case.do. error 'Expecting start of statement, found %s'sprintf<tok_text
end.
Line 3,421 ⟶ 3,400:
paren_expr=: {{
'paren_expr' expect
t=. expr 0
'paren_expr' expect
t
}}
Line 3,429 ⟶ 3,408:
not_prec=: tkPrec{~tknames i.<Op_not
expr=: {{
select.
case.
case.
e=. expr not_prec
case.
e=. Negate make_node (expr not_prec) a:
case.
e=. Not make_node (expr not_prec) a:
case.
gettok e=. Identifier make_leaf tok_value
case.
gettok e=. Integer make_leaf tok_value
case.do. error 'Expecting a primary, found %s'sprintf<tok_text
end.
while.(2=tok_valence)*
q=. 1+tok_precedence [ op=. node_display NB. no right associative operators
gettok''
e=. op make_node e node
end.
e
Line 3,452 ⟶ 3,432:
expect=: {{
if.y-:
error '%s: Expecting "%s", found "%s"'sprintf x;(tkref{::~
}}
Line 3,481 ⟶ 3,461:
case.do.assert.0
end.
}}</lang>
Some quirks worth noting:
|