home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
ipl
/
progs
/
parse.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
3KB
|
134 lines
############################################################################
#
# File: parse.icn
#
# Subject: Program to parse simple statements
#
# Author: Kenneth Walker
#
# Date: February 18, 1996
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# This program parses simple statements.
#
# It provides an interesting example of the use of co-expressions.
#
############################################################################
global lex # co-expression for lexical analyzer
global next_tok # next token from input
record token(type, string)
procedure main()
lex := create ((!&input ? get_tok()) | |token("eof", "eof"))
prog()
end
#
# get_tok is the main body of lexical analyzer
#
procedure get_tok()
local tok
repeat { # skip white space and comments
tab(many(' '))
if ="#" | pos(0) then fail
if any(&letters) then # determine token type
tok := token("id", tab(many(&letters ++ '_')))
else if any(&digits) then
tok := token("integer", tab(many(&digits)))
else case move(1) of {
";" : tok := token("semi", ";")
"(" : tok := token("lparen", "(")
")" : tok := token("rparen", ")")
":" : if ="=" then tok := token("assign", ":=")
else tok := token("colon", ":")
"+" : tok := token("add_op", "+")
"-" : tok := token("add_op", "-")
"*" : tok := token("mult_op", "*")
"/" : tok := token("mult_op", "/")
default : err("invalid character in input")
}
suspend tok
}
end
#
# The procedures that follow make up the parser
#
procedure prog()
next_tok := @lex
stmt()
while next_tok.type == "semi" do {
next_tok := @lex
stmt()
}
if next_tok.type ~== "eof" then
err("eof expected")
end
procedure stmt()
if next_tok.type ~== "id" then
err("id expected")
write(next_tok.string)
if (@lex).type ~== "assign" then
err(":= expected")
next_tok := @lex
expr()
write(":=")
end
procedure expr()
local op
term()
while next_tok.type == "add_op" do {
op := next_tok.string
next_tok := @lex
term()
write(op)
}
end
procedure term()
local op
factor()
while next_tok.type == "mult_op" do {
op := next_tok.string
next_tok := @lex
factor()
write(op)
}
end
procedure factor()
case next_tok.type of {
"id" | "integer": {
write(next_tok.string)
next_tok := @lex
}
"lparen": {
next_tok := @lex
expr()
if next_tok.type ~== "rparen" then
err(") expected")
else
next_tok := @lex
}
default:
err("id or integer expected")
}
end
procedure err(s)
stop(" ** error ** ", s)
end