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
/
parsex.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
4KB
|
168 lines
############################################################################
#
# File: parsex.icn
#
# Subject: Program to parse arithmetic expressions
#
# Author: Cheyenne Wills
#
# Date: June 10, 1988
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# Adapted from C code written by Allen I. Holub published in the
# Feb 1987 issue of Dr. Dobb's Journal.
#
# General purpose expression analyzer. Can evaluate any expression
# consisting of number and the following operators (listed according
# to precedence level):
#
# () - ! 'str'str'
# * / &
# + -
# < <= > >= == !=
# && ||
#
# All operators associate left to right unless () are present.
# The top - is a unary minus.
#
#
# <expr> ::= <term> <expr1>
# <expr1> ::= && <term> <expr1>
# ::= || <term> <expr1>
# ::= epsilon
#
# <term> ::= <fact> <term1>
# <term1> ::= < <fact> <term1>
# ::= <= <fact> <term1>
# ::= > <fact> <term1>
# ::= >= <fact> <term1>
# ::= == <fact> <term1>
# ::= != <fact> <term1>
# ::= epsilon
#
# <fact> ::= <part> <fact1>
# <fact1> ::= + <part> <fact1>
# ::= - <part> <fact1>
# ::= - <part> <fact1>
# ::= epsilon
#
# <part> ::= <const> <part1>
# <part1> ::= * <const> <part1>
# ::= / <const> <part1>
# ::= % <const> <part1>
# ::= epsilon
#
# <const> ::= ( <expr> )
# ::= - ( <expr> )
# ::= - <const>
# ::= ! <const>
# ::= 's1's2' # compares s1 with s2 0 if ~= else 1
# ::= NUMBER # number is a lose term any('0123456789.Ee')
#
############################################################################
procedure main()
local line
writes("->")
while line := read() do {
write(parse(line))
writes("->")
}
end
procedure parse(exp)
return exp ? expr()
end
procedure expr(exp)
local lvalue
lvalue := term()
repeat {
tab(many(' \t'))
if ="&&" then lvalue := iand(term(),lvalue)
else if ="||" then lvalue := ior(term(),lvalue)
else break
}
return lvalue
end
procedure term()
local lvalue
lvalue := fact()
repeat {
tab(many(' \t'))
if ="<=" then lvalue := if lvalue <= fact() then 1 else 0
else if ="<" then lvalue := if lvalue < fact() then 1 else 0
else if =">=" then lvalue := if lvalue >= fact() then 1 else 0
else if =">" then lvalue := if lvalue > fact() then 1 else 0
else if ="==" then lvalue := if lvalue = fact() then 1 else 0
else if ="!=" then lvalue := if lvalue ~= fact() then 1 else 0
else break
}
return lvalue
end
procedure fact()
local lvalue
lvalue := part()
repeat {
tab(many(' \t'))
if ="+" then lvalue +:= part()
else if ="-" then lvalue -:= part()
else break
}
return lvalue
end
procedure part()
local lvalue
lvalue := const()
repeat {
tab(many(' \t'))
if ="*" then lvalue *:= part()
else if ="%" then lvalue %:= part()
else if ="/" then lvalue /:= part()
else break
}
return lvalue
end
procedure const()
local sign, logical, rval, s1, s2
tab(many(' \t'))
if ="-" then sign := -1 else sign := 1
if ="!" then logical := 1 else logical := &null
if ="(" then {
rval := expr()
if not match(")") then {
write(&subject)
write(right("",&pos-1,"_"),"^ Mis-matched parenthesis")
}
else move(1)
}
else if ="'" then {
s1 := tab(upto('\''))
move(1)
s2 := tab(upto('\''))
move(1)
rval := if s1 === s2 then 1 else 0
}
else {
rval := tab(many('0123456789.eE'))
}
if \logical then { return if rval = 0 then 1 else 0 }
else return rval * sign
end