* Copyright (c) 1989 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)expr.c 5.3 (Berkeley) %G%";
* expression evaluator: performs a standard recursive
* descent parse to evaluate any expression permissible
* within the following grammar:
* | lor "?" query ":" query
* lor : land { "||" land }
* land : bor { "&&" bor }
* bor : bxor { "|" bxor }
* bxor : band { "^" band }
* eql : relat { eqrel relat }
* relat : shift { rel shift }
* shift : primary { shop primary }
* primary : term { addop term }
* term : unary { mulop unary }
* This expression evaluator is lifted from a public-domain
* C Pre-Processor included with the DECUS C Compiler distribution.
* It is hacked somewhat to be suitable for m4.
* Originally by: Mike Lutz
static char *nxtch
; /* Parser scan pointer */
* ungetch - Put back the last character examined.
* getch - return the next character from expr string.
#define ungetch() nxtch--
if (setjmp(expjump
) != 0)
experr("Ill-formed expression");
* query : lor | lor '?' query ':' query
register int bool, true_val
, false_val
;
return(bool ? true_val
: false_val
);
* lor : land { '||' land }
while ((c
= skipws()) == '|' && getch() == '|') {
* land : bor { '&&' bor }
while ((c
= skipws()) == '&' && getch() == '&') {
* bor : bxor { '|' bxor }
while ((c
= skipws()) == '|' && getch() != '|') {
* bxor : band { '^' band }
while (skipws() == '^') {
while ((c
= skipws()) == '&' && getch() != '&') {
* eql : relat { eqrel relat }
register int vl
, vr
, rel
;
while ((rel
= geteql()) != -1) {
* relat : shift { rel shift }
register int vl
, vr
, rel
;
while ((rel
= getrel()) != -1) {
* shift : primary { shop primary }
while (((c
= skipws()) == '<' || c
== '>') && c
== getch()) {
if (c
== '<' || c
== '>')
* primary : term { addop term }
while ((c
= skipws()) == '+' || c
== '-') {
* <term> := <unary> { <mulop> <unary> }
while ((c
= skipws()) == '*' || c
== '/' || c
== '%') {
* unary : factor | unop unary
if ((c
= skipws()) == '!' || c
== '~' || c
== '-') {
* factor : constant | '(' query ')'
* Note: constant() handles multi-byte constants
for (i
= 0; i
< sizeof(int); i
++) {
if ((c
= getch()) == '\'') {
if (i
== 0 || getch() != '\'')
experr("Illegal character constant");
for (value
= 0; --i
>= 0;) {
* num : digit | num digit
register int rval
, c
, base
;
base
= ((c
= skipws()) == '0') ? OCTAL
: DECIMAL
;
while (c
>= '0' && c
<= (base
== OCTAL
? '7' : '9')) {
* eqlrel : '=' | '==' | '!='
* rel : '<' | '>' | '<=' | '>='
* Skip over any white space and return terminating char.
while ((c
= getch()) <= ' ' && c
> EOS
)
* Error handler - resets environment to eval(), prints an error,
longjmp(expjump
, -1); /* Force eval() to return FALSE */