diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | Makefile | 21 | ||||
-rw-r--r-- | _tags | 1 | ||||
-rw-r--r-- | frontend/ast.ml | 76 | ||||
-rw-r--r-- | frontend/ast_printer.ml | 177 | ||||
-rw-r--r-- | frontend/file_parser.ml | 19 | ||||
-rw-r--r-- | frontend/lexer.mll | 105 | ||||
-rw-r--r-- | frontend/parser.automaton | 1577 | ||||
-rw-r--r-- | frontend/parser.conflicts | 32 | ||||
-rw-r--r-- | frontend/parser.mly | 221 | ||||
-rw-r--r-- | libs/mapext.ml | 741 | ||||
-rw-r--r-- | libs/mapext.mli | 473 | ||||
-rw-r--r-- | libs/util.ml | 20 | ||||
-rw-r--r-- | main.ml | 25 |
14 files changed, 3492 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca7415d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.swp +_build +analyze +*~ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5e785e0 --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +.PHONY: clean + +BIN=analyze +SRCDIRS=libs,frontend + +SRC= main.ml \ + frontend/ast.ml \ + frontend/parser.mly \ + frontend/lexer.mll \ + frontend/ast_printer.ml + +all: $(BIN) + +$(BIN): $(SRC) + ocamlbuild -Is $(SRCDIRS) -cflags '-I +zarith -I +apron -I +gmp' \ + -lflags '-I +zarith -I +apron -I +gmp zarith.cmxa bigarray.cmxa gmp.cmxa apron.cmxa polkaMPQ.cmxa' \ + main.native + mv main.native $(BIN) + +clean: + rm -rf _build @@ -0,0 +1 @@ +true: use_menhir diff --git a/frontend/ast.ml b/frontend/ast.ml new file mode 100644 index 0000000..180608c --- /dev/null +++ b/frontend/ast.ml @@ -0,0 +1,76 @@ +open Lexing + +type position = Lexing.position +let position_unknown = Lexing.dummy_pos + +type extent = position * position +let extent_unknown = (position_unknown, position_unknown) + +type 'a ext = 'a * extent + +type id = string + +type typ = + | AST_TINT + | AST_TBOOL + | AST_TREAL + +type unary_op = + | AST_UPLUS + | AST_UMINUS + | AST_NOT + | AST_PRE + +type binary_op = + | AST_PLUS + | AST_MINUS + | AST_MUL + | AST_DIV + | AST_MOD + + | AST_EQ + | AST_NE + + | AST_LT + | AST_LE + | AST_GT + | AST_GE + + | AST_AND + | AST_OR + + | AST_ARROW + +type expr = + | AST_unary of unary_op * (expr ext) + | AST_binary of binary_op * (expr ext) * (expr ext) + | AST_identifier of id ext + | AST_int_const of string ext + | AST_bool_const of bool + | AST_real_const of string ext + | AST_if of (expr ext) * (expr ext) * (expr ext) + | AST_instance of (id ext) * (expr ext list) + +type lvalue = id + +type eqn = + | AST_assign of (lvalue ext) * (expr ext) + | AST_guarantee of (id ext) * (expr ext) + | AST_assume of (id ext) * (expr ext) + (* and more : automaton, activate... *) + +type node_decl = { + name : id; + args : (bool * (id ext) * typ) list; + ret : (bool * (id ext) * typ) list; + var : (bool * (id ext) * typ) list; + body : eqn ext list; +} + +type const_decl = (id ext) * typ * (expr ext) + +type toplevel = + | AST_node_decl of node_decl ext + | AST_const_decl of const_decl ext + +type prog = toplevel list diff --git a/frontend/ast_printer.ml b/frontend/ast_printer.ml new file mode 100644 index 0000000..a02b970 --- /dev/null +++ b/frontend/ast_printer.ml @@ -0,0 +1,177 @@ +open Ast +open Lexing + + +(* Locations *) + +let string_of_position p = + Printf.sprintf "%s:%i:%i" p.pos_fname p.pos_lnum (p.pos_cnum - p.pos_bol) + +let string_of_extent (p,q) = + if p.pos_fname = q.pos_fname then + if p.pos_lnum = q.pos_lnum then + if p.pos_cnum = q.pos_cnum then + Printf.sprintf "%s:%i.%i" p.pos_fname p.pos_lnum (p.pos_cnum - p.pos_bol) + else + Printf.sprintf "%s:%i.%i-%i" p.pos_fname p.pos_lnum (p.pos_cnum - p.pos_bol) (q.pos_cnum - q.pos_bol) + else + Printf.sprintf "%s:%i.%i-%i.%i" p.pos_fname p.pos_lnum (p.pos_cnum - p.pos_bol) q.pos_lnum (q.pos_cnum - q.pos_bol) + else + Printf.sprintf "%s:%i.%i-%s:%i.%i" p.pos_fname p.pos_lnum (p.pos_cnum - p.pos_bol) q.pos_fname q.pos_lnum (q.pos_cnum - q.pos_bol) + + +(* Operators *) + +let string_of_unary_op = function + | AST_UPLUS -> "+" + | AST_UMINUS -> "-" + | AST_NOT -> "not" + | AST_PRE -> "pre" + +let string_of_binary_op = function + | AST_MUL -> "*" + | AST_DIV -> "/" + | AST_MOD -> "mod" + | AST_PLUS -> "+" + | AST_MINUS -> "-" + | AST_EQ -> "=" + | AST_NE -> "<>" + | AST_LT -> "<" + | AST_LE -> "<=" + | AST_GT -> ">" + | AST_GE -> ">=" + | AST_AND -> "and" + | AST_OR -> "or" + | AST_ARROW -> "->" + + +let binary_precedence = function + | AST_MUL| AST_DIV| AST_MOD-> 7 + | AST_PLUS | AST_MINUS -> 6 + | AST_EQ | AST_NE -> 5 + | AST_LT | AST_LE | AST_GT | AST_GE -> 4 + | AST_AND -> 3 + | AST_OR -> 2 + | AST_ARROW -> 1 + +let expr_precedence = function + | AST_unary (op, _) -> 99 + | AST_binary(op, _, _) -> binary_precedence op + | _ -> 100 + +(* utility *) + +let print_list f sep fmt l = + let rec aux = function + | [] -> () + | [a] -> f fmt a + | a::b -> f fmt a; Format.pp_print_string fmt sep; aux b + in + aux l + +(* types *) + +let string_of_typ = function + | AST_TINT -> "int" + | AST_TBOOL -> "bool" + | AST_TREAL -> "real" + +(* expressions *) + +let print_id fmt v = + Format.pp_print_string fmt v + +let rec print_expr fmt e = + match e with + + | AST_unary (op,(e1,_)) -> + Format.pp_print_string fmt (string_of_unary_op op); + if expr_precedence e1 <= expr_precedence e + then Format.fprintf fmt " (%a)" print_expr e1 + else Format.fprintf fmt " %a" print_expr e1 + + | AST_binary (op,(e1,_),(e2,_)) -> + if expr_precedence e1 < expr_precedence e + then Format.fprintf fmt "(%a) " print_expr e1 + else Format.fprintf fmt "%a " print_expr e1; + Format.pp_print_string fmt (string_of_binary_op op); + if expr_precedence e2 <= expr_precedence e + then Format.fprintf fmt " (%a)" print_expr e2 + else Format.fprintf fmt " %a" print_expr e2 + + | AST_int_const (i,_) -> Format.pp_print_string fmt i + + | AST_real_const (i,_) -> Format.pp_print_string fmt i + + | AST_bool_const b -> Format.pp_print_bool fmt b + + | AST_if((c,_), (t,_), (e,_)) -> Format.fprintf fmt + "if %a then %a else %a" + print_expr c print_expr t print_expr e + + | AST_identifier (v,_) -> print_id fmt v + + | AST_instance ((i,_),l) -> + Format.fprintf fmt "%a(%a)" + print_id i (print_list print_expr ",") (List.map fst l) + +let print_lvalue fmt v = + Format.pp_print_string fmt v + +(* equations *) + +let indent ind = ind^" " + +let rec print_eqn ind fmt = function + + | AST_assign ((v,_),(e,_)) -> + Format.fprintf fmt "%s%a = %a;@\n" + ind print_lvalue v print_expr e + | AST_assume((i, _), (e, _)) -> + Format.fprintf fmt "%sassume %s : %a;@\n" + ind i print_expr e + | AST_guarantee((i, _), (e, _)) -> + Format.fprintf fmt "%sguarantee %s : %a;@\n" + ind i print_expr e + +and print_block ind fmt b = + List.iter (fun (bb,_) -> print_eqn (indent ind) fmt bb) b + +(* declarations *) + +let print_var_decl fmt (pr, (i, _), ty) = + Format.fprintf fmt "%s%s: %s" + (if pr then "probe " else "") + i + (string_of_typ ty) + +let rec print_var_decls fmt = function + | [] -> () + | [a] -> print_var_decl fmt a + | a::r -> + print_var_decl fmt a; + Format.fprintf fmt "; "; + print_var_decls fmt r + +let print_node_decl fmt d = + Format.fprintf fmt "node %s(%a) returns(%a)@\n" + d.name + print_var_decls d.args + print_var_decls d.ret; + if d.var <> [] then + Format.fprintf fmt "var %a@\n" print_var_decls d.var; + Format.fprintf fmt "let@\n%atel@\n@\n" + (print_block "") d.body + +let print_const_decl fmt ((i, _), ty, (e, _)) = + Format.fprintf fmt + "const %s: %s = %a@\n@\n" + i (string_of_typ ty) + print_expr e + +let print_toplevel fmt = function + | AST_node_decl (n, _) -> print_node_decl fmt n + | AST_const_decl (c, _) -> print_const_decl fmt c + +let print_prog fmt p = + List.iter (print_toplevel fmt) p diff --git a/frontend/file_parser.ml b/frontend/file_parser.ml new file mode 100644 index 0000000..0e975ce --- /dev/null +++ b/frontend/file_parser.ml @@ -0,0 +1,19 @@ +open Ast +open Ast_printer +open Lexing + +let parse_file (filename : string) : prog = + let f = open_in filename in + let lex = from_channel f in + try + lex.lex_curr_p <- { lex.lex_curr_p with pos_fname = filename; }; + Parser.file Lexer.token lex + with + | Parser.Error -> + Printf.eprintf "Parse error (invalid syntax) near %s\n" + (string_of_position lex.lex_start_p); + failwith "Parse error" + | Failure "lexing: empty token" -> + Printf.eprintf "Parse error (invalid token) near %s\n" + (string_of_position lex.lex_start_p); + failwith "Parse error" diff --git a/frontend/lexer.mll b/frontend/lexer.mll new file mode 100644 index 0000000..9d6c208 --- /dev/null +++ b/frontend/lexer.mll @@ -0,0 +1,105 @@ +{ + open Lexing + open Ast + open Parser + + let kwd_table = Hashtbl.create 10 + let () = + List.iter (fun (a, b) -> Hashtbl.add kwd_table a b) + [ + "bool", BOOL; + "int", INT; + "real", REAL; + + "const", CONST; + "node", NODE; + "returns", RETURNS; + "var", VAR; + "let", LET; + "tel", TEL; + + "if", IF; + "then", THEN; + "else", ELSE; + "pre", PRE; + "not", NOT; + "and", AND; + "or", OR; + "mod", MOD; + + "true", TRUE; + "false", FALSE; + + "assume", ASSUME; + "guarantee",GUARANTEE; + "probe", PROBE; + ] + +} + + +(* special character classes *) +let space = [' ' '\t' '\r']+ +let newline = "\n" | "\r" | "\r\n" + +(* utilities *) +let digit = ['0'-'9'] +let digit_ = ['0'-'9' '_'] + +(* integers *) +let int_dec = digit digit_* +let int_bin = ("0b" | "0B") ['0'-'1'] ['0'-'1' '_']* +let int_oct = ("0o" | "0O") ['0'-'7'] ['0'-'7' '_']* +let int_hex = ("0x" | "0X") ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F' '_']* +let const_int = int_bin | int_oct | int_dec | int_hex + +(* tokens *) +rule token = parse + +(* identifier (TOK_id) or reserved keyword *) +| ['a'-'z' 'A'-'Z' '_'] ['a'-'z' 'A'-'Z' '0'-'9' '_']* as id +{ try Hashtbl.find kwd_table id with Not_found -> IDENT id } + +(* symbols *) +| "(" { LPAREN } +| ")" { RPAREN } +| "{" { LCURLY } +| "}" { RCURLY } +| "*" { STAR } +| "+" { PLUS } +| "-" { MINUS } +| "!" { EXCLAIM } +| "/" { DIVIDE } +| "%" { PERCENT } +| "<" { LESS } +| ">" { GREATER } +| "<=" { LESS_EQUAL } +| ">=" { GREATER_EQUAL } +| "==" { EQUAL_EQUAL } +| "<>" { DIFF } +| "&&" { AND_AND } +| "||" { BAR_BAR } +| ";" { SEMICOLON } +| ":" { COLON } +| "," { COMMA } +| "=" { EQUAL } +| "->" { ARROW } + +(* literals *) +| const_int as c { INTVAL c } + +(* spaces, comments *) +| "(*" { comment lexbuf; token lexbuf } +| "--" [^ '\n' '\r']* { token lexbuf } +| newline { new_line lexbuf; token lexbuf } +| space { token lexbuf } + +(* end of files *) +| eof { EOF } + + +(* nested comments (handled recursively) *) +and comment = parse +| "*)" { () } +| [^ '\n' '\r'] { comment lexbuf } +| newline { new_line lexbuf; comment lexbuf } diff --git a/frontend/parser.automaton b/frontend/parser.automaton new file mode 100644 index 0000000..dff892b --- /dev/null +++ b/frontend/parser.automaton @@ -0,0 +1,1577 @@ +State 0: +file' -> . file [ # ] +-- On NODE shift to state 1 +-- On CONST shift to state 103 +-- On toplevel shift to state 109 +-- On node_decl shift to state 110 +-- On list(toplevel) shift to state 113 +-- On file shift to state 115 +-- On const_decl shift to state 112 +-- On EOF reduce production list(toplevel) -> + +State 1: +node_decl -> NODE . IDENT LPAREN vars RPAREN RETURNS vars RPAREN var_decl dbody [ NODE EOF CONST ] +-- On IDENT shift to state 2 + +State 2: +node_decl -> NODE IDENT . LPAREN vars RPAREN RETURNS vars RPAREN var_decl dbody [ NODE EOF CONST ] +-- On LPAREN shift to state 3 + +State 3: +node_decl -> NODE IDENT LPAREN . vars RPAREN RETURNS vars RPAREN var_decl dbody [ NODE EOF CONST ] +-- On IDENT shift to state 4 +-- On vars shift to state 10 +-- On var shift to state 98 +-- On separated_nonempty_list(SEMICOLON,var) shift to state 101 +-- On loption(separated_nonempty_list(SEMICOLON,var)) shift to state 102 +-- On RPAREN reduce production loption(separated_nonempty_list(SEMICOLON,var)) -> + +State 4: +var -> IDENT . COLON typ [ SEMICOLON RPAREN ] +-- On COLON shift to state 5 + +State 5: +var -> IDENT COLON . typ [ SEMICOLON RPAREN ] +-- On REAL shift to state 6 +-- On INT shift to state 7 +-- On BOOL shift to state 8 +-- On typ shift to state 9 + +State 6: +typ -> REAL . [ SEMICOLON RPAREN EQUAL ] +-- On SEMICOLON reduce production typ -> REAL +-- On RPAREN reduce production typ -> REAL +-- On EQUAL reduce production typ -> REAL + +State 7: +typ -> INT . [ SEMICOLON RPAREN EQUAL ] +-- On SEMICOLON reduce production typ -> INT +-- On RPAREN reduce production typ -> INT +-- On EQUAL reduce production typ -> INT + +State 8: +typ -> BOOL . [ SEMICOLON RPAREN EQUAL ] +-- On SEMICOLON reduce production typ -> BOOL +-- On RPAREN reduce production typ -> BOOL +-- On EQUAL reduce production typ -> BOOL + +State 9: +var -> IDENT COLON typ . [ SEMICOLON RPAREN ] +-- On SEMICOLON reduce production var -> IDENT COLON typ +-- On RPAREN reduce production var -> IDENT COLON typ + +State 10: +node_decl -> NODE IDENT LPAREN vars . RPAREN RETURNS vars RPAREN var_decl dbody [ NODE EOF CONST ] +-- On RPAREN shift to state 11 + +State 11: +node_decl -> NODE IDENT LPAREN vars RPAREN . RETURNS vars RPAREN var_decl dbody [ NODE EOF CONST ] +-- On RETURNS shift to state 12 + +State 12: +node_decl -> NODE IDENT LPAREN vars RPAREN RETURNS . vars RPAREN var_decl dbody [ NODE EOF CONST ] +-- On IDENT shift to state 4 +-- On vars shift to state 13 +-- On var shift to state 98 +-- On separated_nonempty_list(SEMICOLON,var) shift to state 101 +-- On loption(separated_nonempty_list(SEMICOLON,var)) shift to state 102 +-- On RPAREN reduce production loption(separated_nonempty_list(SEMICOLON,var)) -> + +State 13: +node_decl -> NODE IDENT LPAREN vars RPAREN RETURNS vars . RPAREN var_decl dbody [ NODE EOF CONST ] +-- On RPAREN shift to state 14 + +State 14: +node_decl -> NODE IDENT LPAREN vars RPAREN RETURNS vars RPAREN . var_decl dbody [ NODE EOF CONST ] +-- On VAR shift to state 15 +-- On var_decl shift to state 20 +-- On LET reduce production var_decl -> +-- On IDENT reduce production var_decl -> +-- On GUARANTEE reduce production var_decl -> +-- On ASSUME reduce production var_decl -> + +State 15: +var_decl -> VAR . nonempty_list(terminated(var,SEMICOLON)) [ LET IDENT GUARANTEE ASSUME ] +-- On IDENT shift to state 4 +-- On var shift to state 16 +-- On nonempty_list(terminated(var,SEMICOLON)) shift to state 19 + +State 16: +nonempty_list(terminated(var,SEMICOLON)) -> var . SEMICOLON [ LET IDENT GUARANTEE ASSUME ] +nonempty_list(terminated(var,SEMICOLON)) -> var . SEMICOLON nonempty_list(terminated(var,SEMICOLON)) [ LET IDENT GUARANTEE ASSUME ] +-- On SEMICOLON shift to state 17 + +State 17: +nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON . [ LET IDENT GUARANTEE ASSUME ] +nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON . nonempty_list(terminated(var,SEMICOLON)) [ LET IDENT GUARANTEE ASSUME ] +-- On IDENT shift to state 4 +-- On var shift to state 16 +-- On nonempty_list(terminated(var,SEMICOLON)) shift to state 18 +-- On LET reduce production nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON +-- On IDENT reduce production nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON +-- On GUARANTEE reduce production nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON +-- On ASSUME reduce production nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON +** Conflict on IDENT + +State 18: +nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON nonempty_list(terminated(var,SEMICOLON)) . [ LET IDENT GUARANTEE ASSUME ] +-- On LET reduce production nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON nonempty_list(terminated(var,SEMICOLON)) +-- On IDENT reduce production nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON nonempty_list(terminated(var,SEMICOLON)) +-- On GUARANTEE reduce production nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON nonempty_list(terminated(var,SEMICOLON)) +-- On ASSUME reduce production nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON nonempty_list(terminated(var,SEMICOLON)) + +State 19: +var_decl -> VAR nonempty_list(terminated(var,SEMICOLON)) . [ LET IDENT GUARANTEE ASSUME ] +-- On LET reduce production var_decl -> VAR nonempty_list(terminated(var,SEMICOLON)) +-- On IDENT reduce production var_decl -> VAR nonempty_list(terminated(var,SEMICOLON)) +-- On GUARANTEE reduce production var_decl -> VAR nonempty_list(terminated(var,SEMICOLON)) +-- On ASSUME reduce production var_decl -> VAR nonempty_list(terminated(var,SEMICOLON)) + +State 20: +node_decl -> NODE IDENT LPAREN vars RPAREN RETURNS vars RPAREN var_decl . dbody [ NODE EOF CONST ] +-- On LET shift to state 21 +-- On IDENT shift to state 22 +-- On GUARANTEE shift to state 23 +-- On ASSUME shift to state 83 +-- On lvalue shift to state 89 +-- On eqn shift to state 95 +-- On dbody shift to state 97 + +State 21: +dbody -> LET . separated_nonempty_list(SEMICOLON,ext(eqn)) TEL [ NODE EOF CONST ] +-- On IDENT shift to state 22 +-- On GUARANTEE shift to state 23 +-- On ASSUME shift to state 83 +-- On separated_nonempty_list(SEMICOLON,ext(eqn)) shift to state 87 +-- On lvalue shift to state 89 +-- On eqn shift to state 92 + +State 22: +lvalue -> IDENT . [ EQUAL ] +-- On EQUAL reduce production lvalue -> IDENT + +State 23: +eqn -> GUARANTEE . IDENT COLON expr [ TEL SEMICOLON ] +-- On IDENT shift to state 24 + +State 24: +eqn -> GUARANTEE IDENT . COLON expr [ TEL SEMICOLON ] +-- On COLON shift to state 25 + +State 25: +eqn -> GUARANTEE IDENT COLON . expr [ TEL SEMICOLON ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IF shift to state 32 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On if_expr shift to state 41 +-- On expr shift to state 82 +-- On binary_expr shift to state 45 + +State 26: +primary_expr -> TRUE . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production primary_expr -> TRUE +-- On TEL reduce production primary_expr -> TRUE +-- On STAR reduce production primary_expr -> TRUE +-- On SEMICOLON reduce production primary_expr -> TRUE +-- On RPAREN reduce production primary_expr -> TRUE +-- On PLUS reduce production primary_expr -> TRUE +-- On PERCENT reduce production primary_expr -> TRUE +-- On NOT_EQUAL reduce production primary_expr -> TRUE +-- On NODE reduce production primary_expr -> TRUE +-- On MINUS reduce production primary_expr -> TRUE +-- On LESS_EQUAL reduce production primary_expr -> TRUE +-- On LESS reduce production primary_expr -> TRUE +-- On GREATER_EQUAL reduce production primary_expr -> TRUE +-- On GREATER reduce production primary_expr -> TRUE +-- On EQUAL_EQUAL reduce production primary_expr -> TRUE +-- On EOF reduce production primary_expr -> TRUE +-- On ELSE reduce production primary_expr -> TRUE +-- On DIVIDE reduce production primary_expr -> TRUE +-- On CONST reduce production primary_expr -> TRUE +-- On COMMA reduce production primary_expr -> TRUE +-- On BAR_BAR reduce production primary_expr -> TRUE +-- On AND_AND reduce production primary_expr -> TRUE + +State 27: +unary_expr -> PLUS . unary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 81 +-- On primary_expr shift to state 38 + +State 28: +unary_expr -> NOT . unary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 80 +-- On primary_expr shift to state 38 + +State 29: +unary_expr -> MINUS . unary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 79 +-- On primary_expr shift to state 38 + +State 30: +primary_expr -> LPAREN . expr RPAREN [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IF shift to state 32 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On if_expr shift to state 41 +-- On expr shift to state 77 +-- On binary_expr shift to state 45 + +State 31: +primary_expr -> INTVAL . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production primary_expr -> INTVAL +-- On TEL reduce production primary_expr -> INTVAL +-- On STAR reduce production primary_expr -> INTVAL +-- On SEMICOLON reduce production primary_expr -> INTVAL +-- On RPAREN reduce production primary_expr -> INTVAL +-- On PLUS reduce production primary_expr -> INTVAL +-- On PERCENT reduce production primary_expr -> INTVAL +-- On NOT_EQUAL reduce production primary_expr -> INTVAL +-- On NODE reduce production primary_expr -> INTVAL +-- On MINUS reduce production primary_expr -> INTVAL +-- On LESS_EQUAL reduce production primary_expr -> INTVAL +-- On LESS reduce production primary_expr -> INTVAL +-- On GREATER_EQUAL reduce production primary_expr -> INTVAL +-- On GREATER reduce production primary_expr -> INTVAL +-- On EQUAL_EQUAL reduce production primary_expr -> INTVAL +-- On EOF reduce production primary_expr -> INTVAL +-- On ELSE reduce production primary_expr -> INTVAL +-- On DIVIDE reduce production primary_expr -> INTVAL +-- On CONST reduce production primary_expr -> INTVAL +-- On COMMA reduce production primary_expr -> INTVAL +-- On BAR_BAR reduce production primary_expr -> INTVAL +-- On AND_AND reduce production primary_expr -> INTVAL + +State 32: +if_expr -> IF . expr THEN expr ELSE expr [ THEN TEL SEMICOLON RPAREN NODE EOF ELSE CONST COMMA ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IF shift to state 32 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On if_expr shift to state 41 +-- On expr shift to state 72 +-- On binary_expr shift to state 45 + +State 33: +primary_expr -> IDENT . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +primary_expr -> IDENT . LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On LPAREN shift to state 34 +-- On THEN reduce production primary_expr -> IDENT +-- On TEL reduce production primary_expr -> IDENT +-- On STAR reduce production primary_expr -> IDENT +-- On SEMICOLON reduce production primary_expr -> IDENT +-- On RPAREN reduce production primary_expr -> IDENT +-- On PLUS reduce production primary_expr -> IDENT +-- On PERCENT reduce production primary_expr -> IDENT +-- On NOT_EQUAL reduce production primary_expr -> IDENT +-- On NODE reduce production primary_expr -> IDENT +-- On MINUS reduce production primary_expr -> IDENT +-- On LESS_EQUAL reduce production primary_expr -> IDENT +-- On LESS reduce production primary_expr -> IDENT +-- On GREATER_EQUAL reduce production primary_expr -> IDENT +-- On GREATER reduce production primary_expr -> IDENT +-- On EQUAL_EQUAL reduce production primary_expr -> IDENT +-- On EOF reduce production primary_expr -> IDENT +-- On ELSE reduce production primary_expr -> IDENT +-- On DIVIDE reduce production primary_expr -> IDENT +-- On CONST reduce production primary_expr -> IDENT +-- On COMMA reduce production primary_expr -> IDENT +-- On BAR_BAR reduce production primary_expr -> IDENT +-- On AND_AND reduce production primary_expr -> IDENT + +State 34: +primary_expr -> IDENT LPAREN . loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IF shift to state 32 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On separated_nonempty_list(COMMA,ext(expr)) shift to state 37 +-- On primary_expr shift to state 38 +-- On loption(separated_nonempty_list(COMMA,ext(expr))) shift to state 39 +-- On if_expr shift to state 41 +-- On expr shift to state 42 +-- On binary_expr shift to state 45 +-- On RPAREN reduce production loption(separated_nonempty_list(COMMA,ext(expr))) -> + +State 35: +primary_expr -> FALSE . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production primary_expr -> FALSE +-- On TEL reduce production primary_expr -> FALSE +-- On STAR reduce production primary_expr -> FALSE +-- On SEMICOLON reduce production primary_expr -> FALSE +-- On RPAREN reduce production primary_expr -> FALSE +-- On PLUS reduce production primary_expr -> FALSE +-- On PERCENT reduce production primary_expr -> FALSE +-- On NOT_EQUAL reduce production primary_expr -> FALSE +-- On NODE reduce production primary_expr -> FALSE +-- On MINUS reduce production primary_expr -> FALSE +-- On LESS_EQUAL reduce production primary_expr -> FALSE +-- On LESS reduce production primary_expr -> FALSE +-- On GREATER_EQUAL reduce production primary_expr -> FALSE +-- On GREATER reduce production primary_expr -> FALSE +-- On EQUAL_EQUAL reduce production primary_expr -> FALSE +-- On EOF reduce production primary_expr -> FALSE +-- On ELSE reduce production primary_expr -> FALSE +-- On DIVIDE reduce production primary_expr -> FALSE +-- On CONST reduce production primary_expr -> FALSE +-- On COMMA reduce production primary_expr -> FALSE +-- On BAR_BAR reduce production primary_expr -> FALSE +-- On AND_AND reduce production primary_expr -> FALSE + +State 36: +binary_expr -> unary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production binary_expr -> unary_expr +-- On TEL reduce production binary_expr -> unary_expr +-- On STAR reduce production binary_expr -> unary_expr +-- On SEMICOLON reduce production binary_expr -> unary_expr +-- On RPAREN reduce production binary_expr -> unary_expr +-- On PLUS reduce production binary_expr -> unary_expr +-- On PERCENT reduce production binary_expr -> unary_expr +-- On NOT_EQUAL reduce production binary_expr -> unary_expr +-- On NODE reduce production binary_expr -> unary_expr +-- On MINUS reduce production binary_expr -> unary_expr +-- On LESS_EQUAL reduce production binary_expr -> unary_expr +-- On LESS reduce production binary_expr -> unary_expr +-- On GREATER_EQUAL reduce production binary_expr -> unary_expr +-- On GREATER reduce production binary_expr -> unary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> unary_expr +-- On EOF reduce production binary_expr -> unary_expr +-- On ELSE reduce production binary_expr -> unary_expr +-- On DIVIDE reduce production binary_expr -> unary_expr +-- On CONST reduce production binary_expr -> unary_expr +-- On COMMA reduce production binary_expr -> unary_expr +-- On BAR_BAR reduce production binary_expr -> unary_expr +-- On AND_AND reduce production binary_expr -> unary_expr + +State 37: +loption(separated_nonempty_list(COMMA,ext(expr))) -> separated_nonempty_list(COMMA,ext(expr)) . [ RPAREN ] +-- On RPAREN reduce production loption(separated_nonempty_list(COMMA,ext(expr))) -> separated_nonempty_list(COMMA,ext(expr)) + +State 38: +unary_expr -> primary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production unary_expr -> primary_expr +-- On TEL reduce production unary_expr -> primary_expr +-- On STAR reduce production unary_expr -> primary_expr +-- On SEMICOLON reduce production unary_expr -> primary_expr +-- On RPAREN reduce production unary_expr -> primary_expr +-- On PLUS reduce production unary_expr -> primary_expr +-- On PERCENT reduce production unary_expr -> primary_expr +-- On NOT_EQUAL reduce production unary_expr -> primary_expr +-- On NODE reduce production unary_expr -> primary_expr +-- On MINUS reduce production unary_expr -> primary_expr +-- On LESS_EQUAL reduce production unary_expr -> primary_expr +-- On LESS reduce production unary_expr -> primary_expr +-- On GREATER_EQUAL reduce production unary_expr -> primary_expr +-- On GREATER reduce production unary_expr -> primary_expr +-- On EQUAL_EQUAL reduce production unary_expr -> primary_expr +-- On EOF reduce production unary_expr -> primary_expr +-- On ELSE reduce production unary_expr -> primary_expr +-- On DIVIDE reduce production unary_expr -> primary_expr +-- On CONST reduce production unary_expr -> primary_expr +-- On COMMA reduce production unary_expr -> primary_expr +-- On BAR_BAR reduce production unary_expr -> primary_expr +-- On AND_AND reduce production unary_expr -> primary_expr + +State 39: +primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) . RPAREN [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On RPAREN shift to state 40 + +State 40: +primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On TEL reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On STAR reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On SEMICOLON reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On RPAREN reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On PLUS reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On PERCENT reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On NOT_EQUAL reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On NODE reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On MINUS reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On LESS_EQUAL reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On LESS reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On GREATER_EQUAL reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On GREATER reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On EQUAL_EQUAL reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On EOF reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On ELSE reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On DIVIDE reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On CONST reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On COMMA reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On BAR_BAR reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN +-- On AND_AND reduce production primary_expr -> IDENT LPAREN loption(separated_nonempty_list(COMMA,ext(expr))) RPAREN + +State 41: +expr -> if_expr . [ THEN TEL SEMICOLON RPAREN NODE EOF ELSE CONST COMMA ] +-- On THEN reduce production expr -> if_expr +-- On TEL reduce production expr -> if_expr +-- On SEMICOLON reduce production expr -> if_expr +-- On RPAREN reduce production expr -> if_expr +-- On NODE reduce production expr -> if_expr +-- On EOF reduce production expr -> if_expr +-- On ELSE reduce production expr -> if_expr +-- On CONST reduce production expr -> if_expr +-- On COMMA reduce production expr -> if_expr + +State 42: +separated_nonempty_list(COMMA,ext(expr)) -> expr . [ RPAREN ] +separated_nonempty_list(COMMA,ext(expr)) -> expr . COMMA separated_nonempty_list(COMMA,ext(expr)) [ RPAREN ] +-- On COMMA shift to state 43 +-- On RPAREN reduce production separated_nonempty_list(COMMA,ext(expr)) -> expr + +State 43: +separated_nonempty_list(COMMA,ext(expr)) -> expr COMMA . separated_nonempty_list(COMMA,ext(expr)) [ RPAREN ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IF shift to state 32 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On separated_nonempty_list(COMMA,ext(expr)) shift to state 44 +-- On primary_expr shift to state 38 +-- On if_expr shift to state 41 +-- On expr shift to state 42 +-- On binary_expr shift to state 45 + +State 44: +separated_nonempty_list(COMMA,ext(expr)) -> expr COMMA separated_nonempty_list(COMMA,ext(expr)) . [ RPAREN ] +-- On RPAREN reduce production separated_nonempty_list(COMMA,ext(expr)) -> expr COMMA separated_nonempty_list(COMMA,ext(expr)) + +State 45: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +if_expr -> binary_expr . [ THEN TEL SEMICOLON RPAREN NODE EOF ELSE CONST COMMA ] +-- On STAR shift to state 46 +-- On PLUS shift to state 48 +-- On PERCENT shift to state 50 +-- On NOT_EQUAL shift to state 54 +-- On MINUS shift to state 56 +-- On LESS_EQUAL shift to state 58 +-- On LESS shift to state 60 +-- On GREATER_EQUAL shift to state 62 +-- On GREATER shift to state 64 +-- On EQUAL_EQUAL shift to state 66 +-- On DIVIDE shift to state 52 +-- On BAR_BAR shift to state 68 +-- On AND_AND shift to state 70 +-- On THEN reduce production if_expr -> binary_expr +-- On TEL reduce production if_expr -> binary_expr +-- On SEMICOLON reduce production if_expr -> binary_expr +-- On RPAREN reduce production if_expr -> binary_expr +-- On NODE reduce production if_expr -> binary_expr +-- On EOF reduce production if_expr -> binary_expr +-- On ELSE reduce production if_expr -> binary_expr +-- On CONST reduce production if_expr -> binary_expr +-- On COMMA reduce production if_expr -> binary_expr + +State 46: +binary_expr -> binary_expr STAR . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 47 + +State 47: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr STAR binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production binary_expr -> binary_expr STAR binary_expr +-- On TEL reduce production binary_expr -> binary_expr STAR binary_expr +-- On STAR reduce production binary_expr -> binary_expr STAR binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr STAR binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr STAR binary_expr +-- On PLUS reduce production binary_expr -> binary_expr STAR binary_expr +-- On PERCENT reduce production binary_expr -> binary_expr STAR binary_expr +-- On NOT_EQUAL reduce production binary_expr -> binary_expr STAR binary_expr +-- On NODE reduce production binary_expr -> binary_expr STAR binary_expr +-- On MINUS reduce production binary_expr -> binary_expr STAR binary_expr +-- On LESS_EQUAL reduce production binary_expr -> binary_expr STAR binary_expr +-- On LESS reduce production binary_expr -> binary_expr STAR binary_expr +-- On GREATER_EQUAL reduce production binary_expr -> binary_expr STAR binary_expr +-- On GREATER reduce production binary_expr -> binary_expr STAR binary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> binary_expr STAR binary_expr +-- On EOF reduce production binary_expr -> binary_expr STAR binary_expr +-- On ELSE reduce production binary_expr -> binary_expr STAR binary_expr +-- On DIVIDE reduce production binary_expr -> binary_expr STAR binary_expr +-- On CONST reduce production binary_expr -> binary_expr STAR binary_expr +-- On COMMA reduce production binary_expr -> binary_expr STAR binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr STAR binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr STAR binary_expr + +State 48: +binary_expr -> binary_expr PLUS . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 49 + +State 49: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr PLUS binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On STAR shift to state 46 +-- On PERCENT shift to state 50 +-- On DIVIDE shift to state 52 +-- On THEN reduce production binary_expr -> binary_expr PLUS binary_expr +-- On TEL reduce production binary_expr -> binary_expr PLUS binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr PLUS binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr PLUS binary_expr +-- On PLUS reduce production binary_expr -> binary_expr PLUS binary_expr +-- On NOT_EQUAL reduce production binary_expr -> binary_expr PLUS binary_expr +-- On NODE reduce production binary_expr -> binary_expr PLUS binary_expr +-- On MINUS reduce production binary_expr -> binary_expr PLUS binary_expr +-- On LESS_EQUAL reduce production binary_expr -> binary_expr PLUS binary_expr +-- On LESS reduce production binary_expr -> binary_expr PLUS binary_expr +-- On GREATER_EQUAL reduce production binary_expr -> binary_expr PLUS binary_expr +-- On GREATER reduce production binary_expr -> binary_expr PLUS binary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> binary_expr PLUS binary_expr +-- On EOF reduce production binary_expr -> binary_expr PLUS binary_expr +-- On ELSE reduce production binary_expr -> binary_expr PLUS binary_expr +-- On CONST reduce production binary_expr -> binary_expr PLUS binary_expr +-- On COMMA reduce production binary_expr -> binary_expr PLUS binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr PLUS binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr PLUS binary_expr + +State 50: +binary_expr -> binary_expr PERCENT . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 51 + +State 51: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr PERCENT binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On TEL reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On STAR reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On PLUS reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On PERCENT reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On NOT_EQUAL reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On NODE reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On MINUS reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On LESS_EQUAL reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On LESS reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On GREATER_EQUAL reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On GREATER reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On EOF reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On ELSE reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On DIVIDE reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On CONST reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On COMMA reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr PERCENT binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr PERCENT binary_expr + +State 52: +binary_expr -> binary_expr DIVIDE . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 53 + +State 53: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr DIVIDE binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On TEL reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On STAR reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On PLUS reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On PERCENT reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On NOT_EQUAL reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On NODE reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On MINUS reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On LESS_EQUAL reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On LESS reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On GREATER_EQUAL reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On GREATER reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On EOF reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On ELSE reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On DIVIDE reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On CONST reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On COMMA reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr DIVIDE binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr DIVIDE binary_expr + +State 54: +binary_expr -> binary_expr NOT_EQUAL . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 55 + +State 55: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr NOT_EQUAL binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On STAR shift to state 46 +-- On PLUS shift to state 48 +-- On PERCENT shift to state 50 +-- On MINUS shift to state 56 +-- On LESS_EQUAL shift to state 58 +-- On LESS shift to state 60 +-- On GREATER_EQUAL shift to state 62 +-- On GREATER shift to state 64 +-- On DIVIDE shift to state 52 +-- On THEN reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On TEL reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On NOT_EQUAL reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On NODE reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On EOF reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On ELSE reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On CONST reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On COMMA reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr NOT_EQUAL binary_expr + +State 56: +binary_expr -> binary_expr MINUS . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 57 + +State 57: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr MINUS binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On STAR shift to state 46 +-- On PERCENT shift to state 50 +-- On DIVIDE shift to state 52 +-- On THEN reduce production binary_expr -> binary_expr MINUS binary_expr +-- On TEL reduce production binary_expr -> binary_expr MINUS binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr MINUS binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr MINUS binary_expr +-- On PLUS reduce production binary_expr -> binary_expr MINUS binary_expr +-- On NOT_EQUAL reduce production binary_expr -> binary_expr MINUS binary_expr +-- On NODE reduce production binary_expr -> binary_expr MINUS binary_expr +-- On MINUS reduce production binary_expr -> binary_expr MINUS binary_expr +-- On LESS_EQUAL reduce production binary_expr -> binary_expr MINUS binary_expr +-- On LESS reduce production binary_expr -> binary_expr MINUS binary_expr +-- On GREATER_EQUAL reduce production binary_expr -> binary_expr MINUS binary_expr +-- On GREATER reduce production binary_expr -> binary_expr MINUS binary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> binary_expr MINUS binary_expr +-- On EOF reduce production binary_expr -> binary_expr MINUS binary_expr +-- On ELSE reduce production binary_expr -> binary_expr MINUS binary_expr +-- On CONST reduce production binary_expr -> binary_expr MINUS binary_expr +-- On COMMA reduce production binary_expr -> binary_expr MINUS binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr MINUS binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr MINUS binary_expr + +State 58: +binary_expr -> binary_expr LESS_EQUAL . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 59 + +State 59: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr LESS_EQUAL binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On STAR shift to state 46 +-- On PLUS shift to state 48 +-- On PERCENT shift to state 50 +-- On MINUS shift to state 56 +-- On DIVIDE shift to state 52 +-- On THEN reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On TEL reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On NOT_EQUAL reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On NODE reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On LESS_EQUAL reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On LESS reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On GREATER_EQUAL reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On GREATER reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On EOF reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On ELSE reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On CONST reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On COMMA reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr LESS_EQUAL binary_expr + +State 60: +binary_expr -> binary_expr LESS . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 61 + +State 61: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr LESS binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On STAR shift to state 46 +-- On PLUS shift to state 48 +-- On PERCENT shift to state 50 +-- On MINUS shift to state 56 +-- On DIVIDE shift to state 52 +-- On THEN reduce production binary_expr -> binary_expr LESS binary_expr +-- On TEL reduce production binary_expr -> binary_expr LESS binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr LESS binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr LESS binary_expr +-- On NOT_EQUAL reduce production binary_expr -> binary_expr LESS binary_expr +-- On NODE reduce production binary_expr -> binary_expr LESS binary_expr +-- On LESS_EQUAL reduce production binary_expr -> binary_expr LESS binary_expr +-- On LESS reduce production binary_expr -> binary_expr LESS binary_expr +-- On GREATER_EQUAL reduce production binary_expr -> binary_expr LESS binary_expr +-- On GREATER reduce production binary_expr -> binary_expr LESS binary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> binary_expr LESS binary_expr +-- On EOF reduce production binary_expr -> binary_expr LESS binary_expr +-- On ELSE reduce production binary_expr -> binary_expr LESS binary_expr +-- On CONST reduce production binary_expr -> binary_expr LESS binary_expr +-- On COMMA reduce production binary_expr -> binary_expr LESS binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr LESS binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr LESS binary_expr + +State 62: +binary_expr -> binary_expr GREATER_EQUAL . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 63 + +State 63: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr GREATER_EQUAL binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On STAR shift to state 46 +-- On PLUS shift to state 48 +-- On PERCENT shift to state 50 +-- On MINUS shift to state 56 +-- On DIVIDE shift to state 52 +-- On THEN reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On TEL reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On NOT_EQUAL reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On NODE reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On LESS_EQUAL reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On LESS reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On GREATER_EQUAL reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On GREATER reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On EOF reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On ELSE reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On CONST reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On COMMA reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr GREATER_EQUAL binary_expr + +State 64: +binary_expr -> binary_expr GREATER . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 65 + +State 65: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr GREATER binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On STAR shift to state 46 +-- On PLUS shift to state 48 +-- On PERCENT shift to state 50 +-- On MINUS shift to state 56 +-- On DIVIDE shift to state 52 +-- On THEN reduce production binary_expr -> binary_expr GREATER binary_expr +-- On TEL reduce production binary_expr -> binary_expr GREATER binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr GREATER binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr GREATER binary_expr +-- On NOT_EQUAL reduce production binary_expr -> binary_expr GREATER binary_expr +-- On NODE reduce production binary_expr -> binary_expr GREATER binary_expr +-- On LESS_EQUAL reduce production binary_expr -> binary_expr GREATER binary_expr +-- On LESS reduce production binary_expr -> binary_expr GREATER binary_expr +-- On GREATER_EQUAL reduce production binary_expr -> binary_expr GREATER binary_expr +-- On GREATER reduce production binary_expr -> binary_expr GREATER binary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> binary_expr GREATER binary_expr +-- On EOF reduce production binary_expr -> binary_expr GREATER binary_expr +-- On ELSE reduce production binary_expr -> binary_expr GREATER binary_expr +-- On CONST reduce production binary_expr -> binary_expr GREATER binary_expr +-- On COMMA reduce production binary_expr -> binary_expr GREATER binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr GREATER binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr GREATER binary_expr + +State 66: +binary_expr -> binary_expr EQUAL_EQUAL . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 67 + +State 67: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr EQUAL_EQUAL binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On STAR shift to state 46 +-- On PLUS shift to state 48 +-- On PERCENT shift to state 50 +-- On MINUS shift to state 56 +-- On LESS_EQUAL shift to state 58 +-- On LESS shift to state 60 +-- On GREATER_EQUAL shift to state 62 +-- On GREATER shift to state 64 +-- On DIVIDE shift to state 52 +-- On THEN reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On TEL reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On NOT_EQUAL reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On NODE reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On EQUAL_EQUAL reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On EOF reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On ELSE reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On CONST reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On COMMA reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr EQUAL_EQUAL binary_expr + +State 68: +binary_expr -> binary_expr BAR_BAR . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 69 + +State 69: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr BAR_BAR binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On STAR shift to state 46 +-- On PLUS shift to state 48 +-- On PERCENT shift to state 50 +-- On NOT_EQUAL shift to state 54 +-- On MINUS shift to state 56 +-- On LESS_EQUAL shift to state 58 +-- On LESS shift to state 60 +-- On GREATER_EQUAL shift to state 62 +-- On GREATER shift to state 64 +-- On EQUAL_EQUAL shift to state 66 +-- On DIVIDE shift to state 52 +-- On AND_AND shift to state 70 +-- On THEN reduce production binary_expr -> binary_expr BAR_BAR binary_expr +-- On TEL reduce production binary_expr -> binary_expr BAR_BAR binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr BAR_BAR binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr BAR_BAR binary_expr +-- On NODE reduce production binary_expr -> binary_expr BAR_BAR binary_expr +-- On EOF reduce production binary_expr -> binary_expr BAR_BAR binary_expr +-- On ELSE reduce production binary_expr -> binary_expr BAR_BAR binary_expr +-- On CONST reduce production binary_expr -> binary_expr BAR_BAR binary_expr +-- On COMMA reduce production binary_expr -> binary_expr BAR_BAR binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr BAR_BAR binary_expr + +State 70: +binary_expr -> binary_expr AND_AND . binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On binary_expr shift to state 71 + +State 71: +binary_expr -> binary_expr . STAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . DIVIDE binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PERCENT binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . PLUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . MINUS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . LESS_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . GREATER_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . EQUAL_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . NOT_EQUAL binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . AND_AND binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr AND_AND binary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +binary_expr -> binary_expr . BAR_BAR binary_expr [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On STAR shift to state 46 +-- On PLUS shift to state 48 +-- On PERCENT shift to state 50 +-- On NOT_EQUAL shift to state 54 +-- On MINUS shift to state 56 +-- On LESS_EQUAL shift to state 58 +-- On LESS shift to state 60 +-- On GREATER_EQUAL shift to state 62 +-- On GREATER shift to state 64 +-- On EQUAL_EQUAL shift to state 66 +-- On DIVIDE shift to state 52 +-- On THEN reduce production binary_expr -> binary_expr AND_AND binary_expr +-- On TEL reduce production binary_expr -> binary_expr AND_AND binary_expr +-- On SEMICOLON reduce production binary_expr -> binary_expr AND_AND binary_expr +-- On RPAREN reduce production binary_expr -> binary_expr AND_AND binary_expr +-- On NODE reduce production binary_expr -> binary_expr AND_AND binary_expr +-- On EOF reduce production binary_expr -> binary_expr AND_AND binary_expr +-- On ELSE reduce production binary_expr -> binary_expr AND_AND binary_expr +-- On CONST reduce production binary_expr -> binary_expr AND_AND binary_expr +-- On COMMA reduce production binary_expr -> binary_expr AND_AND binary_expr +-- On BAR_BAR reduce production binary_expr -> binary_expr AND_AND binary_expr +-- On AND_AND reduce production binary_expr -> binary_expr AND_AND binary_expr + +State 72: +if_expr -> IF expr . THEN expr ELSE expr [ THEN TEL SEMICOLON RPAREN NODE EOF ELSE CONST COMMA ] +-- On THEN shift to state 73 + +State 73: +if_expr -> IF expr THEN . expr ELSE expr [ THEN TEL SEMICOLON RPAREN NODE EOF ELSE CONST COMMA ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IF shift to state 32 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On if_expr shift to state 41 +-- On expr shift to state 74 +-- On binary_expr shift to state 45 + +State 74: +if_expr -> IF expr THEN expr . ELSE expr [ THEN TEL SEMICOLON RPAREN NODE EOF ELSE CONST COMMA ] +-- On ELSE shift to state 75 + +State 75: +if_expr -> IF expr THEN expr ELSE . expr [ THEN TEL SEMICOLON RPAREN NODE EOF ELSE CONST COMMA ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IF shift to state 32 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On if_expr shift to state 41 +-- On expr shift to state 76 +-- On binary_expr shift to state 45 + +State 76: +if_expr -> IF expr THEN expr ELSE expr . [ THEN TEL SEMICOLON RPAREN NODE EOF ELSE CONST COMMA ] +-- On THEN reduce production if_expr -> IF expr THEN expr ELSE expr +-- On TEL reduce production if_expr -> IF expr THEN expr ELSE expr +-- On SEMICOLON reduce production if_expr -> IF expr THEN expr ELSE expr +-- On RPAREN reduce production if_expr -> IF expr THEN expr ELSE expr +-- On NODE reduce production if_expr -> IF expr THEN expr ELSE expr +-- On EOF reduce production if_expr -> IF expr THEN expr ELSE expr +-- On ELSE reduce production if_expr -> IF expr THEN expr ELSE expr +-- On CONST reduce production if_expr -> IF expr THEN expr ELSE expr +-- On COMMA reduce production if_expr -> IF expr THEN expr ELSE expr + +State 77: +primary_expr -> LPAREN expr . RPAREN [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On RPAREN shift to state 78 + +State 78: +primary_expr -> LPAREN expr RPAREN . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production primary_expr -> LPAREN expr RPAREN +-- On TEL reduce production primary_expr -> LPAREN expr RPAREN +-- On STAR reduce production primary_expr -> LPAREN expr RPAREN +-- On SEMICOLON reduce production primary_expr -> LPAREN expr RPAREN +-- On RPAREN reduce production primary_expr -> LPAREN expr RPAREN +-- On PLUS reduce production primary_expr -> LPAREN expr RPAREN +-- On PERCENT reduce production primary_expr -> LPAREN expr RPAREN +-- On NOT_EQUAL reduce production primary_expr -> LPAREN expr RPAREN +-- On NODE reduce production primary_expr -> LPAREN expr RPAREN +-- On MINUS reduce production primary_expr -> LPAREN expr RPAREN +-- On LESS_EQUAL reduce production primary_expr -> LPAREN expr RPAREN +-- On LESS reduce production primary_expr -> LPAREN expr RPAREN +-- On GREATER_EQUAL reduce production primary_expr -> LPAREN expr RPAREN +-- On GREATER reduce production primary_expr -> LPAREN expr RPAREN +-- On EQUAL_EQUAL reduce production primary_expr -> LPAREN expr RPAREN +-- On EOF reduce production primary_expr -> LPAREN expr RPAREN +-- On ELSE reduce production primary_expr -> LPAREN expr RPAREN +-- On DIVIDE reduce production primary_expr -> LPAREN expr RPAREN +-- On CONST reduce production primary_expr -> LPAREN expr RPAREN +-- On COMMA reduce production primary_expr -> LPAREN expr RPAREN +-- On BAR_BAR reduce production primary_expr -> LPAREN expr RPAREN +-- On AND_AND reduce production primary_expr -> LPAREN expr RPAREN + +State 79: +unary_expr -> MINUS unary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production unary_expr -> MINUS unary_expr +-- On TEL reduce production unary_expr -> MINUS unary_expr +-- On STAR reduce production unary_expr -> MINUS unary_expr +-- On SEMICOLON reduce production unary_expr -> MINUS unary_expr +-- On RPAREN reduce production unary_expr -> MINUS unary_expr +-- On PLUS reduce production unary_expr -> MINUS unary_expr +-- On PERCENT reduce production unary_expr -> MINUS unary_expr +-- On NOT_EQUAL reduce production unary_expr -> MINUS unary_expr +-- On NODE reduce production unary_expr -> MINUS unary_expr +-- On MINUS reduce production unary_expr -> MINUS unary_expr +-- On LESS_EQUAL reduce production unary_expr -> MINUS unary_expr +-- On LESS reduce production unary_expr -> MINUS unary_expr +-- On GREATER_EQUAL reduce production unary_expr -> MINUS unary_expr +-- On GREATER reduce production unary_expr -> MINUS unary_expr +-- On EQUAL_EQUAL reduce production unary_expr -> MINUS unary_expr +-- On EOF reduce production unary_expr -> MINUS unary_expr +-- On ELSE reduce production unary_expr -> MINUS unary_expr +-- On DIVIDE reduce production unary_expr -> MINUS unary_expr +-- On CONST reduce production unary_expr -> MINUS unary_expr +-- On COMMA reduce production unary_expr -> MINUS unary_expr +-- On BAR_BAR reduce production unary_expr -> MINUS unary_expr +-- On AND_AND reduce production unary_expr -> MINUS unary_expr + +State 80: +unary_expr -> NOT unary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production unary_expr -> NOT unary_expr +-- On TEL reduce production unary_expr -> NOT unary_expr +-- On STAR reduce production unary_expr -> NOT unary_expr +-- On SEMICOLON reduce production unary_expr -> NOT unary_expr +-- On RPAREN reduce production unary_expr -> NOT unary_expr +-- On PLUS reduce production unary_expr -> NOT unary_expr +-- On PERCENT reduce production unary_expr -> NOT unary_expr +-- On NOT_EQUAL reduce production unary_expr -> NOT unary_expr +-- On NODE reduce production unary_expr -> NOT unary_expr +-- On MINUS reduce production unary_expr -> NOT unary_expr +-- On LESS_EQUAL reduce production unary_expr -> NOT unary_expr +-- On LESS reduce production unary_expr -> NOT unary_expr +-- On GREATER_EQUAL reduce production unary_expr -> NOT unary_expr +-- On GREATER reduce production unary_expr -> NOT unary_expr +-- On EQUAL_EQUAL reduce production unary_expr -> NOT unary_expr +-- On EOF reduce production unary_expr -> NOT unary_expr +-- On ELSE reduce production unary_expr -> NOT unary_expr +-- On DIVIDE reduce production unary_expr -> NOT unary_expr +-- On CONST reduce production unary_expr -> NOT unary_expr +-- On COMMA reduce production unary_expr -> NOT unary_expr +-- On BAR_BAR reduce production unary_expr -> NOT unary_expr +-- On AND_AND reduce production unary_expr -> NOT unary_expr + +State 81: +unary_expr -> PLUS unary_expr . [ THEN TEL STAR SEMICOLON RPAREN PLUS PERCENT NOT_EQUAL NODE MINUS LESS_EQUAL LESS GREATER_EQUAL GREATER EQUAL_EQUAL EOF ELSE DIVIDE CONST COMMA BAR_BAR AND_AND ] +-- On THEN reduce production unary_expr -> PLUS unary_expr +-- On TEL reduce production unary_expr -> PLUS unary_expr +-- On STAR reduce production unary_expr -> PLUS unary_expr +-- On SEMICOLON reduce production unary_expr -> PLUS unary_expr +-- On RPAREN reduce production unary_expr -> PLUS unary_expr +-- On PLUS reduce production unary_expr -> PLUS unary_expr +-- On PERCENT reduce production unary_expr -> PLUS unary_expr +-- On NOT_EQUAL reduce production unary_expr -> PLUS unary_expr +-- On NODE reduce production unary_expr -> PLUS unary_expr +-- On MINUS reduce production unary_expr -> PLUS unary_expr +-- On LESS_EQUAL reduce production unary_expr -> PLUS unary_expr +-- On LESS reduce production unary_expr -> PLUS unary_expr +-- On GREATER_EQUAL reduce production unary_expr -> PLUS unary_expr +-- On GREATER reduce production unary_expr -> PLUS unary_expr +-- On EQUAL_EQUAL reduce production unary_expr -> PLUS unary_expr +-- On EOF reduce production unary_expr -> PLUS unary_expr +-- On ELSE reduce production unary_expr -> PLUS unary_expr +-- On DIVIDE reduce production unary_expr -> PLUS unary_expr +-- On CONST reduce production unary_expr -> PLUS unary_expr +-- On COMMA reduce production unary_expr -> PLUS unary_expr +-- On BAR_BAR reduce production unary_expr -> PLUS unary_expr +-- On AND_AND reduce production unary_expr -> PLUS unary_expr + +State 82: +eqn -> GUARANTEE IDENT COLON expr . [ TEL SEMICOLON ] +-- On TEL reduce production eqn -> GUARANTEE IDENT COLON expr +-- On SEMICOLON reduce production eqn -> GUARANTEE IDENT COLON expr + +State 83: +eqn -> ASSUME . IDENT COLON expr [ TEL SEMICOLON ] +-- On IDENT shift to state 84 + +State 84: +eqn -> ASSUME IDENT . COLON expr [ TEL SEMICOLON ] +-- On COLON shift to state 85 + +State 85: +eqn -> ASSUME IDENT COLON . expr [ TEL SEMICOLON ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IF shift to state 32 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On if_expr shift to state 41 +-- On expr shift to state 86 +-- On binary_expr shift to state 45 + +State 86: +eqn -> ASSUME IDENT COLON expr . [ TEL SEMICOLON ] +-- On TEL reduce production eqn -> ASSUME IDENT COLON expr +-- On SEMICOLON reduce production eqn -> ASSUME IDENT COLON expr + +State 87: +dbody -> LET separated_nonempty_list(SEMICOLON,ext(eqn)) . TEL [ NODE EOF CONST ] +-- On TEL shift to state 88 + +State 88: +dbody -> LET separated_nonempty_list(SEMICOLON,ext(eqn)) TEL . [ NODE EOF CONST ] +-- On NODE reduce production dbody -> LET separated_nonempty_list(SEMICOLON,ext(eqn)) TEL +-- On EOF reduce production dbody -> LET separated_nonempty_list(SEMICOLON,ext(eqn)) TEL +-- On CONST reduce production dbody -> LET separated_nonempty_list(SEMICOLON,ext(eqn)) TEL + +State 89: +eqn -> lvalue . EQUAL expr [ TEL SEMICOLON ] +-- On EQUAL shift to state 90 + +State 90: +eqn -> lvalue EQUAL . expr [ TEL SEMICOLON ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IF shift to state 32 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On if_expr shift to state 41 +-- On expr shift to state 91 +-- On binary_expr shift to state 45 + +State 91: +eqn -> lvalue EQUAL expr . [ TEL SEMICOLON ] +-- On TEL reduce production eqn -> lvalue EQUAL expr +-- On SEMICOLON reduce production eqn -> lvalue EQUAL expr + +State 92: +separated_nonempty_list(SEMICOLON,ext(eqn)) -> eqn . [ TEL ] +separated_nonempty_list(SEMICOLON,ext(eqn)) -> eqn . SEMICOLON separated_nonempty_list(SEMICOLON,ext(eqn)) [ TEL ] +-- On SEMICOLON shift to state 93 +-- On TEL reduce production separated_nonempty_list(SEMICOLON,ext(eqn)) -> eqn + +State 93: +separated_nonempty_list(SEMICOLON,ext(eqn)) -> eqn SEMICOLON . separated_nonempty_list(SEMICOLON,ext(eqn)) [ TEL ] +-- On IDENT shift to state 22 +-- On GUARANTEE shift to state 23 +-- On ASSUME shift to state 83 +-- On separated_nonempty_list(SEMICOLON,ext(eqn)) shift to state 94 +-- On lvalue shift to state 89 +-- On eqn shift to state 92 + +State 94: +separated_nonempty_list(SEMICOLON,ext(eqn)) -> eqn SEMICOLON separated_nonempty_list(SEMICOLON,ext(eqn)) . [ TEL ] +-- On TEL reduce production separated_nonempty_list(SEMICOLON,ext(eqn)) -> eqn SEMICOLON separated_nonempty_list(SEMICOLON,ext(eqn)) + +State 95: +dbody -> eqn . SEMICOLON [ NODE EOF CONST ] +-- On SEMICOLON shift to state 96 + +State 96: +dbody -> eqn SEMICOLON . [ NODE EOF CONST ] +-- On NODE reduce production dbody -> eqn SEMICOLON +-- On EOF reduce production dbody -> eqn SEMICOLON +-- On CONST reduce production dbody -> eqn SEMICOLON + +State 97: +node_decl -> NODE IDENT LPAREN vars RPAREN RETURNS vars RPAREN var_decl dbody . [ NODE EOF CONST ] +-- On NODE reduce production node_decl -> NODE IDENT LPAREN vars RPAREN RETURNS vars RPAREN var_decl dbody +-- On EOF reduce production node_decl -> NODE IDENT LPAREN vars RPAREN RETURNS vars RPAREN var_decl dbody +-- On CONST reduce production node_decl -> NODE IDENT LPAREN vars RPAREN RETURNS vars RPAREN var_decl dbody + +State 98: +separated_nonempty_list(SEMICOLON,var) -> var . [ RPAREN ] +separated_nonempty_list(SEMICOLON,var) -> var . SEMICOLON separated_nonempty_list(SEMICOLON,var) [ RPAREN ] +-- On SEMICOLON shift to state 99 +-- On RPAREN reduce production separated_nonempty_list(SEMICOLON,var) -> var + +State 99: +separated_nonempty_list(SEMICOLON,var) -> var SEMICOLON . separated_nonempty_list(SEMICOLON,var) [ RPAREN ] +-- On IDENT shift to state 4 +-- On var shift to state 98 +-- On separated_nonempty_list(SEMICOLON,var) shift to state 100 + +State 100: +separated_nonempty_list(SEMICOLON,var) -> var SEMICOLON separated_nonempty_list(SEMICOLON,var) . [ RPAREN ] +-- On RPAREN reduce production separated_nonempty_list(SEMICOLON,var) -> var SEMICOLON separated_nonempty_list(SEMICOLON,var) + +State 101: +loption(separated_nonempty_list(SEMICOLON,var)) -> separated_nonempty_list(SEMICOLON,var) . [ RPAREN ] +-- On RPAREN reduce production loption(separated_nonempty_list(SEMICOLON,var)) -> separated_nonempty_list(SEMICOLON,var) + +State 102: +vars -> loption(separated_nonempty_list(SEMICOLON,var)) . [ RPAREN ] +-- On RPAREN reduce production vars -> loption(separated_nonempty_list(SEMICOLON,var)) + +State 103: +const_decl -> CONST . IDENT COLON typ EQUAL expr [ NODE EOF CONST ] +-- On IDENT shift to state 104 + +State 104: +const_decl -> CONST IDENT . COLON typ EQUAL expr [ NODE EOF CONST ] +-- On COLON shift to state 105 + +State 105: +const_decl -> CONST IDENT COLON . typ EQUAL expr [ NODE EOF CONST ] +-- On REAL shift to state 6 +-- On INT shift to state 7 +-- On BOOL shift to state 8 +-- On typ shift to state 106 + +State 106: +const_decl -> CONST IDENT COLON typ . EQUAL expr [ NODE EOF CONST ] +-- On EQUAL shift to state 107 + +State 107: +const_decl -> CONST IDENT COLON typ EQUAL . expr [ NODE EOF CONST ] +-- On TRUE shift to state 26 +-- On PLUS shift to state 27 +-- On NOT shift to state 28 +-- On MINUS shift to state 29 +-- On LPAREN shift to state 30 +-- On INTVAL shift to state 31 +-- On IF shift to state 32 +-- On IDENT shift to state 33 +-- On FALSE shift to state 35 +-- On unary_expr shift to state 36 +-- On primary_expr shift to state 38 +-- On if_expr shift to state 41 +-- On expr shift to state 108 +-- On binary_expr shift to state 45 + +State 108: +const_decl -> CONST IDENT COLON typ EQUAL expr . [ NODE EOF CONST ] +-- On NODE reduce production const_decl -> CONST IDENT COLON typ EQUAL expr +-- On EOF reduce production const_decl -> CONST IDENT COLON typ EQUAL expr +-- On CONST reduce production const_decl -> CONST IDENT COLON typ EQUAL expr + +State 109: +list(toplevel) -> toplevel . list(toplevel) [ EOF ] +-- On NODE shift to state 1 +-- On CONST shift to state 103 +-- On toplevel shift to state 109 +-- On node_decl shift to state 110 +-- On list(toplevel) shift to state 111 +-- On const_decl shift to state 112 +-- On EOF reduce production list(toplevel) -> + +State 110: +toplevel -> node_decl . [ NODE EOF CONST ] +-- On NODE reduce production toplevel -> node_decl +-- On EOF reduce production toplevel -> node_decl +-- On CONST reduce production toplevel -> node_decl + +State 111: +list(toplevel) -> toplevel list(toplevel) . [ EOF ] +-- On EOF reduce production list(toplevel) -> toplevel list(toplevel) + +State 112: +toplevel -> const_decl . [ NODE EOF CONST ] +-- On NODE reduce production toplevel -> const_decl +-- On EOF reduce production toplevel -> const_decl +-- On CONST reduce production toplevel -> const_decl + +State 113: +file -> list(toplevel) . EOF [ # ] +-- On EOF shift to state 114 + +State 114: +file -> list(toplevel) EOF . [ # ] +-- On # reduce production file -> list(toplevel) EOF + +State 115: +file' -> file . [ # ] +-- On # accept file + diff --git a/frontend/parser.conflicts b/frontend/parser.conflicts new file mode 100644 index 0000000..296156a --- /dev/null +++ b/frontend/parser.conflicts @@ -0,0 +1,32 @@ + +** Conflict (shift/reduce) in state 17. +** Token involved: IDENT +** This state is reached from file after reading: + +NODE IDENT LPAREN vars RPAREN RETURNS vars RPAREN VAR var SEMICOLON + +** The derivations that appear below have the following common factor: +** (The question mark symbol (?) represents the spot where the derivations begin to differ.) + +file +list(toplevel) EOF +toplevel list(toplevel) +node_decl +(?) + +** In state 17, looking ahead at IDENT, reducing production +** nonempty_list(terminated(var,SEMICOLON)) -> var SEMICOLON +** is permitted because of the following sub-derivation: + +NODE IDENT LPAREN vars RPAREN RETURNS vars RPAREN var_decl dbody // lookahead token appears because dbody can begin with IDENT + VAR nonempty_list(terminated(var,SEMICOLON)) // lookahead token is inherited + var SEMICOLON . + +** In state 17, looking ahead at IDENT, shifting is permitted +** because of the following sub-derivation: + +NODE IDENT LPAREN vars RPAREN RETURNS vars RPAREN var_decl dbody + VAR nonempty_list(terminated(var,SEMICOLON)) + var SEMICOLON nonempty_list(terminated(var,SEMICOLON)) + var SEMICOLON + . IDENT COLON typ diff --git a/frontend/parser.mly b/frontend/parser.mly new file mode 100644 index 0000000..9db1bd5 --- /dev/null +++ b/frontend/parser.mly @@ -0,0 +1,221 @@ +%{ +open Ast +%} + +/* tokens */ +/**********/ + +%token BOOL +%token INT +%token REAL +%token PROBE +%token TRUE +%token THEN +%token FALSE +%token IF +%token ELSE +%token NOT +%token AND +%token OR +%token MOD +%token CONST +%token NODE +%token RETURNS +%token VAR +%token LET +%token TEL +%token PRE +%token ASSUME +%token GUARANTEE + +%token LPAREN +%token RPAREN +%token LCURLY +%token RCURLY +%token STAR +%token PLUS +%token MINUS +%token EXCLAIM +%token DIVIDE +%token PERCENT +%token LESS +%token GREATER +%token LESS_EQUAL +%token GREATER_EQUAL +%token EQUAL_EQUAL +%token DIFF +%token AND_AND +%token BAR_BAR +%token SEMICOLON +%token COLON +%token COMMA +%token EQUAL +%token ARROW + +%token <string> IDENT +%token <string> INTVAL + +%token EOF + +/* priorities of binary operators (lowest to highest) */ +%left ARROW +%left OR +%left AND +%left EQUAL DIFF +%left LESS GREATER LESS_EQUAL GREATER_EQUAL +%left PLUS MINUS +%left STAR DIVIDE MOD + + +/* entry-points */ +/****************/ + +%start<Ast.toplevel list> file + + +%% + + +/* toplevel */ +/************/ + +file: t=list(toplevel) EOF { t } + +toplevel: +| d=ext(const_decl) { AST_const_decl d } +| d=ext(node_decl) { AST_node_decl d } + + +/* expressions */ +/***************/ + +primary_expr: +| LPAREN e=expr RPAREN { e } +| e=ext(IDENT) { AST_identifier e } +| e=ext(INTVAL) { AST_int_const e } +| TRUE { AST_bool_const true } +| FALSE { AST_bool_const false } +| e=ext(IDENT) LPAREN l=separated_list(COMMA,ext(expr)) RPAREN + { AST_instance (e, l) } + + +unary_expr: +| e=primary_expr { e } +| o=unary_op e=ext(unary_expr) { AST_unary (o, e) } + +%inline unary_op: +| PLUS { AST_UPLUS } +| MINUS { AST_UMINUS } +| NOT { AST_NOT } +| PRE { AST_PRE } + + +binary_expr: +| e=unary_expr { e } +| e=ext(binary_expr) o=binary_op f=ext(binary_expr) { AST_binary (o, e, f) } + +%inline binary_op: +| STAR { AST_MUL } +| DIVIDE { AST_DIV } +| MOD { AST_MOD } +| PLUS { AST_PLUS } +| MINUS { AST_MINUS } +| LESS { AST_LT } +| GREATER { AST_GT } +| LESS_EQUAL { AST_LE } +| GREATER_EQUAL { AST_GE } +| EQUAL { AST_EQ} +| DIFF { AST_NE } +| AND { AST_AND } +| OR { AST_OR } +| ARROW { AST_ARROW } + +if_expr: +| IF c=ext(expr) THEN t=ext(expr) ELSE e=ext(expr) + { AST_if(c, t, e) } +| e=binary_expr { e } + +expr: +| e=if_expr { e } + +lvalue: +| i=IDENT { i } + + +/* equations */ +/****************/ + +eqn: +| i=ext(lvalue) EQUAL e=ext(expr) + { AST_assign(i, e) } +| ASSUME i=ext(IDENT) COLON e=ext(expr) + { AST_assume(i, e) } +| GUARANTEE i=ext(IDENT) COLON e=ext(expr) + { AST_guarantee(i, e) } + +typ: +| INT { AST_TINT } +| BOOL { AST_TBOOL } +| REAL { AST_TREAL } + +dbody: +| e=ext(eqn) SEMICOLON + { [e] } +| LET l=nonempty_list(terminated(ext(eqn), SEMICOLON)) TEL + { l } + +/* declarations */ + +var: +| p=boption(PROBE) i=ext(IDENT) + { (p, i) } + +vari: +| vn=separated_list(COMMA, var) COLON t=typ + { List.map (fun (p, i) -> (p, i, t)) vn } + +vars: +| v=separated_list(SEMICOLON, vari) + { List.flatten v } + +const_decl: +| CONST i=ext(IDENT) COLON t=typ EQUAL e=ext(expr) SEMICOLON + { (i, t, e) } + +var_decl: +| VAR l=nonempty_list(terminated(vari, SEMICOLON)) + { List.flatten l } + +node_decl: +| NODE id=IDENT + LPAREN v=vars RPAREN + RETURNS LPAREN rv=vars RPAREN + e = dbody + { { name = id; + args = v; + ret = rv; + var = []; + body = e; + } } +| NODE id=IDENT + LPAREN v=vars RPAREN + RETURNS LPAREN rv=vars RPAREN + lv=var_decl + LET b=nonempty_list(terminated(ext(eqn), SEMICOLON)) TEL + { { name = id; + args = v; + ret = rv; + var = lv; + body = b; + } } + + +/* utilities */ +/*************/ + +/* adds extent information to rule */ +%inline ext(X): +| x=X { x, ($startpos, $endpos) } + + +%% diff --git a/libs/mapext.ml b/libs/mapext.ml new file mode 100644 index 0000000..51f41ee --- /dev/null +++ b/libs/mapext.ml @@ -0,0 +1,741 @@ +(* + Cours "Sémantique et Application à la Vérification de programmes" + + Antoine Miné 2014 + Ecole normale supérieure, Paris, France / CNRS / INRIA +*) + +(* + This file is derived from the map.ml file from the OCaml distribution. + Changes are marked with the [AM] symbol. + Based on rev. 10468 2010-05-25 13:29:43Z + + Original copyright follows. +*) + +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the GNU Library General Public License, with *) +(* the special exception on linking described in file ../LICENSE. *) +(* *) +(***********************************************************************) + +module type OrderedType = + sig + type t + val compare: t -> t -> int + end + +module type S = + sig + type key + type +'a t + val empty: 'a t + val is_empty: 'a t -> bool + val mem: key -> 'a t -> bool + val add: key -> 'a -> 'a t -> 'a t + val singleton: key -> 'a -> 'a t + val remove: key -> 'a t -> 'a t + val merge: (key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t + val compare: ('a -> 'a -> int) -> 'a t -> 'a t -> int + val equal: ('a -> 'a -> bool) -> 'a t -> 'a t -> bool + val iter: (key -> 'a -> unit) -> 'a t -> unit + val fold: (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b + val for_all: (key -> 'a -> bool) -> 'a t -> bool + val exists: (key -> 'a -> bool) -> 'a t -> bool + val filter: (key -> 'a -> bool) -> 'a t -> 'a t + val partition: (key -> 'a -> bool) -> 'a t -> 'a t * 'a t + val cardinal: 'a t -> int + val bindings: 'a t -> (key * 'a) list + val min_binding: 'a t -> (key * 'a) + val max_binding: 'a t -> (key * 'a) + val choose: 'a t -> (key * 'a) + val split: key -> 'a t -> 'a t * 'a option * 'a t + val find: key -> 'a t -> 'a + val map: ('a -> 'b) -> 'a t -> 'b t + val mapi: (key -> 'a -> 'b) -> 'a t -> 'b t + + + (* [AM] additions by Antoine Mine' *) + + val of_list: (key * 'a) list -> 'a t + + val map2: (key -> 'a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t + val iter2: (key -> 'a -> 'b -> unit) -> 'a t -> 'b t -> unit + val fold2: (key -> 'a -> 'b -> 'c -> 'c) -> 'a t -> 'b t -> 'c -> 'c + val for_all2: (key -> 'a -> 'b -> bool) -> 'a t -> 'b t -> bool + val exists2: (key -> 'a -> 'b -> bool) -> 'a t -> 'b t -> bool + + val map2z: (key -> 'a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t + val iter2z: (key -> 'a -> 'a -> unit) -> 'a t -> 'a t -> unit + val fold2z: (key -> 'a -> 'a -> 'b -> 'b) -> 'a t -> 'a t -> 'b -> 'b + val for_all2z: (key -> 'a -> 'a -> bool) -> 'a t -> 'a t -> bool + val exists2z: (key -> 'a -> 'a -> bool) -> 'a t -> 'a t -> bool + + val map2o: (key -> 'a -> 'c) -> (key -> 'b -> 'c) -> (key -> 'a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t + val iter2o: (key -> 'a -> unit) -> (key -> 'b -> unit) -> (key -> 'a -> 'b -> unit) -> 'a t -> 'b t -> unit + val fold2o: (key -> 'a -> 'c -> 'c) -> (key -> 'b -> 'c -> 'c) -> (key -> 'a -> 'b -> 'c -> 'c) -> 'a t -> 'b t -> 'c -> 'c + val for_all2o: (key -> 'a -> bool) -> (key -> 'b -> bool) -> (key -> 'a -> 'b -> bool) -> 'a t -> 'b t -> bool + val exists2o: (key -> 'a -> bool) -> (key -> 'b -> bool) -> (key -> 'a -> 'b -> bool) -> 'a t -> 'b t -> bool + + val map2zo: (key -> 'a -> 'a) -> (key -> 'a -> 'a) -> (key -> 'a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t + val iter2zo: (key -> 'a -> unit) -> (key -> 'a -> unit) -> (key -> 'a -> 'a -> unit) -> 'a t -> 'a t -> unit + val fold2zo: (key -> 'a -> 'b -> 'b) -> (key -> 'a -> 'b -> 'b) -> (key -> 'a -> 'a -> 'b -> 'b) -> 'a t -> 'a t -> 'b -> 'b + val for_all2zo: (key -> 'a -> bool) -> (key -> 'a -> bool) -> (key -> 'a -> 'a -> bool) -> 'a t -> 'a t -> bool + val exists2zo: (key -> 'a -> bool) -> (key -> 'a -> bool) -> (key -> 'a -> 'a -> bool) -> 'a t -> 'a t -> bool + + val map_slice: (key -> 'a -> 'a) -> 'a t -> key -> key -> 'a t + val iter_slice: (key -> 'a -> unit) -> 'a t -> key -> key -> unit + val fold_slice: (key -> 'a -> 'b -> 'b) -> 'a t -> key -> key -> 'b -> 'b + val for_all_slice: (key -> 'a -> bool) -> 'a t -> key -> key -> bool + val exists_slice: (key -> 'a -> bool) -> 'a t -> key -> key -> bool + + val key_equal: 'a t -> 'a t -> bool + val key_subset: 'a t -> 'a t -> bool + + val find_greater: key -> 'a t -> key * 'a + val find_less: key -> 'a t -> key * 'a + val find_greater_equal: key -> 'a t -> key * 'a + val find_less_equal: key -> 'a t -> key * 'a + + end + +module Make(Ord: OrderedType) = (struct + + type key = Ord.t + + type 'a t = + Empty + | Node of 'a t * key * 'a * 'a t * int + + let height = function + Empty -> 0 + | Node(_,_,_,_,h) -> h + + let create l x d r = + let hl = height l and hr = height r in + Node(l, x, d, r, (if hl >= hr then hl + 1 else hr + 1)) + + let singleton x d = Node(Empty, x, d, Empty, 1) + + let bal l x d r = + let hl = match l with Empty -> 0 | Node(_,_,_,_,h) -> h in + let hr = match r with Empty -> 0 | Node(_,_,_,_,h) -> h in + if hl > hr + 2 then begin + match l with + Empty -> invalid_arg "Mapext.bal" + | Node(ll, lv, ld, lr, _) -> + if height ll >= height lr then + create ll lv ld (create lr x d r) + else begin + match lr with + Empty -> invalid_arg "Mapext.bal" + | Node(lrl, lrv, lrd, lrr, _)-> + create (create ll lv ld lrl) lrv lrd (create lrr x d r) + end + end else if hr > hl + 2 then begin + match r with + Empty -> invalid_arg "Mapext.bal" + | Node(rl, rv, rd, rr, _) -> + if height rr >= height rl then + create (create l x d rl) rv rd rr + else begin + match rl with + Empty -> invalid_arg "Mapext.bal" + | Node(rll, rlv, rld, rlr, _) -> + create (create l x d rll) rlv rld (create rlr rv rd rr) + end + end else + Node(l, x, d, r, (if hl >= hr then hl + 1 else hr + 1)) + + let empty = Empty + + let is_empty = function Empty -> true | _ -> false + + let rec add x data = function + Empty -> + Node(Empty, x, data, Empty, 1) + | Node(l, v, d, r, h) -> + let c = Ord.compare x v in + if c = 0 then + Node(l, x, data, r, h) + else if c < 0 then + bal (add x data l) v d r + else + bal l v d (add x data r) + + let rec find x = function + Empty -> + raise Not_found + | Node(l, v, d, r, _) -> + let c = Ord.compare x v in + if c = 0 then d + else find x (if c < 0 then l else r) + + let rec mem x = function + Empty -> + false + | Node(l, v, d, r, _) -> + let c = Ord.compare x v in + c = 0 || mem x (if c < 0 then l else r) + + let rec min_binding = function + Empty -> raise Not_found + | Node(Empty, x, d, r, _) -> (x, d) + | Node(l, x, d, r, _) -> min_binding l + + let rec max_binding = function + Empty -> raise Not_found + | Node(l, x, d, Empty, _) -> (x, d) + | Node(l, x, d, r, _) -> max_binding r + + let rec remove_min_binding = function + Empty -> invalid_arg "Mapext.remove_min_elt" + | Node(Empty, x, d, r, _) -> r + | Node(l, x, d, r, _) -> bal (remove_min_binding l) x d r + + let merge t1 t2 = + match (t1, t2) with + (Empty, t) -> t + | (t, Empty) -> t + | (_, _) -> + let (x, d) = min_binding t2 in + bal t1 x d (remove_min_binding t2) + + let rec remove x = function + Empty -> + Empty + | Node(l, v, d, r, h) -> + let c = Ord.compare x v in + if c = 0 then + merge l r + else if c < 0 then + bal (remove x l) v d r + else + bal l v d (remove x r) + + let rec iter f = function + Empty -> () + | Node(l, v, d, r, _) -> + iter f l; f v d; iter f r + + let rec map f = function + Empty -> + Empty + | Node(l, v, d, r, h) -> + let l' = map f l in + let d' = f d in + let r' = map f r in + Node(l', v, d', r', h) + + let rec mapi f = function + Empty -> + Empty + | Node(l, v, d, r, h) -> + let l' = mapi f l in + let d' = f v d in + let r' = mapi f r in + Node(l', v, d', r', h) + + let rec fold f m accu = + match m with + Empty -> accu + | Node(l, v, d, r, _) -> + fold f r (f v d (fold f l accu)) + + (* [AM] changed to call p in the key order *) + let rec for_all p = function + Empty -> true + | Node(l, v, d, r, _) -> for_all p l && p v d && for_all p r + + (* [AM] changed to call p in the key order *) + let rec exists p = function + Empty -> false + | Node(l, v, d, r, _) -> exists p l || p v d || exists p r + + (* [AM] changed to call p in the key order *) + let filter p s = + fold (fun k d a -> if p k d then add k d a else a) s Empty + + let partition p s = + let rec part (t, f as accu) = function + | Empty -> accu + | Node(l, v, d, r, _) -> + part (part (if p v d then (add v d t, f) else (t, add v d f)) l) r in + part (Empty, Empty) s + + (* Same as create and bal, but no assumptions are made on the + relative heights of l and r. *) + + let rec join l v d r = + match (l, r) with + (Empty, _) -> add v d r + | (_, Empty) -> add v d l + | (Node(ll, lv, ld, lr, lh), Node(rl, rv, rd, rr, rh)) -> + if lh > rh + 2 then bal ll lv ld (join lr v d r) else + if rh > lh + 2 then bal (join l v d rl) rv rd rr else + create l v d r + + (* Merge two trees l and r into one. + All elements of l must precede the elements of r. + No assumption on the heights of l and r. *) + + let concat t1 t2 = + match (t1, t2) with + (Empty, t) -> t + | (t, Empty) -> t + | (_, _) -> + let (x, d) = min_binding t2 in + join t1 x d (remove_min_binding t2) + + let concat_or_join t1 v d t2 = + match d with + | Some d -> join t1 v d t2 + | None -> concat t1 t2 + + let rec split x = function + Empty -> + (Empty, None, Empty) + | Node(l, v, d, r, _) -> + let c = Ord.compare x v in + if c = 0 then (l, Some d, r) + else if c < 0 then + let (ll, pres, rl) = split x l in (ll, pres, join rl v d r) + else + let (lr, pres, rr) = split x r in (join l v d lr, pres, rr) + + let rec merge f s1 s2 = + match (s1, s2) with + (Empty, Empty) -> Empty + | (Node (l1, v1, d1, r1, h1), _) when h1 >= height s2 -> + let (l2, d2, r2) = split v1 s2 in + concat_or_join (merge f l1 l2) v1 (f v1 (Some d1) d2) (merge f r1 r2) + | (_, Node (l2, v2, d2, r2, h2)) -> + let (l1, d1, r1) = split v2 s1 in + concat_or_join (merge f l1 l2) v2 (f v2 d1 (Some d2)) (merge f r1 r2) + | _ -> + assert false + + type 'a enumeration = End | More of key * 'a * 'a t * 'a enumeration + + let rec cons_enum m e = + match m with + Empty -> e + | Node(l, v, d, r, _) -> cons_enum l (More(v, d, r, e)) + + let compare cmp m1 m2 = + let rec compare_aux e1 e2 = + match (e1, e2) with + (End, End) -> 0 + | (End, _) -> -1 + | (_, End) -> 1 + | (More(v1, d1, r1, e1), More(v2, d2, r2, e2)) -> + let c = Ord.compare v1 v2 in + if c <> 0 then c else + let c = cmp d1 d2 in + if c <> 0 then c else + compare_aux (cons_enum r1 e1) (cons_enum r2 e2) + in compare_aux (cons_enum m1 End) (cons_enum m2 End) + + let equal cmp m1 m2 = + let rec equal_aux e1 e2 = + match (e1, e2) with + (End, End) -> true + | (End, _) -> false + | (_, End) -> false + | (More(v1, d1, r1, e1), More(v2, d2, r2, e2)) -> + Ord.compare v1 v2 = 0 && cmp d1 d2 && + equal_aux (cons_enum r1 e1) (cons_enum r2 e2) + in equal_aux (cons_enum m1 End) (cons_enum m2 End) + + let rec cardinal = function + Empty -> 0 + | Node(l, _, _, r, _) -> cardinal l + 1 + cardinal r + + let rec bindings_aux accu = function + Empty -> accu + | Node(l, v, d, r, _) -> bindings_aux ((v, d) :: bindings_aux accu r) l + + let bindings s = + bindings_aux [] s + + let choose = min_binding + + + + (* [AM] additions by Antoine Mine' *) + (* ******************************* *) + + + let of_list l = + List.fold_left (fun acc (k,x) -> add k x acc) empty l + + + (* similar to split, but returns unbalanced trees *) + let rec cut k = function + Empty -> Empty,None,Empty + | Node (l1,k1,d1,r1,h1) -> + let c = Ord.compare k k1 in + if c < 0 then + let l2,d2,r2 = cut k l1 in (l2,d2,Node (r2,k1,d1,r1,h1)) + else if c > 0 then + let l2,d2,r2 = cut k r1 in (Node (l1,k1,d1,l2,h1),d2,r2) + else (l1,Some d1,r1) + + + (* binary operations that fail on maps with different keys *) + + (* functions are called in increasing key order *) + + let rec map2 f m1 m2 = + match m1 with + | Empty -> if m2 = Empty then Empty else invalid_arg "Mapext.map2" + | Node (l1,k,d1,r1,h1) -> + match cut k m2 with + | l2, Some d2, r2 -> + Node (map2 f l1 l2, k, f k d1 d2, map2 f r1 r2, h1) + | _, None, _ -> invalid_arg "Mapext.map2" + + let rec iter2 f m1 m2 = + match m1 with + | Empty -> if m2 = Empty then () else invalid_arg "Mapext.iter2" + | Node (l1,k,d1,r1,h1) -> + match cut k m2 with + | l2, Some d2, r2 -> iter2 f l1 l2; f k d1 d2; iter2 f r1 r2 + | _, None, _ -> invalid_arg "Mapext.iter2" + + let rec fold2 f m1 m2 acc = + match m1 with + | Empty -> if m2 = Empty then acc else invalid_arg "Mapext.fold2" + | Node (l1,k,d1,r1,h1) -> + match cut k m2 with + | l2, Some d2, r2 -> + fold2 f r1 r2 (f k d1 d2 (fold2 f l1 l2 acc)) + | _, None, _ -> invalid_arg "Mapext.fold2" + + let rec for_all2 f m1 m2 = + match m1 with + | Empty -> if m2 = Empty then true else invalid_arg "Mapext.for_all2" + | Node (l1,k,d1,r1,h1) -> + match cut k m2 with + | l2, Some d2, r2 -> + for_all2 f l1 l2 && f k d1 d2 && for_all2 f r1 r2 + | _, None, _ -> invalid_arg "Mapext.for_all2" + + let rec exists2 f m1 m2 = + match m1 with + | Empty -> if m2 = Empty then false else invalid_arg "Mapext.exists2" + | Node (l1,k,d1,r1,h1) -> + match cut k m2 with + | l2, Some d2, r2 -> + exists2 f l1 l2 || f k d1 d2 || exists2 f r1 r2 + | _, None, _ -> invalid_arg "Mapext.exists2" + + + (* as above, but ignore physically equal subtrees + - for map, assumes: f k d d = d + - for iter, assumes: f k d d has no effect + - for fold, assumes: k f d d acc = acc + - for for_all, assumes: f k d d = true + - for exists, assumes: f k d d = false + *) + + let rec map2z f m1 m2 = + if m1 == m2 then m1 else + match m1 with + | Empty -> if m2 = Empty then Empty else invalid_arg "Mapext.map2z" + | Node (l1,k,d1,r1,h1) -> + match cut k m2 with + | l2, Some d2, r2 -> + let d = if d1 == d2 then d1 else f k d1 d2 in + Node (map2z f l1 l2, k, d, map2z f r1 r2, h1) + | _, None, _ -> invalid_arg "Mapext.map2z" + + let rec iter2z f m1 m2 = + if m1 == m2 then () else + match m1 with + | Empty -> if m2 = Empty then () else invalid_arg "Mapext.iter2z" + | Node (l1,k,d1,r1,h1) -> + match cut k m2 with + | l2, Some d2, r2 -> + iter2z f l1 l2; (if d1 != d2 then f k d1 d2); iter2z f r1 r2 + | _, None, _ -> invalid_arg "Mapext.iter2z" + + let rec fold2z f m1 m2 acc = + if m1 == m2 then acc else + match m1 with + | Empty -> if m2 = Empty then acc else invalid_arg "Mapext.fold2z" + | Node (l1,k,d1,r1,h1) -> + match cut k m2 with + | l2, Some d2, r2 -> + let acc = fold2z f l1 l2 acc in + let acc = if d1 == d2 then acc else f k d1 d2 acc in + fold2z f r1 r2 acc + | _, None, _ -> invalid_arg "Mapext.fold2z" + + let rec for_all2z f m1 m2 = + (m1 == m2) || + (match m1 with + | Empty -> if m2 = Empty then true else invalid_arg "Mapext.for_all2z" + | Node (l1,k,d1,r1,h1) -> + match cut k m2 with + | l2, Some d2, r2 -> + (for_all2z f l1 l2) && + (d1 == d2 || f k d1 d2) && + (for_all2z f r1 r2) + | _, None, _ -> invalid_arg "Mapext.for_all2z" + ) + + let rec exists2z f m1 m2 = + (m1 != m2) && + (match m1 with + | Empty -> if m2 = Empty then false else invalid_arg "Mapext.exists2z" + | Node (l1,k,d1,r1,h1) -> + match cut k m2 with + | l2, Some d2, r2 -> + (exists2z f l1 l2) || + (d1 != d2 && f k d1 d2) || + (exists2z f r1 r2) + | _, None, _ -> invalid_arg "Mapext.exists2z" + ) + + + (* as above, but allow maps with different keys *) + + let rec map2o f1 f2 f m1 m2 = + match m1 with + | Empty -> mapi f2 m2 + | Node (l1,k,d1,r1,h1) -> + let l2, d2, r2 = cut k m2 in + let l = map2o f1 f2 f l1 l2 in + let d = match d2 with None -> f1 k d1 | Some d2 -> f k d1 d2 in + let r = map2o f1 f2 f r1 r2 in + join l k d r + + let rec iter2o f1 f2 f m1 m2 = + match m1 with + | Empty -> iter f2 m2 + | Node (l1,k,d1,r1,h1) -> + let l2, d2, r2 = cut k m2 in + iter2o f1 f2 f l1 l2; + (match d2 with None -> f1 k d1 | Some d2 -> f k d1 d2); + iter2o f1 f2 f r1 r2 + + let rec fold2o f1 f2 f m1 m2 acc = + match m1 with + | Empty -> fold f2 m2 acc + | Node (l1,k,d1,r1,h1) -> + let l2, d2, r2 = cut k m2 in + let acc = fold2o f1 f2 f l1 l2 acc in + let acc = match d2 with + | None -> f1 k d1 acc | Some d2 -> f k d1 d2 acc + in + fold2o f1 f2 f r1 r2 acc + + let rec for_all2o f1 f2 f m1 m2 = + match m1 with + | Empty -> for_all f2 m2 + | Node (l1,k,d1,r1,h1) -> + let l2, d2, r2 = cut k m2 in + (for_all2o f1 f2 f l1 l2) && + (match d2 with None -> f1 k d1 | Some d2 -> f k d1 d2) && + (for_all2o f1 f2 f r1 r2) + + let rec exists2o f1 f2 f m1 m2 = + match m1 with + | Empty -> exists f2 m2 + | Node (l1,k,d1,r1,h1) -> + let l2, d2, r2 = cut k m2 in + (exists2o f1 f2 f l1 l2) || + (match d2 with None -> f1 k d1 | Some d2 -> f k d1 d2) || + (exists2o f1 f2 f r1 r2) + + + (* all together now *) + + let rec map2zo f1 f2 f m1 m2 = + if m1 == m2 then m1 else + match m1 with + | Empty -> mapi f2 m2 + | Node (l1,k,d1,r1,h1) -> + let l2, d2, r2 = cut k m2 in + let l = map2zo f1 f2 f l1 l2 in + let d = match d2 with + | None -> f1 k d1 + | Some d2 -> if d1 == d2 then d1 else f k d1 d2 + in + let r = map2zo f1 f2 f r1 r2 in + join l k d r + + let rec iter2zo f1 f2 f m1 m2 = + if m1 == m2 then () else + match m1 with + | Empty -> iter f2 m2 + | Node (l1,k,d1,r1,h1) -> + let l2, d2, r2 = cut k m2 in + iter2zo f1 f2 f l1 l2; + (match d2 with + | None -> f1 k d1 + | Some d2 -> if d1 != d2 then f k d1 d2); + iter2zo f1 f2 f r1 r2 + + let rec fold2zo f1 f2 f m1 m2 acc = + if m1 == m2 then acc else + match m1 with + | Empty -> fold f2 m2 acc + | Node (l1,k,d1,r1,h1) -> + let l2, d2, r2 = cut k m2 in + let acc = fold2zo f1 f2 f l1 l2 acc in + let acc = match d2 with + | None -> f1 k d1 acc + | Some d2 -> if d1 == d2 then acc else f k d1 d2 acc + in + fold2zo f1 f2 f r1 r2 acc + + let rec for_all2zo f1 f2 f m1 m2 = + (m1 == m2) || + (match m1 with + | Empty -> for_all f2 m2 + | Node (l1,k,d1,r1,h1) -> + let l2, d2, r2 = cut k m2 in + (for_all2zo f1 f2 f l1 l2) && + (match d2 with None -> f1 k d1 | Some d2 -> d1 == d2 || f k d1 d2) && + (for_all2zo f1 f2 f r1 r2) + ) + + let rec exists2zo f1 f2 f m1 m2 = + (m1 != m2) && + (match m1 with + | Empty -> exists f2 m2 + | Node (l1,k,d1,r1,h1) -> + let l2, d2, r2 = cut k m2 in + (exists2zo f1 f2 f l1 l2) || + (match d2 with None -> f1 k d1 | Some d2 -> d1 != d2 && f k d1 d2) || + (exists2zo f1 f2 f r1 r2) + ) + + + (* iterators limited to keys between two bounds *) + + let rec map_slice f m lo hi = + match m with + | Empty -> Empty + | Node (l,k,d,r,h) -> + let c1, c2 = Ord.compare k lo, Ord.compare k hi in + let l = if c1 > 0 then map_slice f l lo k else l in + let d = if c1 >= 0 && c2 <= 0 then f k d else d in + let r = if c2 < 0 then map_slice f r k hi else r in + Node (l,k,d,r,h) + + let rec iter_slice f m lo hi = + match m with + | Empty -> () + | Node (l,k,d,r,_) -> + let c1, c2 = Ord.compare k lo, Ord.compare k hi in + if c1 > 0 then iter_slice f l lo k; + if c1 >= 0 && c2 <= 0 then f k d; + if c2 < 0 then iter_slice f r k hi + + let rec fold_slice f m lo hi acc = + match m with + | Empty -> acc + | Node (l,k,d,r,_) -> + let c1, c2 = Ord.compare k lo, Ord.compare k hi in + let acc = if c1 > 0 then fold_slice f l lo k acc else acc in + let acc = if c1 >= 0 && c2 <= 0 then f k d acc else acc in + if c2 < 0 then fold_slice f r k hi acc else acc + + let rec for_all_slice f m lo hi = + match m with + | Empty -> true + | Node (l,k,d,r,_) -> + let c1, c2 = Ord.compare k lo, Ord.compare k hi in + (c1 <= 0 || for_all_slice f l lo k) && + (c1 < 0 || c2 > 0 || f k d) && + (c2 >= 0 || for_all_slice f r k hi) + + let rec exists_slice f m lo hi = + match m with + | Empty -> false + | Node (l,k,d,r,_) -> + let c1, c2 = Ord.compare k lo, Ord.compare k hi in + (c1 > 0 && exists_slice f l lo k) || + (c1 >= 0 && c2 <= 0 && f k d) || + (c2 < 0 && exists_slice f r k hi) + + + (* key set comparison *) + + let rec key_equal m1 m2 = + (m1 == m2) || + (match m1 with + | Empty -> m2 = Empty + | Node (l1, k, _, r1, _) -> + match cut k m2 with + | _, None, _ -> false + | l2, Some _, r2 -> key_equal l1 l2 && key_equal r1 r2 + ) + + let rec key_subset m1 m2 = + (m1 == m2) || + (match m1 with + | Empty -> true + | Node (l1, k, _, r1, _) -> + match cut k m2 with + | _, None, _ -> false + | l2, Some _, r2 -> key_subset l1 l2 && key_subset r1 r2 + ) + + + (* nagivation *) + + let find_greater_equal k m = + let rec aux m found = match m with + | Empty -> (match found with None -> raise Not_found | Some x -> x) + | Node (l, kk, d, r, _) -> + let c = Ord.compare k kk in + if c = 0 then kk, d else + if c > 0 then aux r found else + aux l (Some (kk, d)) + in + aux m None + + let find_greater k m = + let rec aux m found = match m with + | Empty -> (match found with None -> raise Not_found | Some x -> x) + | Node (l, kk, d, r, _) -> + let c = Ord.compare k kk in + if c >= 0 then aux r found else + aux l (Some (kk, d)) + in + aux m None + + let find_less_equal k m = + let rec aux m found = match m with + | Empty -> (match found with None -> raise Not_found | Some x -> x) + | Node (l, kk, d, r, _) -> + let c = Ord.compare k kk in + if c = 0 then kk, d else + if c < 0 then aux l found else + aux r (Some (kk, d)) + in + aux m None + + let find_less k m = + let rec aux m found = match m with + | Empty -> (match found with None -> raise Not_found | Some x -> x) + | Node (l, kk, d, r, _) -> + let c = Ord.compare k kk in + if c <= 0 then aux l found else + aux r (Some (kk, d)) + in + aux m None + + +end: S with type key = Ord.t) diff --git a/libs/mapext.mli b/libs/mapext.mli new file mode 100644 index 0000000..abee2c0 --- /dev/null +++ b/libs/mapext.mli @@ -0,0 +1,473 @@ +(* + Cours "Sémantique et Application à la Vérification de programmes" + + Antoine Miné 2014 + Ecole normale supérieure, Paris, France / CNRS / INRIA +*) + +(* + This file is derived from the mapi.ml file from the OCaml distribution. + Changes are marked with the [AM] symbol. + Based on rev. 10632 2010-07-24 14:16:58Z. + + Original copyright follows. +*) + + +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1996 Institut National de Recherche en Informatique et *) +(* en Automatique. All rights reserved. This file is distributed *) +(* under the terms of the GNU Library General Public License, with *) +(* the special exception on linking described in file ../LICENSE. *) +(* *) +(***********************************************************************) + +(* $Id: mapext.mli,v 1.1 2014-02-24 16:25:06 mine Exp $ *) + +(** Association tables over ordered types. + + This module implements applicative association tables, also known as + finite maps or dictionaries, given a total ordering function + over the keys. + All operations over maps are purely applicative (no side-effects). + The implementation uses balanced binary trees, and therefore searching + and insertion take time logarithmic in the size of the map. +*) + +module type OrderedType = + sig + type t + (** The type of the map keys. *) + val compare : t -> t -> int + (** A total ordering function over the keys. + This is a two-argument function [f] such that + [f e1 e2] is zero if the keys [e1] and [e2] are equal, + [f e1 e2] is strictly negative if [e1] is smaller than [e2], + and [f e1 e2] is strictly positive if [e1] is greater than [e2]. + Example: a suitable ordering function is the generic structural + comparison function {!Pervasives.compare}. *) + end +(** Input signature of the functor {!Map.Make}. *) + +module type S = + sig + type key + (** The type of the map keys. *) + + type (+'a) t + (** The type of maps from type [key] to type ['a]. *) + + val empty: 'a t + (** The empty map. *) + + val is_empty: 'a t -> bool + (** Test whether a map is empty or not. *) + + val mem: key -> 'a t -> bool + (** [mem x m] returns [true] if [m] contains a binding for [x], + and [false] otherwise. *) + + val add: key -> 'a -> 'a t -> 'a t + (** [add x y m] returns a map containing the same bindings as + [m], plus a binding of [x] to [y]. If [x] was already bound + in [m], its previous binding disappears. *) + + val singleton: key -> 'a -> 'a t + (** [singleton x y] returns the one-element map that contains a binding [y] + for [x]. + @since 3.12.0 + *) + + val remove: key -> 'a t -> 'a t + (** [remove x m] returns a map containing the same bindings as + [m], except for [x] which is unbound in the returned map. *) + + val merge: + (key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t + (** [merge f m1 m2] computes a map whose keys is a subset of keys of [m1] + and of [m2]. The presence of each such binding, and the corresponding + value, is determined with the function [f]. + @since 3.12.0 + *) + + val compare: ('a -> 'a -> int) -> 'a t -> 'a t -> int + (** Total ordering between maps. The first argument is a total ordering + used to compare data associated with equal keys in the two maps. *) + + val equal: ('a -> 'a -> bool) -> 'a t -> 'a t -> bool + (** [equal cmp m1 m2] tests whether the maps [m1] and [m2] are + equal, that is, contain equal keys and associate them with + equal data. [cmp] is the equality predicate used to compare + the data associated with the keys. *) + + val iter: (key -> 'a -> unit) -> 'a t -> unit + (** [iter f m] applies [f] to all bindings in map [m]. + [f] receives the key as first argument, and the associated value + as second argument. The bindings are passed to [f] in increasing + order with respect to the ordering over the type of the keys. *) + + val fold: (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b + (** [fold f m a] computes [(f kN dN ... (f k1 d1 a)...)], + where [k1 ... kN] are the keys of all bindings in [m] + (in increasing order), and [d1 ... dN] are the associated data. *) + + val for_all: (key -> 'a -> bool) -> 'a t -> bool + (* [AM] now guarantees the evaluation order *) + (** [for_all p m] checks if all the bindings of the map + satisfy the predicate [p]. + The predicate [p] is tested on bindings according to the key order. + @since 3.12.0 + *) + + val exists: (key -> 'a -> bool) -> 'a t -> bool + (* [AM] now guarantees the evaluation order *) + (** [exists p m] checks if at least one binding of the map + satisfy the predicate [p]. + The predicate [p] is tested on bindings according to the key order. + @since 3.12.0 + *) + + val filter: (key -> 'a -> bool) -> 'a t -> 'a t + (* [AM] now guarantees the evaluation order *) + (** [filter p m] returns the map with all the bindings in [m] + that satisfy predicate [p]. + The predicate [p] is tested on bindings according to the key order. + @since 3.12.0 + *) + + val partition: (key -> 'a -> bool) -> 'a t -> 'a t * 'a t + (** [partition p m] returns a pair of maps [(m1, m2)], where + [m1] contains all the bindings of [s] that satisfy the + predicate [p], and [m2] is the map with all the bindings of + [s] that do not satisfy [p]. + @since 3.12.0 + *) + + val cardinal: 'a t -> int + (** Return the number of bindings of a map. + @since 3.12.0 + *) + + val bindings: 'a t -> (key * 'a) list + (** Return the list of all bindings of the given map. + The returned list is sorted in increasing order with respect + to the ordering [Ord.compare], where [Ord] is the argument + given to {!Map.Make}. + @since 3.12.0 + *) + + val min_binding: 'a t -> (key * 'a) + (** Return the smallest binding of the given map + (with respect to the [Ord.compare] ordering), or raise + [Not_found] if the map is empty. + @since 3.12.0 + *) + + val max_binding: 'a t -> (key * 'a) + (** Same as {!Map.S.min_binding}, but returns the largest binding + of the given map. + @since 3.12.0 + *) + + val choose: 'a t -> (key * 'a) + (** Return one binding of the given map, or raise [Not_found] if + the map is empty. Which binding is chosen is unspecified, + but equal bindings will be chosen for equal maps. + @since 3.12.0 + *) + + val split: key -> 'a t -> 'a t * 'a option * 'a t + (** [split x m] returns a triple [(l, data, r)], where + [l] is the map with all the bindings of [m] whose key + is strictly less than [x]; + [r] is the map with all the bindings of [m] whose key + is strictly greater than [x]; + [data] is [None] if [m] contains no binding for [x], + or [Some v] if [m] binds [v] to [x]. + @since 3.12.0 + *) + + val find: key -> 'a t -> 'a + (** [find x m] returns the current binding of [x] in [m], + or raises [Not_found] if no such binding exists. *) + + val map: ('a -> 'b) -> 'a t -> 'b t + (** [map f m] returns a map with same domain as [m], where the + associated value [a] of all bindings of [m] has been + replaced by the result of the application of [f] to [a]. + The bindings are passed to [f] in increasing order + with respect to the ordering over the type of the keys. *) + + val mapi: (key -> 'a -> 'b) -> 'a t -> 'b t + (** Same as {!Map.S.map}, but the function receives as arguments both the + key and the associated value for each binding of the map. *) + + + (* [AM] additions *) + + (** {2 Additional functions} *) + + val of_list: (key * 'a) list -> 'a t + (** [of_list l] converts an association list to a map. *) + + val map2: (key -> 'a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t + (** [map2 f m1 m2] is similar to [map] but applies [f] to pairs + of bindings [a1] from [m1] and [a2] from [m2] corresponding to + the same key to construct a new map with the same key set. + [m1] and [m2] must have the same key sets. + The binging are passed to [f] in increasing order of key. *) + + val iter2: (key -> 'a -> 'b -> unit) -> 'a t -> 'b t -> unit + (** [iter2 f m1 m2] is similar to [map] but applies [f] to pairs + of bindings [a1] from [m1] and [a2] from [m2] corresponding to + the same key. + [m1] and [m2] must have the same key sets. + The binging are passed to [f] in increasing order of key. *) + + val fold2: (key -> 'a -> 'b -> 'c -> 'c) -> 'a t -> 'b t -> 'c -> 'c + (** [fold2 f m1 m2 x] is similar to [fold] but applies [f] to pairs + of bindings [a1] from [m1] and [a2] from [m2] corresponding to + the same key. + [m1] and [m2] must have the same key sets. + The bindings are passed to [f] in increasing order of keys. *) + + val for_all2: (key -> 'a -> 'b -> bool) -> 'a t -> 'b t -> bool + (** [for_all2 f m1 m2] is similar to [for_all] but applies [f] to pairs + of bindings [a1] from [m1] and [a2] from [m2] corresponding to + the same key. + [m1] and [m2] must have the same key sets. + The bindings are passed to [f] in increasing order of keys. *) + + val exists2: (key -> 'a -> 'b -> bool) -> 'a t -> 'b t -> bool + (** [exists2 f m1 m2] is similar to [exists] but applies [f] to pairs + of bindings [a1] from [m1] and [a2] from [m2] corresponding to + the same key. + [m1] and [m2] must have the same key sets. + The bindings are passed to [f] in increasing order of keys. *) + + + + + val map2z: (key -> 'a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t + (** [map2z f m1 m2] is similar to [map2 f m1 m2], but physically + equal subtrees are put unchanged into the result instead of + being traversed. + This is more efficient than [map2], and equivalent if [f] is + side-effect free and idem-potent ([f k a a = a]). + [m1] and [m2] must have the same key sets. + The bindings are passed to [f] in increasing order of keys. *) + + val iter2z: (key -> 'a -> 'a -> unit) -> 'a t -> 'a t -> unit + (** [iter2z f m1 m2] is similar to [iter2 f m1 m2], but physically + equal subtrees are ignored. + This is more efficient than [iter2], and equivalent if + [f k a a] has no effect. + [m1] and [m2] must have the same key sets. + The bindings are passed to [f] in increasing order of keys. *) + + val fold2z: (key -> 'a -> 'a -> 'b -> 'b) -> 'a t -> 'a t -> 'b -> 'b + (** [fold2z f m1 m2 a] is similar to [fold2 f m1 m2 a], but physically + equal subtrees are ignored. + This is more efficient than [fold2], and equivalent if + [f k a a x = x] and has no effect. + [m1] and [m2] must have the same key sets. + The bindings are passed to [f] in increasing order of keys. *) + + val for_all2z: (key -> 'a -> 'a -> bool) -> 'a t -> 'a t -> bool + (** [for_all2z f m1 m2] is similar to [for_all2 f m1 m2], but returns + [true] for physically equal subtrees without traversing them. + This is more efficient than [for_all2z], and equivalent if + [f k a a = true] and has no effect. + [m1] and [m2] must have the same key sets. + The bindings are passed to [f] in increasing order of keys. *) + + val exists2z: (key -> 'a -> 'a -> bool) -> 'a t -> 'a t -> bool + (** [exists2z f m1 m2] is similar to [exists2 f m1 m2], but returns + [false] for physically equal subtrees without traversing them. + This is more efficient than [exists2z], and equivalent if + [f k a a = false] and has no effect. + [m1] and [m2] must have the same key sets. + The bindings are passed to [f] in increasing order of keys. *) + + + + + val map2o: (key -> 'a -> 'c) -> (key -> 'b -> 'c) -> (key -> 'a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t + (** [map2o f1 f2 f m1 m2] is similar to [map2 f m1 m2], but + accepts maps defined over different sets of keys. + To get a new binding, [f1] is used for keys appearing only + in [m1], [f2] for keys appearing only in [m2], and [f] for + keys appearing in both maps. + The returned map has bindings for all keys appearing in either + [m1] or [m2]. + The bindings are passed to [f], [f1], [f2] in increasing order of keys. *) + + val iter2o: (key -> 'a -> unit) -> (key -> 'b -> unit) -> (key -> 'a -> 'b -> unit) -> 'a t -> 'b t -> unit + (** [iter2o f1 f2 f m1 m2] is similar to [iter2 f m1 m2], but + accepts maps defined over different sets of keys. + [f1] is called for keys appearing only in [m1], + [f2] for keys appearing only in [m2], + and [f] for keys appearing in both maps. + The bindings are passed to [f], [f1], [f2] in increasing order of keys. *) + + val fold2o: (key -> 'a -> 'c -> 'c) -> (key -> 'b -> 'c -> 'c) -> (key -> 'a -> 'b -> 'c -> 'c) -> 'a t -> 'b t -> 'c -> 'c + (** [fold2o f1 f2 f m1 m2 a] is similar to [fold2 f m1 m2 a], but + accepts maps defined over different sets of keys. + [f1] is called for keys appearing only in [m1], + [f2] for keys appearing only in [m2], + and [f] for keys appearing in both maps. + The bindings are passed to [f], [f1], [f2] in increasing order of keys. *) + + val for_all2o: (key -> 'a -> bool) -> (key -> 'b -> bool) -> (key -> 'a -> 'b -> bool) -> 'a t -> 'b t -> bool + (** [for_all2o f1 f2 f m1 m2] is similar to [for_all2 f m1 m2], but + accepts maps defined over different sets of keys. + [f1] is called for keys appearing only in [m1], + [f2] for keys appearing only in [m2], + and [f] for keys appearing in both maps. + The bindings are passed to [f], [f1], [f2] in increasing order of keys. *) + + val exists2o: (key -> 'a -> bool) -> (key -> 'b -> bool) -> (key -> 'a -> 'b -> bool) -> 'a t -> 'b t -> bool + (** [fexists2o f1 f2 f m1 m2] is similar to [fexists2 f m1 m2], but + accepts maps defined over different sets of keys. + [f1] is called for keys appearing only in [m1], + [f2] for keys appearing only in [m2], + and [f] for keys appearing in both maps. + The bindings are passed to [f], [f1], [f2] in increasing order of keys. *) + + + + val map2zo: (key -> 'a -> 'a) -> (key -> 'a -> 'a) -> (key -> 'a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t + (** [map2zo f1 f2 f m1 m2] is similar to [map2o f1 f2 f m1 m2] but, + similary to [map2z], [f] is not called on physically equal + subtrees. + This is more efficient than [map2o], and equivalent if [f] is + side-effect free and idem-potent ([f k a a = a]). + The returned map has bindings for all keys appearing in either + [m1] or [m2]. + The bindings are passed to [f], [f1], [f2] in increasing order of keys. *) + + val iter2zo: (key -> 'a -> unit) -> (key -> 'a -> unit) -> (key -> 'a -> 'a -> unit) -> 'a t -> 'a t -> unit + (** [iter2zo f1 f2 f m1 m2] is similar to [iter2o f1 f2 f m1 m2] but, + similary to [iter2z], [f] is not called on physically equal + subtrees. + This is more efficient than [iter2o], and equivalent if [f] is + side-effect free. + The bindings are passed to [f], [f1], [f2] in increasing order of keys. *) + + val fold2zo: (key -> 'a -> 'b -> 'b) -> (key -> 'a -> 'b -> 'b) -> (key -> 'a -> 'a -> 'b -> 'b) -> 'a t -> 'a t -> 'b -> 'b + (** [fold2zo f1 f2 f m1 m2 a] is similar to [fold2o f1 f2 f m1 m2 a] but, + similary to [fold2z], [f] is not called on physically equal + subtrees. + This is more efficient than [fold2o], and equivalent if + [f k a a x = x] and has no side-effect. + The bindings are passed to [f], [f1], [f2] in increasing order of keys. *) + + val for_all2zo: (key -> 'a -> bool) -> (key -> 'a -> bool) -> (key -> 'a -> 'a -> bool) -> 'a t -> 'a t -> bool + (** [for_all2zo f1 f2 f m1 m2] is similar to [for_all2o f1 f2 f m1 m2] but, + similary to [for_all2z], [f] is not called on physically equal + subtrees. + This is more efficient than [for_all2o], and equivalent if + [f k a a = true] and has no side-effect. + The bindings are passed to [f], [f1], [f2] in increasing order of keys. *) + + val exists2zo: (key -> 'a -> bool) -> (key -> 'a -> bool) -> (key -> 'a -> 'a -> bool) -> 'a t -> 'a t -> bool + (** [exists2zo f1 f2 f m1 m2] is similar to [exists2o f1 f2 f m1 m2] but, + similary to [exists2z], [f] is not called on physically equal + subtrees. + This is more efficient than [exists2o], and equivalent if + [f k a a = false] and has no side-effect. + The bindings are passed to [f], [f1], [f2] in increasing order of keys. *) + + val map_slice: (key -> 'a -> 'a) -> 'a t -> key -> key -> 'a t + (** [map_slice f m k1 k2] is similar to [map f m], but only applies + [f] to bindings with key greater or equal to [k1] and smaller + or equal to [k2] to construct the returned map. Bindings with + keys outside this range in [m] are put unchanged in the result. + It is as if, outside this range, [f k a = a] and has no effect. + The result has the same key set as [m]. + The bindings are passed to [f] in increasing order of keys, + between [k1] and [k2]. *) + + val iter_slice: (key -> 'a -> unit) -> 'a t -> key -> key -> unit + (** [iter_slice f m k1 k2] is similar to [iter f m], but only calls + [f] on bindings with key greater or equal to [k1] and smaller + or equal to [k2]. + It is as if, outside this range, [f k a] has no effect. + The bindings are passed to [f] in increasing order of keys, + between [k1] and [k2]. *) + + val fold_slice: (key -> 'a -> 'b -> 'b) -> 'a t -> key -> key -> 'b -> 'b + (** [fold_slice f m k1 k2 a] is similar to [fold f m], but only calls + [f] on bindings with key greater or equal to [k1] and smaller + or equal to [k2]. + It is as if, outside this range, [f k a x = x] and has no effect. + The bindings are passed to [f] in increasing order of keys, + between [k1] and [k2]. *) + + val for_all_slice: (key -> 'a -> bool) -> 'a t -> key -> key -> bool + (** [for_all_slice f m k1 k2 a] is similar to [for_all f m], but only calls + [f] on bindings with key greater or equal to [k1] and smaller + or equal to [k2]. + It is as if, outside this range, [f k a = true] and has no effect. + The bindings are passed to [f] in increasing order of keys, + between [k1] and [k2]. *) + + val exists_slice: (key -> 'a -> bool) -> 'a t -> key -> key -> bool + (** [exists_slice f m k1 k2 a] is similar to [exists f m], but only calls + [f] on bindings with key greater or equal to [k1] and smaller + or equal to [k2]. + It is as if, outside this range, [f k a = false] and has no effect. + The bindings are passed to [f] in increasing order of keys, + between [k1] and [k2]. *) + + val key_equal: 'a t -> 'a t -> bool + (** [key_equal m1 m2] returns true if [m1] and [m2] are defined + over exactly the same set of keys (but with possibly different + values). + *) + + val key_subset: 'a t -> 'a t -> bool + (** [key_equal m1 m2] returns true if [m1] is defined on a subset of + the keys of [m2] (but with possibly different values). + *) + + val find_greater: key -> 'a t -> key * 'a + (** [find_greater k m] returns the binding (key and value) in [m] + with key strictly greater than [k] and as small as possible. + Raises [Not_found] if [m] has no binding for a key strictly greater + than [k]. + *) + + val find_less: key -> 'a t -> key * 'a + (** [find_less k m] returns the binding (key and value) in [m] + with key strictly less than [k] and as large as possible. + Raises [Not_found] if [m] has no binding for a key strictly less + than [k]. + *) + + val find_greater_equal: key -> 'a t -> key * 'a + (** [find_greater_euql k m] returns the binding (key and value) in [m] + with key greater or equal to [k] and as small as possible. + Raises [Not_found] if [m] has no binding for a key greater or equal + to [k]. + *) + + val find_less_equal: key -> 'a t -> key * 'a + (** [find_less_equal k m] returns the binding (key and value) in [m] + with key less or equal to [k] and as large as possible. + Raises [Not_found] if [m] has no binding for a key less or equal + to [k]. + *) + + + end +(** Output signature of the functor {!Map.Make}. *) + +module Make (Ord : OrderedType) : S with type key = Ord.t +(** Functor building an implementation of the map structure + given a totally ordered type. *) diff --git a/libs/util.ml b/libs/util.ml new file mode 100644 index 0000000..30cf5bf --- /dev/null +++ b/libs/util.ml @@ -0,0 +1,20 @@ +exception TypeError + +module VarMap = Mapext.Make(String) + +let rec fix equal f s = + let fs = f s in + if equal fs s + then fs + else fix equal f fs + +let (@@) f x = f x + +let print_list x l = + Format.printf "%s: " x; + let rec aux = function + | [] -> () + | [a] -> Format.printf "%s" a + | p::q -> Format.printf "%s, " p; aux q + in + Format.printf "["; aux l; Format.printf "]@."; @@ -0,0 +1,25 @@ +open Ast + +(* command line options *) +let dump = ref false +let ifile = ref "" + +let usage = "usage: analyzer [options] file.scade" + +let options = [ + "--dump", Arg.Set dump, "Dump program source."; +] + +let () = + Arg.parse options (fun f -> ifile := f) usage; + + if !ifile = "" then begin + Format.eprintf "No input file...@."; + exit 1 + end; + + let prog = File_parser.parse_file !ifile in + if !dump then Ast_printer.print_prog Format.std_formatter prog; + () (* nothing to do yet ... *) + + |