// parse implements a production in the expression parse hierarchy. Singles and // doubles are strings holding the operators that are available at at this precedence // level, while nextLevel implements the next higher precendence level. func (p *parser) parse(singles, doubles string, nextLevel func(*parser) *Expr) *Expr { e := nextLevel(p) for { if p.peek(true) == eof { return e } op := p.op(singles, doubles) if op == "" { return e } e = &Expr{ op: op, left: e, right: nextLevel(p), } } } // orlist = andList | andList '||' orList. func orList(p *parser) *Expr { return p.parse("", "||", andList) } // andlist = cmpList | cmpList '&&' andList. func andList(p *parser) *Expr { return p.parse("", "&&", cmpList) } // cmpList = expr | expr ('>' | '<' | '==' | '!=' | '>=' | '<=') expr. func cmpList(p *parser) *Expr { return p.parse("+-|^!><", "==!=>=<=", expr) } // expr = term | term ('+' | '-' | '|' | '^') term. func expr(p *parser) *Expr { return p.parse("+-|^!", "", term) } // term = factor | factor ('*' | '/' | '%' | '>>' | '<<' | '&' | '&^') factor func term(p *parser) *Expr { return p.parse("*/%&", ">><<&^", factor) } // factor = constant | identifier | '+' factor | '-' factor | '^' factor | '!' factor | '(' orList ')' func factor(p *parser) *Expr {