Data update

This commit is contained in:
Ingy döt Net 2026-02-01 16:33:20 -08:00
parent 5150844a7d
commit 4bb20c9b71
7735 changed files with 38060 additions and 199180 deletions

View file

@ -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);

View file

@ -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.

View file

@ -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:

View file

@ -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 ( "" )