Data update
This commit is contained in:
parent
5150844a7d
commit
4bb20c9b71
7735 changed files with 38060 additions and 199180 deletions
|
|
@ -269,6 +269,7 @@ Tree *stmt() {
|
|||
|
||||
if (tok.tok != tk_Comma)
|
||||
break;
|
||||
/* I think there's should be "tok = gettok();" in this line - hinjolicious */
|
||||
}
|
||||
expect("Print", tk_Rparen);
|
||||
expect("Print", tk_Semi);
|
||||
|
|
|
|||
|
|
@ -1,606 +0,0 @@
|
|||
>>SOURCE FORMAT IS FREE
|
||||
identification division.
|
||||
*> this code is dedicated to the public domain
|
||||
*> (GnuCOBOL) 2.3-dev.0
|
||||
*> for extra credit, generate this program directly from the EBNF
|
||||
program-id. parser.
|
||||
environment division.
|
||||
configuration section.
|
||||
repository. function all intrinsic.
|
||||
input-output section.
|
||||
file-control.
|
||||
select input-file assign using input-name
|
||||
status is input-status
|
||||
organization is line sequential.
|
||||
data division.
|
||||
file section.
|
||||
fd input-file global.
|
||||
01 input-record global.
|
||||
03 input-line pic zzzz9.
|
||||
03 input-column pic zzzzzz9.
|
||||
03 filler pic x(3).
|
||||
03 input-token pic x(16).
|
||||
03 input-value pic x(48).
|
||||
|
||||
working-storage section.
|
||||
01 program-name pic x(32) value spaces global.
|
||||
01 input-name pic x(32) value spaces global.
|
||||
01 input-status pic xx global.
|
||||
|
||||
01 line-no pic 999 value 0.
|
||||
01 col-no pic 99 value 0.
|
||||
|
||||
01 error-record global.
|
||||
03 error-line-no pic zzzz9.
|
||||
03 error-col-no pic zzzzzz9.
|
||||
03 filler pic x value space.
|
||||
03 error-message pic x(64) value spaces.
|
||||
|
||||
01 token global.
|
||||
03 token-type pic x(16).
|
||||
03 token-line pic 999.
|
||||
03 token-column pic 99.
|
||||
03 token-value pic x(48).
|
||||
|
||||
01 parse-stack global.
|
||||
03 p pic 999 value 0.
|
||||
03 p-lim pic 999 value 200.
|
||||
03 p-zero pic 999 value 0.
|
||||
03 parse-entry occurs 200.
|
||||
05 parse-name pic x(24).
|
||||
05 parse-token pic x(16).
|
||||
05 parse-left pic 999.
|
||||
05 parse-right pic 999.
|
||||
05 parse-work pic 999.
|
||||
05 parse-work1 pic 999.
|
||||
|
||||
01 abstract-syntax-tree global.
|
||||
03 t pic 999 value 0.
|
||||
03 t1 pic 999.
|
||||
03 t-lim pic 999 value 998.
|
||||
03 filler occurs 998.
|
||||
05 leaf.
|
||||
07 leaf-type pic x(14).
|
||||
07 leaf-value pic x(48).
|
||||
05 node redefines leaf.
|
||||
07 node-type pic x(14).
|
||||
07 node-left pic 999.
|
||||
07 node-right pic 999.
|
||||
|
||||
01 indent pic x(200) value all '| ' global.
|
||||
|
||||
procedure division chaining program-name.
|
||||
start-parser.
|
||||
if program-name <> spaces
|
||||
string program-name delimited by space '.lex' into input-name
|
||||
open input input-file
|
||||
if input-status <> '00'
|
||||
string 'in parser ' trim(input-name) ' open status ' input-status
|
||||
into error-message
|
||||
call 'reporterror'
|
||||
end-if
|
||||
end-if
|
||||
call 'gettoken'
|
||||
call 'stmt_list'
|
||||
if input-name <> spaces
|
||||
close input-file
|
||||
end-if
|
||||
|
||||
call 'printast' using t
|
||||
|
||||
>>d perform dump-ast
|
||||
|
||||
stop run
|
||||
.
|
||||
dump-ast.
|
||||
display '==========' upon syserr
|
||||
display 'ast:' upon syserr
|
||||
display 't=' t upon syserr
|
||||
perform varying t1 from 1 by 1 until t1 > t
|
||||
if leaf-type(t1) = 'Identifier' or 'Integer' or 'String'
|
||||
display t1 space trim(leaf-type(t1)) space trim(leaf-value(t1)) upon syserr
|
||||
else
|
||||
display t1 space node-left(t1) space node-right(t1) space trim(node-type(t1))
|
||||
upon syserr
|
||||
end-if
|
||||
end-perform
|
||||
.
|
||||
|
||||
identification division.
|
||||
program-id. stmt_list common recursive.
|
||||
data division.
|
||||
procedure division.
|
||||
start-stmt_list.
|
||||
call 'push' using module-id
|
||||
move p-zero to parse-left(p)
|
||||
perform forever
|
||||
call 'stmt'
|
||||
move return-code to parse-right(p)
|
||||
call 'makenode' using 'Sequence' parse-left(p) parse-right(p)
|
||||
move return-code to parse-left(p)
|
||||
if parse-right(p) = 0
|
||||
or token-type = 'End_of_input'
|
||||
exit perform
|
||||
end-if
|
||||
end-perform
|
||||
call 'pop'
|
||||
.
|
||||
end program stmt_list.
|
||||
|
||||
identification division.
|
||||
program-id. stmt common recursive.
|
||||
procedure division.
|
||||
start-stmt.
|
||||
call 'push' using module-id
|
||||
move p-zero to parse-left(p)
|
||||
evaluate token-type
|
||||
when 'Semicolon'
|
||||
call 'gettoken'
|
||||
when 'Identifier'
|
||||
*>Identifier '=' expr ';'
|
||||
call 'makeleaf' using 'Identifier' token-value
|
||||
move return-code to parse-left(p)
|
||||
call 'gettoken'
|
||||
call 'expect' using 'Op_assign'
|
||||
call 'expr'
|
||||
move return-code to parse-right(p)
|
||||
call 'expect' using 'Semicolon'
|
||||
call 'makenode' using 'Assign' parse-left(p) parse-right(p)
|
||||
move return-code to parse-left(p)
|
||||
when 'Keyword_while'
|
||||
*>'while' paren_expr '{' stmt '}'
|
||||
call 'gettoken'
|
||||
call 'paren_expr'
|
||||
move return-code to parse-work(p)
|
||||
call 'stmt'
|
||||
move return-code to parse-right(p)
|
||||
call 'makenode' using 'While' parse-work(p) parse-right(p)
|
||||
move return-code to parse-left(p)
|
||||
when 'Keyword_if'
|
||||
*>'if' paren_expr stmt ['else' stmt]
|
||||
call 'gettoken'
|
||||
call 'paren_expr'
|
||||
move return-code to parse-left(p)
|
||||
call 'stmt'
|
||||
move return-code to parse-work(p)
|
||||
move p-zero to parse-work1(p)
|
||||
if token-type = 'Keyword_else'
|
||||
call 'gettoken'
|
||||
call 'stmt'
|
||||
move return-code to parse-work1(p)
|
||||
end-if
|
||||
call 'makenode' using 'If' parse-work(p) parse-work1(p)
|
||||
move return-code to parse-right(p)
|
||||
call 'makenode' using 'If' parse-left(p) parse-right(p)
|
||||
move return-code to parse-left(p)
|
||||
when 'Keyword_print'
|
||||
*>'print' '(' prt_list ')' ';'
|
||||
call 'gettoken'
|
||||
call 'expect' using 'LeftParen'
|
||||
call 'prt_list'
|
||||
move return-code to parse-left(p)
|
||||
call 'expect' using 'RightParen'
|
||||
call 'expect' using 'Semicolon'
|
||||
when 'Keyword_putc'
|
||||
*>'putc' paren_expr ';'
|
||||
call 'gettoken'
|
||||
call 'paren_expr'
|
||||
move return-code to parse-left(p)
|
||||
call 'makenode' using 'Prtc' parse-left(p) p-zero
|
||||
move return-code to parse-left(p)
|
||||
call 'expect' using 'Semicolon'
|
||||
when 'LeftBrace'
|
||||
*>'{' stmt '}'
|
||||
call 'gettoken'
|
||||
move p-zero to parse-left(p)
|
||||
perform until token-type = 'RightBrace' or 'End_of_input'
|
||||
call 'stmt'
|
||||
move return-code to parse-right(p)
|
||||
call 'makenode' using 'Sequence' parse-left(p) parse-right(p)
|
||||
move return-code to parse-left(p)
|
||||
end-perform
|
||||
if token-type <> 'End_of_input'
|
||||
call 'gettoken'
|
||||
end-if
|
||||
when other
|
||||
move 0 to parse-left(p)
|
||||
end-evaluate
|
||||
move parse-left(p) to return-code
|
||||
call 'pop'
|
||||
.
|
||||
end program stmt.
|
||||
|
||||
identification division.
|
||||
program-id. paren_expr common recursive.
|
||||
procedure division.
|
||||
start-paren_expr.
|
||||
*>'(' expr ')' ;
|
||||
call 'push' using module-id
|
||||
call 'expect' using 'LeftParen'
|
||||
call 'expr'
|
||||
call 'expect' using 'RightParen'
|
||||
call 'pop'
|
||||
.
|
||||
end program paren_expr.
|
||||
|
||||
identification division.
|
||||
program-id. prt_list common.
|
||||
procedure division.
|
||||
start-prt_list.
|
||||
*>(string | expr) {',' (String | expr)} ;
|
||||
call 'push' using module-id
|
||||
move p-zero to parse-work(p)
|
||||
perform prt_entry
|
||||
perform until token-type <> 'Comma'
|
||||
call 'gettoken'
|
||||
perform prt_entry
|
||||
end-perform
|
||||
call 'pop'
|
||||
exit program
|
||||
.
|
||||
prt_entry.
|
||||
if token-type = 'String'
|
||||
call 'makeleaf' using token-type token-value
|
||||
move return-code to parse-left(p)
|
||||
call 'makenode' using 'Prts' parse-left(p) p-zero
|
||||
call 'gettoken'
|
||||
else
|
||||
call 'expr'
|
||||
move return-code to parse-left(p)
|
||||
call 'makenode' using 'Prti' parse-left(p) p-zero
|
||||
end-if
|
||||
move return-code to parse-right(p)
|
||||
call 'makenode' using 'Sequence' parse-work(p) parse-right(p)
|
||||
move return-code to parse-work(p)
|
||||
.
|
||||
end program prt_list.
|
||||
|
||||
identification division.
|
||||
program-id. expr common recursive.
|
||||
procedure division.
|
||||
start-expr.
|
||||
*>and_expr {'||' and_expr} ;
|
||||
call 'push' using module-id
|
||||
call 'and_expr'
|
||||
move return-code to parse-left(p)
|
||||
perform forever
|
||||
if token-type <> 'Op_or'
|
||||
exit perform
|
||||
end-if
|
||||
call 'gettoken'
|
||||
call 'and_expr'
|
||||
move return-code to parse-right(p)
|
||||
call 'makenode' using 'Or' parse-left(p) parse-right(p)
|
||||
move return-code to parse-left(p)
|
||||
end-perform
|
||||
move parse-left(p) to return-code
|
||||
call 'pop'
|
||||
.
|
||||
end program expr.
|
||||
|
||||
identification division.
|
||||
program-id. and_expr common recursive.
|
||||
procedure division.
|
||||
start-and_expr.
|
||||
*>equality_expr {'&&' equality_expr} ;
|
||||
call 'push' using module-id
|
||||
call 'equality_expr'
|
||||
move return-code to parse-left(p)
|
||||
perform forever
|
||||
if token-type <> 'Op_and'
|
||||
exit perform
|
||||
end-if
|
||||
call 'gettoken'
|
||||
call 'equality_expr'
|
||||
move return-code to parse-right(p)
|
||||
call 'makenode' using 'And' parse-left(p) parse-right(p)
|
||||
move return-code to parse-left(p)
|
||||
end-perform
|
||||
call 'pop'
|
||||
.
|
||||
end program and_expr.
|
||||
|
||||
identification division.
|
||||
program-id. equality_expr common recursive.
|
||||
procedure division.
|
||||
start-equality_expr.
|
||||
*>relational_expr [('==' | '!=') relational_expr] ;
|
||||
call 'push' using module-id
|
||||
call 'relational_expr'
|
||||
move return-code to parse-left(p)
|
||||
evaluate token-type
|
||||
when 'Op_equal'
|
||||
move 'Equal' to parse-token(p)
|
||||
when 'Op_notequal'
|
||||
move 'NotEqual' to parse-token(p)
|
||||
end-evaluate
|
||||
if parse-token(p) <> spaces
|
||||
call 'gettoken'
|
||||
call 'relational_expr'
|
||||
move return-code to parse-right(p)
|
||||
call 'makenode' using parse-token(p) parse-left(p) parse-right(p)
|
||||
move return-code to parse-left(p)
|
||||
end-if
|
||||
call 'pop'
|
||||
.
|
||||
end program equality_expr.
|
||||
|
||||
identification division.
|
||||
program-id. relational_expr common recursive.
|
||||
procedure division.
|
||||
start-relational_expr.
|
||||
*>addition_expr [('<' | '<=' | '>' | '>=') addition_expr] ;
|
||||
call 'push' using module-id
|
||||
call 'addition_expr'
|
||||
move return-code to parse-left(p)
|
||||
evaluate token-type
|
||||
when 'Op_less'
|
||||
move 'Less' to parse-token(p)
|
||||
when 'Op_lessequal'
|
||||
move 'LessEqual' to parse-token(p)
|
||||
when 'Op_greater'
|
||||
move 'Greater' to parse-token(p)
|
||||
when 'Op_greaterequal'
|
||||
move 'GreaterEqual' to parse-token(p)
|
||||
end-evaluate
|
||||
if parse-token(p) <> spaces
|
||||
call 'gettoken'
|
||||
call 'addition_expr'
|
||||
move return-code to parse-right(p)
|
||||
call 'makenode' using parse-token(p) parse-left(p) parse-right(p)
|
||||
move return-code to parse-left(p)
|
||||
end-if
|
||||
call 'pop'
|
||||
.
|
||||
end program relational_expr.
|
||||
|
||||
identification division.
|
||||
program-id. addition_expr common recursive.
|
||||
procedure division.
|
||||
start-addition_expr.
|
||||
*>multiplication_expr {('+' | '-') multiplication_expr} ;
|
||||
call 'push' using module-id
|
||||
call 'multiplication_expr'
|
||||
move return-code to parse-left(p)
|
||||
perform forever
|
||||
evaluate token-type
|
||||
when 'Op_add'
|
||||
move 'Add' to parse-token(p)
|
||||
when 'Op_subtract'
|
||||
move 'Subtract' to parse-token(p)
|
||||
when other
|
||||
exit perform
|
||||
end-evaluate
|
||||
call 'gettoken'
|
||||
call 'multiplication_expr'
|
||||
move return-code to parse-right(p)
|
||||
call 'makenode' using parse-token(p) parse-left(p) parse-right(p)
|
||||
move return-code to parse-left(p)
|
||||
end-perform
|
||||
call 'pop'
|
||||
.
|
||||
end program addition_expr.
|
||||
|
||||
identification division.
|
||||
program-id. multiplication_expr common recursive.
|
||||
procedure division.
|
||||
start-multiplication_expr.
|
||||
*>primary {('*' | '/' | '%') primary } ;
|
||||
call 'push' using module-id
|
||||
call 'primary'
|
||||
move return-code to parse-left(p)
|
||||
perform forever
|
||||
evaluate token-type
|
||||
when 'Op_multiply'
|
||||
move 'Multiply' to parse-token(p)
|
||||
when 'Op_divide'
|
||||
move 'Divide' to parse-token(p)
|
||||
when 'Op_mod'
|
||||
move 'Mod' to parse-token(p)
|
||||
when other
|
||||
exit perform
|
||||
end-evaluate
|
||||
call 'gettoken'
|
||||
call 'primary'
|
||||
move return-code to parse-right(p)
|
||||
call 'makenode' using parse-token(p) parse-left(p) parse-right(p)
|
||||
move return-code to parse-left(p)
|
||||
end-perform
|
||||
call 'pop'
|
||||
.
|
||||
end program multiplication_expr.
|
||||
|
||||
identification division.
|
||||
program-id. primary common recursive.
|
||||
procedure division.
|
||||
start-primary.
|
||||
*> Identifier
|
||||
*>| Integer
|
||||
*>| 'LeftParen' expr 'RightParen'
|
||||
*>| ('+' | '-' | '!') primary
|
||||
*>;
|
||||
call 'push' using module-id
|
||||
evaluate token-type
|
||||
when 'Identifier'
|
||||
call 'makeleaf' using 'Identifier' token-value
|
||||
call 'gettoken'
|
||||
when 'Integer'
|
||||
call 'makeleaf' using 'Integer' token-value
|
||||
call 'gettoken'
|
||||
when 'LeftParen'
|
||||
call 'gettoken'
|
||||
call 'expr'
|
||||
call 'expect' using 'RightParen'
|
||||
move t to return-code
|
||||
when 'Op_add'
|
||||
call 'gettoken'
|
||||
call 'primary'
|
||||
when 'Op_subtract'
|
||||
call 'gettoken'
|
||||
call 'primary'
|
||||
move return-code to parse-left(p)
|
||||
call 'makenode' using 'Negate' parse-left(p) p-zero
|
||||
when 'Op_not'
|
||||
call 'gettoken'
|
||||
call 'primary'
|
||||
move return-code to parse-left(p)
|
||||
call 'makenode' using 'Not' parse-left(p) p-zero
|
||||
when other
|
||||
move 0 to return-code
|
||||
end-evaluate
|
||||
call 'pop'
|
||||
.
|
||||
end program primary.
|
||||
|
||||
program-id. reporterror common.
|
||||
procedure division.
|
||||
start-reporterror.
|
||||
report-error.
|
||||
move token-line to error-line-no
|
||||
move token-column to error-col-no
|
||||
display error-record upon syserr
|
||||
stop run with error status -1
|
||||
.
|
||||
end program reporterror.
|
||||
|
||||
identification division.
|
||||
program-id. gettoken common.
|
||||
procedure division.
|
||||
start-gettoken.
|
||||
if program-name = spaces
|
||||
move '00' to input-status
|
||||
accept input-record on exception move '10' to input-status end-accept
|
||||
else
|
||||
read input-file
|
||||
end-if
|
||||
|
||||
evaluate input-status
|
||||
when '00'
|
||||
move input-token to token-type
|
||||
move input-value to token-value
|
||||
move numval(input-line) to token-line
|
||||
move numval(input-column) to token-column
|
||||
>>d display indent(1:min(4 * p,length(indent))) 'new token: ' token-type upon syserr
|
||||
when '10'
|
||||
string 'in parser ' trim(input-name) ' unexpected end of input'
|
||||
into error-message
|
||||
call 'reporterror'
|
||||
when other
|
||||
string 'in parser ' trim(input-name) ' unexpected input-status ' input-status
|
||||
into error-message
|
||||
call 'reporterror'
|
||||
end-evaluate
|
||||
.
|
||||
end program gettoken.
|
||||
|
||||
identification division.
|
||||
program-id. expect common.
|
||||
data division.
|
||||
linkage section.
|
||||
01 what any length.
|
||||
procedure division using what.
|
||||
start-expect.
|
||||
if token-type <> what
|
||||
string 'in parser expected ' what ' found ' token-type into error-message
|
||||
call 'reporterror'
|
||||
end-if
|
||||
>>d display indent(1:min(4 * p,length(indent))) 'match: ' token-type upon syserr
|
||||
call 'gettoken'
|
||||
.
|
||||
end program expect.
|
||||
|
||||
identification division.
|
||||
program-id. push common.
|
||||
data division.
|
||||
linkage section.
|
||||
01 what any length.
|
||||
procedure division using what.
|
||||
start-push.
|
||||
>>d display indent(1:min(4 * p,length(indent))) 'push ' what upon syserr
|
||||
if p >= p-lim
|
||||
move 'in parser stack overflow' to error-message
|
||||
call 'reporterror'
|
||||
end-if
|
||||
add 1 to p
|
||||
initialize parse-entry(p)
|
||||
move what to parse-name(p)
|
||||
.
|
||||
end program push.
|
||||
|
||||
identification division.
|
||||
program-id. pop common.
|
||||
procedure division.
|
||||
start-pop.
|
||||
if p < 1
|
||||
move 'in parser stack underflow' to error-message
|
||||
call 'reporterror'
|
||||
end-if
|
||||
>>d display indent(1:4 * p - 4) 'pop ' parse-name(p) upon syserr
|
||||
subtract 1 from p
|
||||
.
|
||||
end program pop.
|
||||
|
||||
identification division.
|
||||
program-id. makenode common.
|
||||
data division.
|
||||
linkage section.
|
||||
01 parm-type any length.
|
||||
01 parm-left pic 999.
|
||||
01 parm-right pic 999.
|
||||
procedure division using parm-type parm-left parm-right.
|
||||
start-makenode.
|
||||
if t >= t-lim
|
||||
string 'in parser makenode tree index t exceeds ' t-lim into error-message
|
||||
call 'reporterror'
|
||||
end-if
|
||||
add 1 to t
|
||||
move parm-type to node-type(t)
|
||||
move parm-left to node-left(t)
|
||||
move parm-right to node-right(t)
|
||||
move t to return-code
|
||||
.
|
||||
end program makenode.
|
||||
|
||||
identification division.
|
||||
program-id. makeleaf common.
|
||||
data division.
|
||||
linkage section.
|
||||
01 parm-type any length.
|
||||
01 parm-value pic x(48).
|
||||
procedure division using parm-type parm-value.
|
||||
start-makeleaf.
|
||||
if t >= t-lim
|
||||
string 'in parser makeleaf tree index t exceeds ' t-lim into error-message
|
||||
call 'reporterror'
|
||||
end-if
|
||||
add 1 to t
|
||||
move parm-type to leaf-type(t)
|
||||
move parm-value to leaf-value(t)
|
||||
move t to return-code
|
||||
.
|
||||
end program makeleaf.
|
||||
|
||||
identification division.
|
||||
program-id. printast recursive.
|
||||
data division.
|
||||
linkage section.
|
||||
01 n pic 999.
|
||||
procedure division using n.
|
||||
start-printast.
|
||||
if n = 0
|
||||
display ';'
|
||||
exit program
|
||||
end-if
|
||||
evaluate leaf-type(n)
|
||||
when 'Identifier'
|
||||
when 'Integer'
|
||||
when 'String'
|
||||
display leaf-type(n) trim(leaf-value(n))
|
||||
when other
|
||||
display node-type(n)
|
||||
call 'printast' using node-left(n)
|
||||
call 'printast' using node-right(n)
|
||||
end-evaluate
|
||||
.
|
||||
end program printast.
|
||||
end program parser.
|
||||
|
|
@ -1,154 +1,149 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- demo\rosetta\Compiler\parse.e
|
||||
-- =============================
|
||||
--
|
||||
-- The reusable part of parse.exw
|
||||
--</span>
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">include</span> <span style="color: #000000;">lex</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
|
||||
-- demo\rosetta\Compiler\parse.e
|
||||
-- The reusable part of parse.exw
|
||||
with javascript_semantics
|
||||
include lex.e
|
||||
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tok</span>
|
||||
sequence tok
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">errd</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">args</span><span style="color: #0000FF;">={})</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">tok_line</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tok_col</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tok</span>
|
||||
<span style="color: #000000;">error</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span><span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
procedure errd(sequence msg, sequence args={})
|
||||
{tok_line,tok_col} = tok
|
||||
error(msg,args)
|
||||
end procedure
|
||||
|
||||
<span style="color: #008080;">global</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">toks</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">next_tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
global sequence toks
|
||||
integer next_tok = 1
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">toks</span><span style="color: #0000FF;">[</span><span style="color: #000000;">next_tok</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">next_tok</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">tok</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
function get_tok()
|
||||
sequence tok = toks[next_tok]
|
||||
next_tok += 1
|
||||
return tok
|
||||
end function
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">tk</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">tk</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">s</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">errd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%s: Expecting '%s', found '%s'\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tkNames</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">tkNames</span><span style="color: #0000FF;">[</span><span style="color: #000000;">tk</span><span style="color: #0000FF;">]})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
procedure expect(string msg, integer s)
|
||||
integer tk = tok[3]
|
||||
if tk!=s then
|
||||
errd("%s: Expecting '%s', found '%s'\n", {msg, tkNames[s], tkNames[tk]})
|
||||
end if
|
||||
tok = get_tok()
|
||||
end procedure
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">node</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span>
|
||||
function expr(integer p)
|
||||
object x = NULL, node
|
||||
integer op = tok[3]
|
||||
|
||||
<span style="color: #008080;">switch</span> <span style="color: #000000;">op</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_LeftParen</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"expr"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tk_RightParen</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_sub</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_add</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">node</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">precedences</span><span style="color: #0000FF;">[</span><span style="color: #000000;">tk_neg</span><span style="color: #0000FF;">]);</span>
|
||||
<span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">op</span><span style="color: #0000FF;">==</span><span style="color: #000000;">tk_sub</span><span style="color: #0000FF;">?{</span><span style="color: #000000;">tk_neg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">}:</span><span style="color: #000000;">node</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_not</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_not</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">precedences</span><span style="color: #0000FF;">[</span><span style="color: #000000;">tk_not</span><span style="color: #0000FF;">]),</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_Identifier</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_Identifier</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]}</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_Integer</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_Integer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]}</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #008080;">default</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">errd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Expecting a primary, found: %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tkNames</span><span style="color: #0000FF;">[</span><span style="color: #000000;">op</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
|
||||
switch op do
|
||||
case tk_LeftParen:
|
||||
tok = get_tok()
|
||||
x = expr(0)
|
||||
expect("expr",tk_RightParen)
|
||||
case tk_sub:
|
||||
case tk_add:
|
||||
tok = get_tok()
|
||||
node = expr(precedences[tk_neg]);
|
||||
x = iff(op==tk_sub?{tk_neg, node, NULL}:node)
|
||||
case tk_not:
|
||||
tok = get_tok();
|
||||
x = {tk_not, expr(precedences[tk_not]), NULL}
|
||||
case tk_Identifier:
|
||||
x = {tk_Identifier, tok[4]}
|
||||
tok = get_tok();
|
||||
case tk_Integer:
|
||||
x = {tk_Integer, tok[4]}
|
||||
tok = get_tok();
|
||||
default:
|
||||
errd("Expecting a primary, found: %s\n", tkNames[op])
|
||||
end switch
|
||||
|
||||
<span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">narys</span><span style="color: #0000FF;">[</span><span style="color: #000000;">op</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">BINARY</span>
|
||||
<span style="color: #008080;">and</span> <span style="color: #000000;">precedences</span><span style="color: #0000FF;">[</span><span style="color: #000000;">op</span><span style="color: #0000FF;">]>=</span><span style="color: #000000;">p</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">precedences</span><span style="color: #0000FF;">[</span><span style="color: #000000;">op</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)}</span>
|
||||
<span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">;</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
op = tok[3]
|
||||
while narys[op]=BINARY
|
||||
and precedences[op]>=p do
|
||||
tok = get_tok()
|
||||
x = {op, x, expr(precedences[op]+1)}
|
||||
op = tok[3]
|
||||
end while
|
||||
return x;
|
||||
end function
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">paren_expr</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tk_LeftParen</span><span style="color: #0000FF;">);</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tk_RightParen</span><span style="color: #0000FF;">);</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">t</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
function paren_expr(string msg)
|
||||
expect(msg, tk_LeftParen);
|
||||
object t = expr(0)
|
||||
expect(msg, tk_RightParen);
|
||||
return t
|
||||
end function
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">stmt</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span>
|
||||
function stmt()
|
||||
object t = NULL, e, s
|
||||
|
||||
<span style="color: #008080;">switch</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_if</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">condition</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">paren_expr</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"If-cond"</span><span style="color: #0000FF;">);</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">ifblock</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stmt</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">elseblock</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">;</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">tk_else</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #000000;">elseblock</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stmt</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_if</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">condition</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_if</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ifblock</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">elseblock</span><span style="color: #0000FF;">}}</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_putc</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">paren_expr</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Prtc"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_putc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Putc"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tk_Semicolon</span><span style="color: #0000FF;">);</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_print</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Print"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tk_LeftParen</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">tk_String</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_Prints</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_String</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]},</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_Printi</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">),</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_Sequence</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">tk_Comma</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Print"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tk_Comma</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Print"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tk_RightParen</span><span style="color: #0000FF;">);</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Print"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tk_Semicolon</span><span style="color: #0000FF;">);</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_Semicolon</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_Identifier</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">v</span>
|
||||
<span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_Identifier</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]}</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"assign"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tk_assign</span><span style="color: #0000FF;">);</span>
|
||||
<span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">);</span>
|
||||
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_assign</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"assign"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tk_Semicolon</span><span style="color: #0000FF;">);</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_while</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">paren_expr</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"while"</span><span style="color: #0000FF;">);</span>
|
||||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stmt</span><span style="color: #0000FF;">();</span>
|
||||
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_while</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_LeftBrace</span><span style="color: #0000FF;">:</span> <span style="color: #000080;font-style:italic;">/* {stmt} */</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"LeftBrace"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tk_LeftBrace</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">],{</span><span style="color: #000000;">tk_RightBrace</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tk_EOI</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_Sequence</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">stmt</span><span style="color: #0000FF;">()}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #000000;">expect</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"LeftBrace"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tk_RightBrace</span><span style="color: #0000FF;">);</span>
|
||||
<span style="color: #008080;">break</span><span style="color: #0000FF;">;</span>
|
||||
<span style="color: #008080;">case</span> <span style="color: #000000;">tk_EOI</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #008080;">break</span><span style="color: #0000FF;">;</span>
|
||||
<span style="color: #008080;">default</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">errd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"expecting start of statement, found '%s'\n"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tkNames</span><span style="color: #0000FF;">[</span><span style="color: #000000;">tok</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]]);</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">t</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
switch tok[3] do
|
||||
case tk_if:
|
||||
tok = get_tok();
|
||||
object condition = paren_expr("If-cond");
|
||||
object ifblock = stmt();
|
||||
object elseblock = NULL;
|
||||
if tok[3] == tk_else then
|
||||
tok = get_tok();
|
||||
elseblock = stmt();
|
||||
end if
|
||||
t = {tk_if, condition, {tk_if, ifblock, elseblock}}
|
||||
case tk_putc:
|
||||
tok = get_tok();
|
||||
e = paren_expr("Prtc")
|
||||
t = {tk_putc, e, NULL}
|
||||
expect("Putc", tk_Semicolon);
|
||||
case tk_print:
|
||||
tok = get_tok();
|
||||
expect("Print",tk_LeftParen)
|
||||
while 1 do
|
||||
if tok[3] == tk_String then
|
||||
e = {tk_Prints, {tk_String, tok[4]}, NULL}
|
||||
tok = get_tok();
|
||||
else
|
||||
e = {tk_Printi, expr(0), NULL}
|
||||
end if
|
||||
t = {tk_Sequence, t, e}
|
||||
if tok[3]!=tk_Comma then exit end if
|
||||
expect("Print", tk_Comma)
|
||||
end while
|
||||
expect("Print", tk_RightParen);
|
||||
expect("Print", tk_Semicolon);
|
||||
case tk_Semicolon:
|
||||
tok = get_tok();
|
||||
case tk_Identifier:
|
||||
object v
|
||||
v = {tk_Identifier, tok[4]}
|
||||
tok = get_tok();
|
||||
expect("assign", tk_assign);
|
||||
e = expr(0);
|
||||
t = {tk_assign, v, e}
|
||||
expect("assign", tk_Semicolon);
|
||||
case tk_while:
|
||||
tok = get_tok();
|
||||
e = paren_expr("while");
|
||||
s = stmt();
|
||||
t = {tk_while, e, s}
|
||||
case tk_LeftBrace: /* {stmt} */
|
||||
expect("LeftBrace", tk_LeftBrace)
|
||||
while not find(tok[3],{tk_RightBrace,tk_EOI}) do
|
||||
t = {tk_Sequence, t, stmt()}
|
||||
end while
|
||||
expect("LeftBrace", tk_RightBrace);
|
||||
break;
|
||||
case tk_EOI:
|
||||
break;
|
||||
default:
|
||||
errd("expecting start of statement, found '%s'\n", tkNames[tok[3]]);
|
||||
end switch
|
||||
return t
|
||||
end function
|
||||
|
||||
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #000000;">parse</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">NULL</span>
|
||||
<span style="color: #000000;">tok</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_tok</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stmt</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tk_Sequence</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">t</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
<!--
|
||||
global function parse()
|
||||
object t = NULL
|
||||
tok = get_tok()
|
||||
while 1 do
|
||||
object s = stmt()
|
||||
if s=NULL then exit end if
|
||||
t = {tk_Sequence, t, s}
|
||||
end while
|
||||
return t
|
||||
end function
|
||||
And a simple test driver for the specific task:
|
||||
|
|
|
|||
|
|
@ -1,60 +1,55 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- demo\rosetta\Compiler\parse.exw
|
||||
-- ===============================
|
||||
--</span>
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">include</span> <span style="color: #000000;">parse</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
|
||||
-- demo\rosetta\Compiler\parse.exw
|
||||
with javascript_semantics
|
||||
include parse.e
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">print_ast</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">==</span> <span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">output_file</span><span style="color: #0000FF;">,</span><span style="color: #008000;">";\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ttype</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">output_file</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tkNames</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ttype</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">ttype</span><span style="color: #0000FF;">=</span><span style="color: #000000;">tk_Identifier</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">output_file</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %s\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">ttype</span><span style="color: #0000FF;">=</span><span style="color: #000000;">tk_Integer</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">output_file</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">ttype</span><span style="color: #0000FF;">=</span><span style="color: #000000;">tk_String</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">output_file</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %s\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">enquote</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]))</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">output_file</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">print_ast</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #000000;">print_ast</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
procedure print_ast(object t)
|
||||
if t == NULL then
|
||||
printf(output_file,";\n")
|
||||
else
|
||||
integer ttype = t[1]
|
||||
printf(output_file,tkNames[ttype])
|
||||
if ttype=tk_Identifier then
|
||||
printf(output_file," %s\n",t[2])
|
||||
elsif ttype=tk_Integer then
|
||||
printf(output_file," %d\n",t[2])
|
||||
elsif ttype=tk_String then
|
||||
printf(output_file," %s\n",enquote(t[2]))
|
||||
else
|
||||
printf(output_file,"\n")
|
||||
print_ast(t[2])
|
||||
print_ast(t[3])
|
||||
end if
|
||||
end if
|
||||
end procedure
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">ptree</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tkNames</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">tk_Identifier</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tk_String</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">t1</span><span style="color: #0000FF;">=</span><span style="color: #000000;">tk_Sequence</span> <span style="color: #008080;">and</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"NULL"</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ptree</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">t</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
function ptree(object t)
|
||||
if sequence(t) then
|
||||
integer t1 = t[1]
|
||||
t = deep_copy(t)
|
||||
t[1] = tkNames[t1]
|
||||
if not find(t1,{tk_Identifier,tk_String}) then
|
||||
for i=2 to length(t) do
|
||||
if t1=tk_Sequence and t[i]=NULL then
|
||||
t[i] = "NULL"
|
||||
else
|
||||
t[i] = ptree(t[i])
|
||||
end if
|
||||
end for
|
||||
end if
|
||||
end if
|
||||
return t
|
||||
end function
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">cl</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">open_files</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cl</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">toks</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">lex</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #004080;">object</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">parse</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">print_ast</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ptree</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">),{</span><span style="color: #004600;">pp_Nest</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #004600;">pp_Pause</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #004600;">pp_IntCh</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #000000;">close_files</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
procedure main(sequence cl)
|
||||
open_files(cl)
|
||||
toks = lex()
|
||||
object t = parse()
|
||||
print_ast(t)
|
||||
pp(ptree(t),{pp_Nest,10,pp_Pause,0,pp_IntCh,false})
|
||||
close_files()
|
||||
end procedure
|
||||
|
||||
<span style="color: #000080;font-style:italic;">--main(command_line())</span>
|
||||
<span style="color: #000000;">main</span><span style="color: #0000FF;">({</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"test3.c"</span><span style="color: #0000FF;">})</span> <span style="color: #000080;font-style:italic;">-- not parseable!
|
||||
--main({0,0,"primes.c"}) -- as Algol, C, Python (apart from spacing)
|
||||
--main({0,0,"count.c"}) -- as AWK ( "" )</span>
|
||||
<!--
|
||||
--main(command_line())
|
||||
main({0,0,"test3.c"}) -- not parseable!
|
||||
--main({0,0,"primes.c"}) -- as Algol, C, Python (apart from spacing)
|
||||
--main({0,0,"count.c"}) -- as AWK ( "" )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue