# File test/src/full_parser_test.rb, line 19
  def parser
    keywords = Keywords.case_sensitive(%w{case when else end and or not true false})
    ops = Operators.new(%w{+ - * / % ++ -- == > < >= <= != : ( )})
    lexer = integer.token(:int)|keywords.lexer|ops.lexer
    delim = whitespaces |comment_line('#')
    lexeme = lexer.lexeme(delim) << eof
    expr = nil
    lazy_expr = lazy{expr}
    compare = ops['>'] >> Gt | ops['<'] >> Lt | ops['>='] >> Ge | ops['<='] >> Le |
      ops['=='] >> Eq | ops['!='] >> Ne
    comparison = sequence(lazy_expr, compare, lazy_expr) {|e1,f,e2|f.call(e1,e2)}
    bool = nil
    lazy_bool = lazy{bool}
    bool_term = keywords[:true] >> true | keywords[:false] >> false |
      comparison | ops['('] >> lazy_bool << ops[')']
    bool_table = OperatorTable.new.
      infixl(keywords[:or] >> Or, 20).
      infixl(keywords[:and] >> And, 30).
      infixl(keywords[:not] >> Not, 30)
    
    bool = Expressions.build(bool_term, bool_table)
    simple_case = sequence(keywords[:when], lazy_expr, ops[':'], lazy_expr) do |w,cond,t,val|
      [cond, val]
    end
    full_case = sequence(keywords[:when], bool, ops[':'], lazy_expr) do |w,cond,t,val|
      [cond, val]
    end
    default_case = (keywords[:else] >> lazy_expr).optional
    simple_when_then = sequence(lazy_expr, simple_case.many, default_case, 
      keywords[:end]) do |val, cases, default|
      calculate_simple_cases(val, cases, default)
    end
    full_when_then = sequence(full_case.many, default_case, keywords[:end]) do |cases, default|
      calculate_full_cases(cases, default)
    end
    case_expr = keywords[:case] >> (simple_when_then | full_when_then)
    
    term = token(:int, &To_i) | (ops['('] >> lazy_expr << ops[')']) | case_expr
    table = OperatorTable.new.
      infixl(ops['+'] >> Plus, 20).
      infixl(ops['-'] >> Minus, 20).
      infixl(ops['*'] >> Mul, 30).
      infixl(ops['/'] >> Div, 30).
      postfix(ops['++'] >> Inc, 40).
      postfix(ops['--'] >> Dec, 40).
      prefix(ops['-'] >> Neg, 50)
    expr = Expressions.build(term, table)
    lexeme.nested(expr << eof)
  end