diff --git a/bootstrap/bin/hocc/aplr.ml b/bootstrap/bin/hocc/aplr.ml index 7031212f4..51e2c1540 100644 --- a/bootstrap/bin/hocc/aplr.ml +++ b/bootstrap/bin/hocc/aplr.ml @@ -75,7 +75,10 @@ let remergeable_actions states remergeables frontiers spines = | None, Some (symbol_index, action_set) -> begin (* All states in the mergeable set must either have an empty action set or identical - * nonempty action set. *) + * nonempty action set. Note that these are post-conflict-resolution action sets; were + * they pre-conflict-resolution action sets, the equivalent remergeability test would + * require identical dominant actions (or identical [possibly unresolvable] action + * sets). *) match reduces_only action_set with | false -> remergeables, frontiers, NotRemergeable spines | true -> begin diff --git a/bootstrap/bin/hocc/conf.ml b/bootstrap/bin/hocc/conf.ml index 5eea1986c..3d1b4d8d1 100644 --- a/bootstrap/bin/hocc/conf.ml +++ b/bootstrap/bin/hocc/conf.ml @@ -29,15 +29,12 @@ let pp_gc gc formatter = | No -> "No" ) -type remerge = - | Default of bool - | Explicit of bool - type t = { verbose: bool; warn: bool; text: bool; hocc: bool; + yacc: bool; algorithm: algorithm; resolve_opt: bool option; remerge_opt: bool option; @@ -49,13 +46,14 @@ type t = { dstdir_opt: Path.t option; } -let pp {verbose; warn; text; hocc; algorithm; resolve_opt; remerge_opt; gc; hemlock; ocaml; +let pp {verbose; warn; text; hocc; yacc; algorithm; resolve_opt; remerge_opt; gc; hemlock; ocaml; srcdir_opt; module_opt; dstdir_opt} formatter = formatter |> Fmt.fmt "{verbose=" |> Bool.pp verbose |> Fmt.fmt "; warn=" |> Bool.pp warn |> Fmt.fmt "; text=" |> Bool.pp text |> Fmt.fmt "; hocc=" |> Bool.pp hocc + |> Fmt.fmt "; yacc=" |> Bool.pp yacc |> Fmt.fmt "; algorithm=" |> pp_algorithm algorithm |> Fmt.fmt "; resolve_opt=" |> Option.pp Bool.pp resolve_opt |> Fmt.fmt "; remerge_opt=" |> Option.pp Bool.pp remerge_opt @@ -72,6 +70,7 @@ let default = { warn=false; text=false; hocc=false; + yacc=false; algorithm=Aplr; resolve_opt=None; remerge_opt=None; @@ -91,14 +90,15 @@ let resolve algorithm resolve_opt = let remerge algorithm remerge_opt = match algorithm, remerge_opt with - | _, Some remerge -> Explicit remerge + | _, Some remerge + -> remerge | Aplr, None - -> Default true | Ielr, None - | Lr, None | Pgm, None + -> true + | Lr, None | Lalr, None - -> Default false + -> false let usage error = let exit_code, formatter = match error with @@ -115,8 +115,10 @@ Parameters: -w[arn] : Warn about unused grammar constructs. -txt | -text : Write a detailed automaton description in plain text format to "/hocc/.txt". - -hmh | -hocc : Write a complete grammar specification in hocc format to + -hmh | -hocc : Write a complete grammar specification in Hocc format to "/hocc/.hmh". + -y[acc] : Write a complete grammar specification in Yacc format to + "/hocc/.y". -a[lgorithm] : Use the specified orithm for generating an automaton. Defaults to aplr. - aplr: Adequacy Preservation LR(1) @@ -127,7 +129,8 @@ Parameters: -r[esolve] (yes|no) : Control conflict resolution enablement. Defaults to yes for aplr/ielr/lr algorithms, no for pgm/lalr algorithms. -[re]m[erge] (yes|no) : Control compatible state subgraph remerging enablement. - Defaults to yes for aplr algorithm, no otherwise. + Defaults to yes for aplr/ielr/pgm algorithms, no for + lr/lalr algorithms. -g[c] (pre|post|no) : Control unreachable state garbage collection enablement and ordering relative to remerging. Defaults to post-remerging. @@ -213,6 +216,7 @@ let of_argv argv = | "-w" | "-warn" -> f {t with warn=true} argv (succ i) | "-txt" | "-text" -> f {t with text=true} argv (succ i) | "-hmh" | "-hocc" -> f {t with hocc=true} argv (succ i) + | "-y" | "-yacc" -> f {t with yacc=true} argv (succ i) | "-a" | "-algorithm" -> begin let algorithm = match Bytes.to_string_replace (arg_arg argv i) with | "aplr" -> Aplr @@ -329,6 +333,9 @@ let text {text; _} = let hocc {hocc; _} = hocc +let yacc {yacc; _} = + yacc + let algorithm {algorithm; _} = algorithm diff --git a/bootstrap/bin/hocc/conf.mli b/bootstrap/bin/hocc/conf.mli index 9c7c9f2bc..6ae9b7bba 100644 --- a/bootstrap/bin/hocc/conf.mli +++ b/bootstrap/bin/hocc/conf.mli @@ -14,10 +14,6 @@ type gc = | PostRemerge (** Perform unreachable state garbage collection after potentially remerging. *) | No (** Do not perform unreachable state garbage collection. *) -type remerge = - | Default of bool (** Default; no remerge parameter specified. *) - | Explicit of bool (** Explicit remerge parameter specified. *) - val pp_algorithm: algorithm -> (module Fmt.Formatter) -> (module Fmt.Formatter) (** [pp_algorithm algorithm] formats [algorithm]. *) @@ -39,7 +35,10 @@ val text: t -> bool (** [text t] returns true if a plain-text automaton description is to be generated. *) val hocc: t -> bool -(** [hocc t] returns true if a hocc-format grammar specification is to be generated. *) +(** [hocc t] returns true if a Hocc-format grammar specification is to be generated. *) + +val yacc: t -> bool +(** [yacc t] returns true if a Yacc-format grammar specification is to be generated. *) val algorithm: t -> algorithm (** [algorithm t] returns the algorithm to be used when generating the automaton. *) @@ -50,9 +49,8 @@ val resolve: t -> bool val gc: t -> gc (** [gc t] returns whether/when to perform unreachable state garbage collection. *) -val remerge: t -> remerge -(** [remerge t] returns a [Default]/[Explicit] remerging parameter, true if remerging of equivalent - split states is enabled. *) +val remerge: t -> bool +(** [remerge t] returns true if remerging of equivalent split states is enabled. *) val hemlock: t -> bool (** [hemlock t] returns true if a Hemlock-based parser is to be generated. *) diff --git a/bootstrap/bin/hocc/description.ml b/bootstrap/bin/hocc/description.ml index 031d98c85..6dc866b44 100644 --- a/bootstrap/bin/hocc/description.ml +++ b/bootstrap/bin/hocc/description.ml @@ -239,78 +239,70 @@ let generate_txt conf io Spec.{algorithm; precs; symbols; prods; states; _} = ) |> Fmt.fmt "Tokens" |> Fmt.fmt "\n" |> (fun formatter -> - Symbols.symbols_fold ~init:formatter - ~f:(fun formatter (Symbol.{name; alias; stype; prec; first; follow; _} as symbol) -> - match Symbol.is_token symbol with - | false -> formatter - | true -> begin - formatter - |> Fmt.fmt " " |> Fmt.fmt "token " - |> Fmt.fmt name - |> (fun formatter -> - match alias with - | None -> formatter - | Some alias -> formatter |> Fmt.fmt " " |> String.pp alias - ) - |> (fun formatter -> - match SymbolType.is_explicit stype with - | false -> formatter - | true -> - formatter |> Fmt.fmt " of " |> Fmt.fmt (SymbolType.to_string stype) - ) - |> (fun formatter -> - match prec with - | None -> formatter - | Some prec -> formatter |> Fmt.fmt " " |> pp_prec precs prec - ) - |> Fmt.fmt "\n" - |> Fmt.fmt " First: " - |> pp_symbol_set first - |> Fmt.fmt "\n" - |> Fmt.fmt " Follow: " - |> pp_symbol_set follow - |> Fmt.fmt "\n" - end + Symbols.tokens_fold ~init:formatter + ~f:(fun formatter Symbol.{name; alias; stype; prec; first; follow; _} -> + formatter + |> Fmt.fmt " " |> Fmt.fmt "token " + |> Fmt.fmt name + |> (fun formatter -> + match alias with + | None -> formatter + | Some alias -> formatter |> Fmt.fmt " " |> String.pp alias + ) + |> (fun formatter -> + match SymbolType.is_explicit stype with + | false -> formatter + | true -> + formatter |> Fmt.fmt " of " |> Fmt.fmt (SymbolType.to_string stype) + ) + |> (fun formatter -> + match prec with + | None -> formatter + | Some prec -> formatter |> Fmt.fmt " " |> pp_prec precs prec + ) + |> Fmt.fmt "\n" + |> Fmt.fmt " First: " + |> pp_symbol_set first + |> Fmt.fmt "\n" + |> Fmt.fmt " Follow: " + |> pp_symbol_set follow + |> Fmt.fmt "\n" ) symbols ) |> Fmt.fmt "Non-terminals" |> Fmt.fmt "\n" |> (fun formatter -> - Symbols.symbols_fold ~init:formatter - ~f:(fun formatter (Symbol.{name; start; stype; prods; first; follow; _} as symbol) -> - match Symbol.is_nonterm symbol with - | false -> formatter - | true -> begin - formatter - |> Fmt.fmt " " - |> Fmt.fmt (match start with - | true -> "start " - | false -> "nonterm " - ) - |> Fmt.fmt name - |> (fun formatter -> - match SymbolType.is_explicit stype with - | false -> formatter - | true -> - formatter |> Fmt.fmt " of " |> Fmt.fmt (SymbolType.to_string stype) - ) - |> Fmt.fmt "\n" - |> Fmt.fmt " First: " - |> pp_symbol_set first - |> Fmt.fmt "\n" - |> Fmt.fmt " Follow: " - |> pp_symbol_set follow - |> Fmt.fmt "\n" - |> Fmt.fmt " Productions\n" - |> (fun formatter -> - Array.fold ~init:formatter - ~f:(fun formatter prod -> - formatter - |> Fmt.fmt " " - |> pp_prod prod - |> Fmt.fmt "\n" - ) prods - ) - end + Symbols.nonterms_fold ~init:formatter + ~f:(fun formatter Symbol.{name; start; stype; prods; first; follow; _} -> + formatter + |> Fmt.fmt " " + |> Fmt.fmt (match start with + | true -> "start " + | false -> "nonterm " + ) + |> Fmt.fmt name + |> (fun formatter -> + match SymbolType.is_explicit stype with + | false -> formatter + | true -> + formatter |> Fmt.fmt " of " |> Fmt.fmt (SymbolType.to_string stype) + ) + |> Fmt.fmt "\n" + |> Fmt.fmt " First: " + |> pp_symbol_set first + |> Fmt.fmt "\n" + |> Fmt.fmt " Follow: " + |> pp_symbol_set follow + |> Fmt.fmt "\n" + |> Fmt.fmt " Productions\n" + |> (fun formatter -> + Array.fold ~init:formatter + ~f:(fun formatter prod -> + formatter + |> Fmt.fmt " " + |> pp_prod prod + |> Fmt.fmt "\n" + ) prods + ) ) symbols ) |> Fmt.fmt states_algorithm |> Fmt.fmt " States" diff --git a/bootstrap/bin/hocc/grammar.ml b/bootstrap/bin/hocc/grammar.ml index 430ba3acd..3c5db0ea5 100644 --- a/bootstrap/bin/hocc/grammar.ml +++ b/bootstrap/bin/hocc/grammar.ml @@ -2,26 +2,240 @@ open Basis open! Basis.Rudiments let generate_hocc io Spec.{precs; symbols; _} = - let io = io.log |> Fmt.fmt "hocc: Generating hocc report\n" |> Io.with_log io in + let io = io.log |> Fmt.fmt "hocc: Generating Hocc report\n" |> Io.with_log io in io.hocc |> Fmt.fmt "hocc\n" |> (fun formatter -> Precs.fold_prec_sets ~init:formatter ~f:(fun formatter prec_set -> - formatter |> PrecSet.src_fmt prec_set + formatter |> PrecSet.hocc_fmt prec_set ) precs ) |> (fun formatter -> - Symbols.symbols_fold ~init:formatter ~f:(fun formatter symbol -> - match Symbol.is_token symbol && not (Symbol.is_synthetic symbol) with - | false -> formatter - | true -> formatter |> Symbols.src_fmt precs symbol symbols + Symbols.tokens_fold ~init:formatter ~f:(fun formatter symbol -> + match Symbol.is_synthetic symbol with + | true -> formatter + | false -> formatter |> Symbols.hocc_fmt precs symbol symbols ) symbols ) |> (fun formatter -> - Symbols.symbols_fold ~init:formatter ~f:(fun formatter symbol -> - match Symbol.is_nonterm symbol && not (Symbol.is_synthetic symbol) with - | false -> formatter - | true -> formatter |> Symbols.src_fmt precs symbol symbols + Symbols.nonterms_fold ~init:formatter ~f:(fun formatter symbol -> + match Symbol.is_synthetic symbol with + | true -> formatter + | false -> formatter |> Symbols.hocc_fmt precs symbol symbols ) symbols ) |> Io.with_hocc io + +let generate_yacc io Spec.{precs; symbols; _} = + let io = io.log |> Fmt.fmt "hocc: Generating Yacc report\n" |> Io.with_log io in + let nstarts = Symbols.nonterms_fold ~init:0L ~f:(fun nstarts ({start; _} as symbol) -> + nstarts + (Bool.to_uns (start && not (Symbol.is_synthetic symbol))) + ) symbols in + io.yacc + |> Fmt.fmt "%{\n" + |> Fmt.fmt "%}\n\n" + |> (fun formatter -> + Precs.fold_prec_sets_right ~init:formatter ~f:(fun formatter {index; names; assoc; _} -> + formatter + |> Fmt.fmt ( + match assoc with + | None -> "%precedence" + | Some Left -> "%left" + | Some Right -> "%right" + | Some Nonassoc -> "%nonassoc" + ) + |> Fmt.fmt " " + |> Fmt.fmt (String.join ~sep:" " (Array.to_list names)) + |> (fun formatter -> + Symbols.tokens_fold ~init:formatter ~f:(fun formatter {name; prec; _} -> + match prec with + | None -> formatter + | Some {prec_set_index; _} -> begin + let PrecSet.{index=i; _} = Precs.prec_set_of_prec_index prec_set_index precs in + match i = index with + | false -> formatter + | true -> formatter |> Fmt.fmt " " |> Fmt.fmt name + end + ) symbols + ) + |> Fmt.fmt "\n" + ) precs + ) + |> Fmt.fmt "\n" + |> (fun formatter -> + Symbols.tokens_fold ~init:formatter ~f:(fun formatter {name; stype; alias; _} -> + match SymbolType.is_synthetic stype with + | true -> formatter + | false -> begin + formatter + |> Fmt.fmt "%token " + |> Fmt.fmt name + |> (fun formatter -> + match alias with + | None -> formatter + | Some alias -> formatter |> Fmt.fmt " \"" |> Fmt.fmt alias |> Fmt.fmt "\"" + ) + |> Fmt.fmt "\n" + end + ) symbols + ) + |> (fun formatter -> + match nstarts with + | 0L -> not_reached () + | 1L -> formatter + | _ -> begin + formatter + |> Fmt.fmt "\n" + |> (fun formatter -> + Symbols.nonterms_fold ~init:formatter + ~f:(fun formatter ({name; start; _} as symbol) -> + match start && not (Symbol.is_synthetic symbol) with + | false -> formatter + | true -> begin + formatter + |> Fmt.fmt "%token HOCC_PSEUDO_START_" |> Fmt.fmt name |> Fmt.fmt "\n" + end + ) symbols + ) + end + ) + |> Fmt.fmt "\n%%\n\n" + |> (fun formatter -> + match nstarts with + | 0L -> not_reached () + | 1L -> begin + formatter + |> (fun formatter -> + Symbols.nonterms_fold ~init:formatter ~f:(fun formatter ({name; start; _} as symbol) -> + match start && not (Symbol.is_synthetic symbol) with + | false -> formatter + | true -> formatter |> Fmt.fmt "%start " |> Fmt.fmt name |> Fmt.fmt ";\n" + ) symbols + ) + end + | _ -> begin + formatter + |> Fmt.fmt "%start hocc-pseudo-start;\n" + |> Fmt.fmt "\n" + |> Fmt.fmt "hocc-pseudo-start:\n" + |> (fun formatter -> + let formatter, _first = + Symbols.nonterms_fold ~init:(formatter, true) + ~f:(fun (formatter, first) ({name; start; _} as symbol) -> + let formatter, first = + match start && not (Symbol.is_synthetic symbol) with + | false -> formatter, first + | true -> begin + let formatter = + formatter + |> (fun formatter -> + match first with + | true -> formatter |> Fmt.fmt " " + | false -> formatter |> Fmt.fmt "| " + ) + |> Fmt.fmt "HOCC_PSEUDO_START_" |> Fmt.fmt name + |> Fmt.fmt " " |> Fmt.fmt name |> Fmt.fmt ";\n" + in + formatter, false + end + in + formatter, first + ) symbols in + formatter + ) + |> Fmt.fmt ";\n" + end + ) + |> (fun formatter -> + Symbols.nonterms_fold ~init:formatter + ~f:(fun formatter ({name; prods; _} as symbol) -> + match Symbol.is_synthetic symbol with + | true -> formatter + | false -> begin + let has_epsilon_prod = Array.for_any ~f:(fun Prod.{rhs_indexes; _} -> + Array.is_empty rhs_indexes + ) prods in + formatter + |> Fmt.fmt "\n" + |> Fmt.fmt name |> Fmt.fmt " :\n" + |> (fun formatter -> + match has_epsilon_prod with + | false -> formatter + | true -> begin + Array.fold ~init:formatter ~f:(fun formatter Prod.{rhs_indexes; prec; _} -> + formatter + |> (fun formatter -> + match Array.length rhs_indexes with + | 0L -> begin + formatter |> Fmt.fmt " /* empty */" + |> (fun formatter -> + match prec with + | None -> formatter + | Some {name_index; prec_set_index} -> begin + let prec_set = Precs.prec_set_of_prec_index prec_set_index precs in + let name = PrecSet.name_of_name_index name_index prec_set in + formatter |> Fmt.fmt " %prec " |> Fmt.fmt name + end + ) + |> Fmt.fmt "\n" + end + | _ -> formatter + ) + ) prods + end + ) + |> (fun formatter -> + let formatter, _first = + Array.fold ~init:(formatter, not has_epsilon_prod) + ~f:(fun (formatter, first) Prod.{rhs_indexes; prec; _} -> + let formatter = + formatter + |> (fun formatter -> + match Array.length rhs_indexes with + | 0L -> formatter + | _ -> begin + formatter + |> (fun formatter -> + match first with + | true -> formatter |> Fmt.fmt " " + | false -> formatter |> Fmt.fmt "|" + ) + |> (fun formatter -> + Array.fold ~init:formatter ~f:(fun formatter rhs_index -> + let Symbol.{name; alias; _} = + Symbols.symbol_of_symbol_index rhs_index symbols in + formatter + |> Fmt.fmt " " + |> (fun formatter -> + match alias with + | None -> formatter |> Fmt.fmt name + | Some alias -> + formatter |> Fmt.fmt "\"" |> Fmt.fmt alias |> Fmt.fmt "\"" + ) + ) rhs_indexes + ) + |> (fun formatter -> + match prec with + | None -> formatter + | Some {name_index; prec_set_index} -> begin + let prec_set = + Precs.prec_set_of_prec_index prec_set_index precs in + let name = PrecSet.name_of_name_index name_index prec_set in + formatter |> Fmt.fmt " %prec " |> Fmt.fmt name + end + ) + |> Fmt.fmt "\n" + end + ) + in + formatter, false + ) prods + in + formatter + ) + |> Fmt.fmt ";\n" + end + ) symbols + ) + |> Fmt.fmt "\n%%\n" + |> Io.with_yacc io diff --git a/bootstrap/bin/hocc/grammar.mli b/bootstrap/bin/hocc/grammar.mli index bb5d0de64..f986ebe31 100644 --- a/bootstrap/bin/hocc/grammar.mli +++ b/bootstrap/bin/hocc/grammar.mli @@ -1,4 +1,7 @@ -(** hocc grammar generation. *) +(** Hocc/Yacc grammar generation. *) val generate_hocc: Io.t -> Spec.t -> Io.t -(** [generate_hocc conf io spec] integrates a hocc representation of [spec]'s grammar into [io]. *) +(** [generate_hocc io spec] integrates a Hocc representation of [spec]'s grammar into [io]. *) + +val generate_yacc: Io.t -> Spec.t -> Io.t +(** [generate_yacc io spec] integrates a Yacc representation of [spec]'s grammar into [io]. *) diff --git a/bootstrap/bin/hocc/hocc.ml b/bootstrap/bin/hocc/hocc.ml index 1cca60218..6f41444f6 100644 --- a/bootstrap/bin/hocc/hocc.ml +++ b/bootstrap/bin/hocc/hocc.ml @@ -52,6 +52,10 @@ let _ = | false -> io | true -> Grammar.generate_hocc io spec in + let io = match Conf.yacc conf with + | false -> io + | true -> Grammar.generate_yacc io spec + in let nconflicts = Spec.conflicts spec in let conflicts = nconflicts <> 0L in let exit_code = 0 in diff --git a/bootstrap/bin/hocc/io.ml b/bootstrap/bin/hocc/io.ml index fc5f8f3a9..f68bd619a 100644 --- a/bootstrap/bin/hocc/io.ml +++ b/bootstrap/bin/hocc/io.ml @@ -8,6 +8,7 @@ type t = { log: (module Fmt.Formatter); txt: (module Fmt.Formatter); hocc: (module Fmt.Formatter); + yacc: (module Fmt.Formatter); hmi: (module Fmt.Formatter); hm: (module Fmt.Formatter); mli: (module Fmt.Formatter); @@ -74,6 +75,11 @@ let init_hocc conf = | false -> File.Fmt.sink | true -> String.Fmt.empty +let init_yacc conf = + match Conf.yacc conf with + | false -> File.Fmt.sink + | true -> String.Fmt.empty + let init_hmi conf hmhi = match Conf.hemlock conf, hmhi with | false, _ @@ -103,12 +109,13 @@ let init conf = let log = init_log conf in let txt = init_txt conf in let hocc = init_hocc conf in + let yacc = init_yacc conf in let hmi = init_hmi conf hmhi in let hm = init_hm conf in let mli = init_mli conf hmhi in let ml = init_ml conf in - {err; hmhi; hmh; log; txt; hocc; hmi; hm; mli; ml} + {err; hmhi; hmh; log; txt; hocc; yacc; hmi; hm; mli; ml} let open_outfile_as_formatter ~is_report ~err path = let _ = match is_report with @@ -134,16 +141,17 @@ let fini_formatter ?(is_report=false) conf conflicts ~err ~log formatter suffix end | false -> log, formatter -let fini conf conflicts ({err; log; txt; hocc; hmi; hm; mli; ml; _} as t) = +let fini conf conflicts ({err; log; txt; hocc; yacc; hmi; hm; mli; ml; _} as t) = let log, txt = fini_formatter ~is_report:true conf conflicts ~err ~log txt ".txt" in let log, hocc = fini_formatter ~is_report:true conf conflicts ~err ~log hocc ".hmh" in + let log, yacc = fini_formatter ~is_report:true conf conflicts ~err ~log yacc ".y" in let log, hmi = fini_formatter conf conflicts ~err ~log hmi ".hmi" in let log, hm = fini_formatter conf conflicts ~err ~log hm ".hm" in let log, mli = fini_formatter conf conflicts ~err ~log mli ".mli" in let log, ml = fini_formatter conf conflicts ~err ~log ml ".ml" in let log = Fmt.flush log in - {t with log; txt; hocc; hmi; hm; mli; ml} + {t with log; txt; hocc; yacc; hmi; hm; mli; ml} let fatal {err; _} = let _err = Fmt.flush err in @@ -162,6 +170,9 @@ let with_txt t txt = let with_hocc t hocc = {t with hocc} +let with_yacc t yacc = + {t with yacc} + let with_hmi t hmi = {t with hmi} diff --git a/bootstrap/bin/hocc/io.mli b/bootstrap/bin/hocc/io.mli index d008a1c96..e92cad077 100644 --- a/bootstrap/bin/hocc/io.mli +++ b/bootstrap/bin/hocc/io.mli @@ -15,6 +15,7 @@ type t = { log: (module Fmt.Formatter); txt: (module Fmt.Formatter); hocc: (module Fmt.Formatter); + yacc: (module Fmt.Formatter); hmi: (module Fmt.Formatter); hm: (module Fmt.Formatter); mli: (module Fmt.Formatter); @@ -43,6 +44,9 @@ val with_txt: t -> (module Fmt.Formatter) -> t val with_hocc: t -> (module Fmt.Formatter) -> t (** [with_hocc t hocc] is equivalent to [{t with hocc}]. *) +val with_yacc: t -> (module Fmt.Formatter) -> t +(** [with_yacc t yacc] is equivalent to [{t with yacc}]. *) + val with_hmi: t -> (module Fmt.Formatter) -> t (** [with_hmi t hmi] is equivalent to [{t with hmi}]. *) diff --git a/bootstrap/bin/hocc/precSet.ml b/bootstrap/bin/hocc/precSet.ml index 684567569..3ee407637 100644 --- a/bootstrap/bin/hocc/precSet.ml +++ b/bootstrap/bin/hocc/precSet.ml @@ -36,7 +36,7 @@ let pp_hr {names; _} formatter = |> Fmt.fmt "prec " |> Fmt.fmt (String.join ~sep:", " (Array.to_list names)) -let src_fmt {names; assoc; stmt; _} formatter = +let hocc_fmt {names; assoc; stmt; _} formatter = let string_of_token token = begin Hmc.Source.Slice.to_string (Scan.Token.source token) end in diff --git a/bootstrap/bin/hocc/precSet.mli b/bootstrap/bin/hocc/precSet.mli index 867989d06..f9c703c30 100644 --- a/bootstrap/bin/hocc/precSet.mli +++ b/bootstrap/bin/hocc/precSet.mli @@ -28,7 +28,7 @@ include IdentifiableIntf.S with type t := t val pp_hr: t -> (module Fmt.Formatter) -> (module Fmt.Formatter) (** Formatter which outputs precedence set in human-readable form. *) -val src_fmt: t -> (module Fmt.Formatter) -> (module Fmt.Formatter) +val hocc_fmt: t -> (module Fmt.Formatter) -> (module Fmt.Formatter) (** Formatter which outputs precedence set in hocc syntax. *) val init: index:Index.t -> names:string array -> assoc:(Assoc.t option) -> doms:Bitset.t diff --git a/bootstrap/bin/hocc/precs.ml b/bootstrap/bin/hocc/precs.ml index a3e522b1c..42e73b8fe 100644 --- a/bootstrap/bin/hocc/precs.ml +++ b/bootstrap/bin/hocc/precs.ml @@ -44,39 +44,8 @@ let prec_set_of_prec_index prec_index {prec_sets; _} = let fold_prec_sets ~init ~f {prec_sets; _} = Ordmap.fold ~init ~f:(fun accum (_, prec) -> f accum prec) prec_sets -let src_fmt Prec.{name_index; prec_set_index} t formatter = - let PrecSet.{assoc; stmt; _} as prec_set = prec_set_of_prec_index prec_set_index t in - let name = PrecSet.name_of_name_index name_index prec_set in - let string_of_token token = begin - Hmc.Source.Slice.to_string (Scan.Token.source token) - end in - formatter - |> Fmt.fmt (match assoc with - | None -> " neutral " - | Some Left -> " left " - | Some Right -> " right " - | Some Nonassoc -> " nonassoc " - ) - |> Fmt.fmt name - |> (fun formatter -> - match stmt with - | PrecSet {prec_rels=PrecRelsPrecs {precs=Precs {uident; precs_tl}}; _} -> begin - let rec fmt_precs_tl precs_tl formatter = begin - match precs_tl with - | Parse.PrecsTlUident {uident; precs_tl} -> begin - formatter - |> Fmt.fmt ", " |> Fmt.fmt (string_of_token uident) - |> fmt_precs_tl precs_tl - end - | PrecsTlEpsilon -> formatter - end in - formatter - |> Fmt.fmt " < " |> Fmt.fmt (string_of_token uident) - |> fmt_precs_tl precs_tl - end - | PrecSet {prec_rels=PrecRelsEpsilon; _} -> formatter - ) - |> Fmt.fmt "\n" +let fold_prec_sets_right ~init ~f {prec_sets; _} = + Ordmap.fold_right ~init ~f:(fun accum (_, prec) -> f accum prec) prec_sets let pp_prec_hr Prec.{name_index; prec_set_index} t formatter = let prec_set = prec_set_of_prec_index prec_set_index t in diff --git a/bootstrap/bin/hocc/precs.mli b/bootstrap/bin/hocc/precs.mli index bb2726d6d..9df66b38f 100644 --- a/bootstrap/bin/hocc/precs.mli +++ b/bootstrap/bin/hocc/precs.mli @@ -37,8 +37,9 @@ val fold_prec_sets: init:'accum -> f:('accum -> PrecSet.t -> 'accum) -> t -> 'ac (** [fold ~init ~f t] iteratively applies [f] to the precedence sets in [t], in increasing index order. *) -val src_fmt: Prec.t -> t -> (module Fmt.Formatter) -> (module Fmt.Formatter) -(** Formatter which outputs precedence in hocc syntax. *) +val fold_prec_sets_right: init:'accum -> f:('accum -> PrecSet.t -> 'accum) -> t -> 'accum +(** [fold ~init ~f t] iteratively applies [f] to the precedence sets in [t], in decreasing index + order. *) val pp_prec_hr: Prec.t -> t -> (module Fmt.Formatter) -> (module Fmt.Formatter) (** Formatter which outputs precedence in human-readable form. *) diff --git a/bootstrap/bin/hocc/prods.ml b/bootstrap/bin/hocc/prods.ml index 4eceedd67..0dbb483b7 100644 --- a/bootstrap/bin/hocc/prods.ml +++ b/bootstrap/bin/hocc/prods.ml @@ -24,7 +24,7 @@ let prod_of_prod_index = Array.get let fold = Array.fold -let src_fmt precs symbols Prod.{lhs_index; rhs_indexes; prec; _} formatter = +let hocc_fmt precs symbols Prod.{lhs_index; rhs_indexes; prec; _} formatter = let lhs_symbol = Symbols.symbol_of_symbol_index lhs_index symbols in formatter |> Fmt.fmt " " diff --git a/bootstrap/bin/hocc/prods.mli b/bootstrap/bin/hocc/prods.mli index 70b9f90d5..1049c4ffe 100644 --- a/bootstrap/bin/hocc/prods.mli +++ b/bootstrap/bin/hocc/prods.mli @@ -32,5 +32,5 @@ val fold: init:'accum -> f:('accum -> Prod.t -> 'accum) -> t -> 'accum (** [fold ~init ~f t] iteratively applies [f] to the productions in [t], in increasing index order. *) -val src_fmt: Precs.t -> Symbols.t -> Prod.t -> (module Fmt.Formatter) -> (module Fmt.Formatter) +val hocc_fmt: Precs.t -> Symbols.t -> Prod.t -> (module Fmt.Formatter) -> (module Fmt.Formatter) (** Formatter which outputs production in hocc syntax. *) diff --git a/bootstrap/bin/hocc/spec.ml b/bootstrap/bin/hocc/spec.ml index a7e4aa7e5..ba8f90552 100644 --- a/bootstrap/bin/hocc/spec.ml +++ b/bootstrap/bin/hocc/spec.ml @@ -1178,8 +1178,9 @@ and warn_unused io precs symbols prods states = match Set.mem name precs_used with | true -> formatter | false -> begin - let prec = Prec.init ~name ~prec_set in - formatter |> Fmt.fmt "hocc:" |> Precs.src_fmt prec precs + let Prec.{prec_set_index; _} = Prec.init ~name ~prec_set in + let prec_set = Precs.prec_set_of_prec_index prec_set_index precs in + formatter |> Fmt.fmt "hocc:" |> PrecSet.hocc_fmt prec_set end ) names ) precs @@ -1211,7 +1212,7 @@ and warn_unused io precs symbols prods states = |> (fun formatter -> Ordset.fold ~init:formatter ~f:(fun formatter prec_set -> - formatter |> Fmt.fmt "hocc:" |> PrecSet.src_fmt prec_set + formatter |> Fmt.fmt "hocc:" |> PrecSet.hocc_fmt prec_set ) prec_sets_assoc_unused ) |> Io.with_err io @@ -1230,7 +1231,7 @@ and warn_unused io precs symbols prods states = Symbols.tokens_fold ~init:formatter ~f:(fun formatter token -> match Set.mem Symbol.(token.index) tokens_used with | true -> formatter - | false -> formatter |> Fmt.fmt "hocc:" |> Symbols.src_fmt precs token symbols + | false -> formatter |> Fmt.fmt "hocc:" |> Symbols.hocc_fmt precs token symbols ) symbols ) |> Io.with_err io @@ -1257,7 +1258,7 @@ and warn_unused io precs symbols prods states = |> (fun formatter -> Ordset.fold ~init:formatter ~f:(fun formatter token -> - formatter |> Fmt.fmt "hocc:" |> Symbols.src_fmt precs token symbols + formatter |> Fmt.fmt "hocc:" |> Symbols.hocc_fmt precs token symbols ) tokens_prec_unused ) |> Io.with_err io @@ -1310,7 +1311,7 @@ and warn_unused io precs symbols prods states = | false -> begin formatter |> Fmt.fmt "hocc:" - |> Prods.src_fmt precs symbols prod + |> Prods.hocc_fmt precs symbols prod end ) prods ) @@ -1338,7 +1339,7 @@ and warn_unused io precs symbols prods states = |> (fun formatter -> Ordset.fold ~init:formatter ~f:(fun formatter prod -> - formatter |> Fmt.fmt "hocc:" |> Prods.src_fmt precs symbols prod + formatter |> Fmt.fmt "hocc:" |> Prods.hocc_fmt precs symbols prod ) prods_prec_unused ) |> Io.with_err io @@ -1374,30 +1375,8 @@ and init algorithm ~resolve ~gc ~remerge ~warn io hmh = | No -> io, isocores, states in let io, isocores, states = match remerge with - | Conf.Default true - | Explicit true -> begin - let conflicts = - states - |> Array.map ~f:(fun state -> State.conflicts ~filter_pseudo_end:true state) - |> Array.reduce ~f:Uns.( + ) - |> Option.value ~default:0L - in - match remerge, conflicts with - | Default true, 0L - | Explicit true, _ - -> Aplr.remerge_states io symbols isocores states - | _, _ -> begin - let io = - io.log - |> Fmt.fmt "hocc: State subgraph remerging disabled due to unresolvable conflicts\n" - |> Fmt.fmt "hocc: Explicitly enable remerging (-remerge yes) to override\n" - |> Io.with_log io - in - io, isocores, states - end - end - | Default false - | Explicit false -> io, isocores, states + | true -> Aplr.remerge_states io symbols isocores states + | false -> io, isocores, states in let io, _isocores, states = match gc with | PostRemerge -> Trace.gc_states io prods isocores states diff --git a/bootstrap/bin/hocc/spec.mli b/bootstrap/bin/hocc/spec.mli index 5b73d6d8c..f059cb5d6 100644 --- a/bootstrap/bin/hocc/spec.mli +++ b/bootstrap/bin/hocc/spec.mli @@ -27,7 +27,7 @@ val synthetic_name_of_start_name: string -> string (** [synthetic_name_of_start_name start_name] returns a synthetic symbol name based on [start_name], e.g. "Start" -> "Start'". *) -val init: Conf.algorithm -> resolve:bool -> gc:Conf.gc -> remerge:Conf.remerge -> warn:bool -> Io.t +val init: Conf.algorithm -> resolve:bool -> gc:Conf.gc -> remerge:bool -> warn:bool -> Io.t -> Parse.nonterm_hmh -> Io.t * t (** [init algorithm ~resolve ~gc ~remerge ~warn io hmh] creates a specification using the specified [algorithm] on [hmh], with conflicts optionally resolved, unreachable states optionally diff --git a/bootstrap/bin/hocc/symbols.ml b/bootstrap/bin/hocc/symbols.ml index 7cc1a2f14..bccd6cca8 100644 --- a/bootstrap/bin/hocc/symbols.ml +++ b/bootstrap/bin/hocc/symbols.ml @@ -147,7 +147,7 @@ let nonterms_fold ~init ~f {symbols; ntokens; _} = Array.Slice.init ~range:(ntokens =:< Array.length symbols) symbols |> Array.Slice.fold ~init ~f -let src_fmt precs (Symbol.{name; prec; alias; start; prods; _} as symbol) t formatter = +let hocc_fmt precs (Symbol.{name; prec; alias; start; prods; _} as symbol) t formatter = match Symbol.is_token symbol with | true -> begin formatter diff --git a/bootstrap/bin/hocc/symbols.mli b/bootstrap/bin/hocc/symbols.mli index 2bf8cc71e..d9207016a 100644 --- a/bootstrap/bin/hocc/symbols.mli +++ b/bootstrap/bin/hocc/symbols.mli @@ -114,7 +114,7 @@ val nonterms_fold: init:'accum -> f:('accum -> Symbol.t -> 'accum) -> t -> 'accu (** [nonterms_fold ~init ~f t] iteratively applies [f] to the non-terminals in [t], in increasing index order. *) -val src_fmt: Precs.t -> Symbol.t -> t -> (module Fmt.Formatter) -> (module Fmt.Formatter) +val hocc_fmt: Precs.t -> Symbol.t -> t -> (module Fmt.Formatter) -> (module Fmt.Formatter) (** Formatter which outputs symbol in hocc syntax. *) val pp_prod_hr: Prod.t -> t -> (module Fmt.Formatter) -> (module Fmt.Formatter) diff --git a/bootstrap/test/hocc/Conflict.expected b/bootstrap/test/hocc/Conflict.expected index 7dc59598f..391647054 100644 --- a/bootstrap/test/hocc/Conflict.expected +++ b/bootstrap/test/hocc/Conflict.expected @@ -6,7 +6,7 @@ hocc: Generating LR(1) item set closures (workq/total) 0/4 hocc: Generating 4 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+.+.+ hocc: 0 unreachable states -hocc: State subgraph remerging disabled due to unresolvable conflicts -hocc: Explicitly enable remerging (-remerge yes) to override +hocc: Searching for remergeable states: 0/0 +hocc: 0 remergeable states hocc: 1 unresolvable conflict in 1 state (0 ⊥, 0 shift-reduce, 1 reduce-reduce) hocc: Hemlock code not generated due to conflict diff --git a/bootstrap/test/hocc/Example_rno.expected b/bootstrap/test/hocc/Example_rno.expected index ebb485ca0..6110313ac 100644 --- a/bootstrap/test/hocc/Example_rno.expected +++ b/bootstrap/test/hocc/Example_rno.expected @@ -6,8 +6,8 @@ hocc: Generating LR(1) item set closures (workq/total) 0/14 hocc: Generating 14 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+.+.+.++ hocc: 0 unreachable states -hocc: State subgraph remerging disabled due to unresolvable conflicts -hocc: Explicitly enable remerging (-remerge yes) to override +hocc: Searching for remergeable states: 0/0 +hocc: 0 remergeable states hocc: 8 conflicts in 2 states (0 ⊥, 8 shift-reduce, 0 reduce-reduce) (conflict resolution disabled) hocc: 2 unused precedence set associativities: hocc: left mul diff --git a/bootstrap/test/hocc/Gawk_aaplr.expected b/bootstrap/test/hocc/Gawk_aaplr.expected index f3a30983c..94b9db04c 100644 --- a/bootstrap/test/hocc/Gawk_aaplr.expected +++ b/bootstrap/test/hocc/Gawk_aaplr.expected @@ -7,9 +7,10 @@ hocc: Generating 2_467 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+.+......+..+......+.....+..+.....+......+..+..+..+.+++++++ hocc: 108 unreachable states hocc: Reindexing 2_359 LR(1) states -hocc: State subgraph remerging disabled due to unresolvable conflicts -hocc: Explicitly enable remerging (-remerge yes) to override -hocc: 308 unresolvable conflicts in 210 states (43 ⊥, 265 shift-reduce, 0 reduce-reduce) +hocc: Searching for remergeable states: 1_992/2_039 +hocc: Remerging 1_992 LR(1) states +hocc: Reindexing 367 LR(1) states +hocc: 104 unresolvable conflicts in 66 states (38 ⊥, 66 shift-reduce, 0 reduce-reduce) hocc: 11 unused precedence set associativities: hocc: left pParen hocc: left pDollar < pParen diff --git a/bootstrap/test/hocc/Gpic_aielr.expected b/bootstrap/test/hocc/Gpic_aielr.expected index 8188d64b8..747cf78d0 100644 --- a/bootstrap/test/hocc/Gpic_aielr.expected +++ b/bootstrap/test/hocc/Gpic_aielr.expected @@ -13,6 +13,9 @@ hocc: Generating 450 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+.+....+....+..+.+.+.+++ hocc: 3 unreachable states hocc: Reindexing 447 LR(1) states +hocc: Searching for remergeable states: 19/24 +hocc: Remerging 19 LR(1) states +hocc: Reindexing 428 LR(1) states hocc: 239 unresolvable conflicts in 239 states (239 ⊥, 0 shift-reduce, 0 reduce-reduce) hocc: 17 unused precedence set associativities: hocc: right pXmark < pCarat diff --git a/bootstrap/test/hocc/Hocc.expected b/bootstrap/test/hocc/Hocc.expected index e602ab97c..02fbdb2c0 100644 --- a/bootstrap/test/hocc/Hocc.expected +++ b/bootstrap/test/hocc/Hocc.expected @@ -12,6 +12,8 @@ hocc: Remerging 648 LR(1) states hocc: Reindexing 263 LR(1) states hocc: 0 unresolvable conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report +hocc: Generating Yacc report hocc: Writing "./hocc/Hocc.txt" hocc: Writing "./hocc/Hocc.hmh" +hocc: Writing "./hocc/Hocc.y" diff --git a/bootstrap/test/hocc/Hocc.expected.y b/bootstrap/test/hocc/Hocc.expected.y new file mode 100644 index 000000000..de042afe8 --- /dev/null +++ b/bootstrap/test/hocc/Hocc.expected.y @@ -0,0 +1,359 @@ +%{ +%} + +%precedence pAS AS +%right pSEMI SEMI +%left pCOMMA COMMA +%left pDOT DOT +%precedence pCIDENT +%precedence pPrec PREC +%precedence pCodeTlEpsilon + +%token HOCC "hocc" +%token NONTERM "nonterm" +%token EPSILON_ "epsilon" +%token START "start" +%token TOKEN "token" +%token NEUTRAL "neutral" +%token LEFT "left" +%token RIGHT "right" +%token NONASSOC "nonassoc" +%token PREC "prec" +%token UIDENT +%token CIDENT +%token USCORE "_" +%token ISTRING +%token COLON_COLON_EQ "::=" +%token OF "of" +%token COLON ":" +%token DOT "." +%token ARROW "->" +%token BAR "|" +%token LT "<" +%token EQ "=" +%token COMMA "," +%token SEMI ";" +%token AS "as" +%token LINE_DELIM +%token INDENT +%token DEDENT +%token LPAREN "(" +%token RPAREN ")" +%token LCAPTURE "(|" +%token RCAPTURE "|)" +%token LBRACK "[" +%token RBRACK "]" +%token LARRAY "[|" +%token RARRAY "|]" +%token LCURLY "{" +%token RCURLY "}" +%token OTHER_TOKEN +%token EOI + +%token HOCC_PSEUDO_START_Hmh +%token HOCC_PSEUDO_START_Hmhi + +%% + +%start hocc-pseudo-start; + +hocc-pseudo-start: + HOCC_PSEUDO_START_Hmh Hmh; +| HOCC_PSEUDO_START_Hmhi Hmhi; +; + +Uident : + "hocc" +| "nonterm" +| "epsilon" +| "start" +| "token" +| "neutral" +| "left" +| "right" +| "nonassoc" +| "prec" +| UIDENT +; + +PrecsTl : + /* empty */ +| "," Uident PrecsTl +; + +Precs : + Uident PrecsTl +; + +PrecRels : + /* empty */ +| "<" Precs +; + +PrecType : + "neutral" +| "left" +| "right" +| "nonassoc" +; + +PrecSet : + PrecType Precs PrecRels +; + +SymbolTypeQualifier : + /* empty */ +| CIDENT "." SymbolTypeQualifier +; + +SymbolType : + "of" SymbolTypeQualifier Uident +; + +PrecRef : + /* empty */ +| "prec" Uident +; + +Alias : + /* empty */ +| ISTRING +; + +TokenType : + /* empty */ +| SymbolType Code +; + +Token : + "token" CIDENT Alias TokenType PrecRef +; + +Sep : + LINE_DELIM +| ";" +| "|" +; + +CodesTl : + /* empty */ +| Sep Code CodesTl +; + +Codes : + Code CodesTl +; + +Codes0 : + /* empty */ +| Codes +; + +Delimited : + INDENT Codes DEDENT +| "(" Codes0 ")" +| "(|" Codes0 "|)" +| "[" Codes0 "]" +| "[|" Codes0 "|]" +| "{" Codes0 "}" +; + +CodeToken : + OTHER_TOKEN +| Uident +| CIDENT +| "_" +| ISTRING +| "::=" +| "as" +| "of" +| ":" +| "." +| "->" +| "<" +| "=" +| "," +; + +CodeTl : + /* empty */ %prec pCodeTlEpsilon +| Delimited CodeTl +| CodeToken CodeTl +; + +Code : + Delimited CodeTl +| CodeToken CodeTl +; + +PatternField : + Uident +| Uident "=" Pattern +; + +PatternFields : + PatternField %prec pSEMI +| PatternField ";" "_" +| PatternField ";" PatternFields +; + +SemiSuffix : + /* empty */ +| ";" +; + +ModulePath : + CIDENT +| ModulePath "." ModulePath %prec pDOT +; + +Pattern : + "_" +| Uident +| Pattern "as" Uident +| "(" Pattern ")" +| CIDENT Pattern %prec pCIDENT +| ModulePath "." "(" Pattern ")" +| Pattern "," Pattern %prec pCOMMA +| "{" PatternFields SemiSuffix "}" +| ModulePath "." "{" PatternFields SemiSuffix "}" +; + +ProdParamSymbol : + CIDENT +| ISTRING +; + +ProdParam : + Uident ":" ProdParamSymbol +| "(" Pattern ")" ":" ProdParamSymbol +| ModulePath "." "(" Pattern ")" ":" ProdParamSymbol +| "{" PatternFields SemiSuffix "}" ":" ProdParamSymbol +| ModulePath "." "{" PatternFields SemiSuffix "}" ":" ProdParamSymbol +| "_" ":" ProdParamSymbol +| ProdParamSymbol +; + +ProdParamsTl : + ProdParam ProdParamsTl +| PrecRef +; + +ProdParams : + ProdParam ProdParamsTl +; + +ProdPattern : + ProdParams +| "epsilon" PrecRef +; + +Prod : + ProdPattern +; + +ProdsTl : + /* empty */ +| "|" Prod ProdsTl +; + +Prods : + "|" Prod ProdsTl +| Prod ProdsTl +; + +Reduction : + Prods "->" Code +; + +ReductionsTl : + /* empty */ +| "|" Reduction ReductionsTl +; + +Reductions : + Reduction ReductionsTl +; + +NontermType : + "nonterm" +| "start" +; + +Nonterm : + NontermType CIDENT PrecRef "::=" Prods +| NontermType CIDENT SymbolType PrecRef "::=" Reductions +; + +Stmt : + PrecSet +| Token +| Nonterm +; + +StmtsTl : + /* empty */ +| LINE_DELIM Stmt StmtsTl +; + +Stmts : + Stmt StmtsTl +; + +Hocc : + "hocc" INDENT Stmts DEDENT +; + +MatterToken : + Sep +| "nonterm" +| "epsilon" +| "start" +| "token" +| "neutral" +| "left" +| "right" +| "nonassoc" +| "prec" +| OTHER_TOKEN +| UIDENT +| CIDENT +| "_" +| ISTRING +| "::=" +| "as" +| "of" +| ":" +| "." +| "->" +| "<" +| "=" +| "," +| INDENT +| DEDENT +| "(" +| ")" +| "(|" +| "|)" +| "[" +| "]" +| "[|" +| "|]" +| "{" +| "}" +; + +Matter : + /* empty */ +| MatterToken Matter +; + +Hmh : + Matter Hocc Matter EOI +; + +Hmhi : + Matter "hocc" Matter EOI +; + +%% diff --git a/bootstrap/test/hocc/IelrFig1.expected b/bootstrap/test/hocc/IelrFig1.expected index 846051643..1ff6d8fe1 100644 --- a/bootstrap/test/hocc/IelrFig1.expected +++ b/bootstrap/test/hocc/IelrFig1.expected @@ -12,8 +12,10 @@ hocc: Generating LR(1) item set closures (workq/total) 0/12 hocc: Generating 12 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/1 +hocc: 0 remergeable states hocc: 0 unresolvable conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig1.txt" hocc: Writing "./hocc/IelrFig1.hmh" diff --git a/bootstrap/test/hocc/IelrFig1_rno.expected b/bootstrap/test/hocc/IelrFig1_rno.expected index 6258fde8c..96c991ed8 100644 --- a/bootstrap/test/hocc/IelrFig1_rno.expected +++ b/bootstrap/test/hocc/IelrFig1_rno.expected @@ -12,6 +12,8 @@ hocc: Generating LR(1) item set closures (workq/total) 0/12 hocc: Generating 12 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/1 +hocc: 0 remergeable states hocc: 1 conflict in 1 state (0 ⊥, 1 shift-reduce, 0 reduce-reduce) (conflict resolution disabled) hocc: 1 unused precedence set associativity: hocc: left p @@ -20,6 +22,6 @@ hocc: token Ta prec p hocc: 1 unused production precedence: hocc: A ::= Ta prec p hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig1_rno.txt" hocc: Writing "./hocc/IelrFig1_rno.hmh" diff --git a/bootstrap/test/hocc/IelrFig2.expected b/bootstrap/test/hocc/IelrFig2.expected index 689209384..478765fdc 100644 --- a/bootstrap/test/hocc/IelrFig2.expected +++ b/bootstrap/test/hocc/IelrFig2.expected @@ -13,10 +13,12 @@ hocc: Generating 21 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+.+.+ hocc: 2 unreachable states hocc: Reindexing 19 LR(1) states +hocc: Searching for remergeable states: 0/2 +hocc: 0 remergeable states hocc: 0 unresolvable conflicts hocc: 1 unused production: hocc: S ::= Tb C Ta hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig2.txt" hocc: Writing "./hocc/IelrFig2.hmh" diff --git a/bootstrap/test/hocc/IelrFig2_rno.expected b/bootstrap/test/hocc/IelrFig2_rno.expected index 37e01d888..fdf358a55 100644 --- a/bootstrap/test/hocc/IelrFig2_rno.expected +++ b/bootstrap/test/hocc/IelrFig2_rno.expected @@ -12,11 +12,13 @@ hocc: Generating LR(1) item set closures (workq/total) 0/21 hocc: Generating 21 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/2 +hocc: 0 remergeable states hocc: 1 conflict in 1 state (0 ⊥, 0 shift-reduce, 1 reduce-reduce) (conflict resolution disabled) hocc: 2 unused production precedences: hocc: B ::= Ta Ta prec p1 hocc: C ::= Ta Ta prec p2 hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig2_rno.txt" hocc: Writing "./hocc/IelrFig2_rno.hmh" diff --git a/bootstrap/test/hocc/IelrFig3.expected b/bootstrap/test/hocc/IelrFig3.expected index e875f9916..40e410a9b 100644 --- a/bootstrap/test/hocc/IelrFig3.expected +++ b/bootstrap/test/hocc/IelrFig3.expected @@ -13,6 +13,8 @@ hocc: Generating 21 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+.+.+ hocc: 6 unreachable states hocc: Reindexing 15 LR(1) states +hocc: Searching for remergeable states: 0/2 +hocc: 0 remergeable states hocc: 0 unresolvable conflicts hocc: 1 unused precedence: hocc: neutral p3 < p2 @@ -24,6 +26,6 @@ hocc: S ::= Ta C Ta hocc: S ::= Tb C Ta hocc: C ::= Ta Ta prec p3 hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig3.txt" hocc: Writing "./hocc/IelrFig3.hmh" diff --git a/bootstrap/test/hocc/IelrFig3_apgm.expected b/bootstrap/test/hocc/IelrFig3_apgm.expected index 06e7f40b6..713f582f2 100644 --- a/bootstrap/test/hocc/IelrFig3_apgm.expected +++ b/bootstrap/test/hocc/IelrFig3_apgm.expected @@ -7,6 +7,8 @@ hocc: Generating 19 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+.+.+ hocc: 8 unreachable states hocc: Reindexing 11 LR(1) states +hocc: Searching for remergeable states: 0/0 +hocc: 0 remergeable states hocc: 0 unresolvable conflicts hocc: 2 unused precedences: hocc: neutral p2 < p1 @@ -22,6 +24,6 @@ hocc: S ::= Tb C Ta hocc: B ::= Ta Ta prec p2 hocc: C ::= Ta Ta prec p3 hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig3_apgm.txt" hocc: Writing "./hocc/IelrFig3_apgm.hmh" diff --git a/bootstrap/test/hocc/IelrFig3_rno.expected b/bootstrap/test/hocc/IelrFig3_rno.expected index 7d6828686..a1959f2ba 100644 --- a/bootstrap/test/hocc/IelrFig3_rno.expected +++ b/bootstrap/test/hocc/IelrFig3_rno.expected @@ -12,12 +12,14 @@ hocc: Generating LR(1) item set closures (workq/total) 0/21 hocc: Generating 21 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/2 +hocc: 0 remergeable states hocc: 2 conflicts in 2 states (0 ⊥, 0 shift-reduce, 2 reduce-reduce) (conflict resolution disabled) hocc: 3 unused production precedences: hocc: A ::= Ta Ta prec p1 hocc: B ::= Ta Ta prec p2 hocc: C ::= Ta Ta prec p3 hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig3_rno.txt" hocc: Writing "./hocc/IelrFig3_rno.hmh" diff --git a/bootstrap/test/hocc/IelrFig4_rno.expected b/bootstrap/test/hocc/IelrFig4_rno.expected index b5d874a99..b23ce68cb 100644 --- a/bootstrap/test/hocc/IelrFig4_rno.expected +++ b/bootstrap/test/hocc/IelrFig4_rno.expected @@ -12,8 +12,10 @@ hocc: Generating LR(1) item set closures (workq/total) 0/16 hocc: Generating 16 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+..+.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/1 +hocc: 0 remergeable states hocc: 1 conflict in 1 state (0 ⊥, 0 shift-reduce, 1 reduce-reduce) (conflict resolution disabled) hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig4_rno.txt" hocc: Writing "./hocc/IelrFig4_rno.hmh" diff --git a/bootstrap/test/hocc/IelrFig5.expected b/bootstrap/test/hocc/IelrFig5.expected index c2263a727..5a89c7b87 100644 --- a/bootstrap/test/hocc/IelrFig5.expected +++ b/bootstrap/test/hocc/IelrFig5.expected @@ -12,8 +12,10 @@ hocc: Generating LR(1) item set closures (workq/total) 0/22 hocc: Generating 22 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+++.++.+.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/3 +hocc: 0 remergeable states hocc: 0 unresolvable conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig5.txt" hocc: Writing "./hocc/IelrFig5.hmh" diff --git a/bootstrap/test/hocc/IelrFig5Diamond.expected b/bootstrap/test/hocc/IelrFig5Diamond.expected index 21003c663..43e145df5 100644 --- a/bootstrap/test/hocc/IelrFig5Diamond.expected +++ b/bootstrap/test/hocc/IelrFig5Diamond.expected @@ -12,8 +12,10 @@ hocc: Generating LR(1) item set closures (workq/total) 0/28 hocc: Generating 28 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+....+++.++.++.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/5 +hocc: 0 remergeable states hocc: 0 unresolvable conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig5Diamond.txt" hocc: Writing "./hocc/IelrFig5Diamond.hmh" diff --git a/bootstrap/test/hocc/IelrFig5Diamonds.expected b/bootstrap/test/hocc/IelrFig5Diamonds.expected index fd140fe1e..2da860ba6 100644 --- a/bootstrap/test/hocc/IelrFig5Diamonds.expected +++ b/bootstrap/test/hocc/IelrFig5Diamonds.expected @@ -12,8 +12,10 @@ hocc: Generating LR(1) item set closures (workq/total) 0/34 hocc: Generating 34 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+.....+++.++.+++.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/7 +hocc: 0 remergeable states hocc: 0 unresolvable conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig5Diamonds.txt" hocc: Writing "./hocc/IelrFig5Diamonds.hmh" diff --git a/bootstrap/test/hocc/IelrFig5_rno.expected b/bootstrap/test/hocc/IelrFig5_rno.expected index 1f1d38628..ff72c59a2 100644 --- a/bootstrap/test/hocc/IelrFig5_rno.expected +++ b/bootstrap/test/hocc/IelrFig5_rno.expected @@ -12,12 +12,14 @@ hocc: Generating LR(1) item set closures (workq/total) 0/22 hocc: Generating 22 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+++.++.+.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/3 +hocc: 0 remergeable states hocc: 1 conflict in 1 state (0 ⊥, 1 shift-reduce, 0 reduce-reduce) (conflict resolution disabled) hocc: 1 unused token precedence: hocc: token Ta prec p2 hocc: 1 unused production precedence: hocc: E ::= epsilon prec p1 hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig5_rno.txt" hocc: Writing "./hocc/IelrFig5_rno.hmh" diff --git a/bootstrap/test/hocc/IelrFig6.expected b/bootstrap/test/hocc/IelrFig6.expected index d05866b34..1894cbc21 100644 --- a/bootstrap/test/hocc/IelrFig6.expected +++ b/bootstrap/test/hocc/IelrFig6.expected @@ -12,8 +12,10 @@ hocc: Generating LR(1) item set closures (workq/total) 0/15 hocc: Generating 15 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+.+++.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/0 +hocc: 0 remergeable states hocc: 0 unresolvable conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/IelrFig6.txt" hocc: Writing "./hocc/IelrFig6.hmh" diff --git a/bootstrap/test/hocc/IelrRemergeable_aielr_gno.expected b/bootstrap/test/hocc/IelrRemergeable_aielr_gno.expected index 846f64679..f1c980f30 100644 --- a/bootstrap/test/hocc/IelrRemergeable_aielr_gno.expected +++ b/bootstrap/test/hocc/IelrRemergeable_aielr_gno.expected @@ -10,6 +10,9 @@ hocc: Gathering IELR(1) conflict state attributions (/=none/some) hocc: LR(1) item set compatibility: ielr hocc: Generating LR(1) item set closures (workq/total) 0/58 hocc: Generating 58 LR(1) states +hocc: Searching for remergeable states: 13/13 +hocc: Remerging 13 LR(1) states +hocc: Reindexing 45 LR(1) states hocc: 0 unresolvable conflicts hocc: Generating text report hocc: Writing "./hocc/IelrRemergeable_aielr_gno.txt" diff --git a/bootstrap/test/hocc/IelrRemergeable_aielr_gno.expected.txt b/bootstrap/test/hocc/IelrRemergeable_aielr_gno.expected.txt index 6d406dcc8..20ee21451 100644 --- a/bootstrap/test/hocc/IelrRemergeable_aielr_gno.expected.txt +++ b/bootstrap/test/hocc/IelrRemergeable_aielr_gno.expected.txt @@ -182,9 +182,9 @@ IELR(1) States EOI : Reduce Pos ::= EPair State 6 [6.0] Kernel - [Pos ::= E · "min" Pos "max" Pos, {")", "+", "-", "max", ",", EOI}] prec p1 - [Pos ::= E · "<" Pos "," Pos ">", {")", "+", "-", "max", ",", EOI}] - [EPair ::= E · "," E, {")", "+", "-", "max", ",", EOI}] prec p4 + [Pos ::= E · "min" Pos "max" Pos, {")", "+", "-", "max", ">", ",", EOI}] prec p1 + [Pos ::= E · "<" Pos "," Pos ">", {")", "+", "-", "max", ">", ",", EOI}] + [EPair ::= E · "," E, {")", "+", "-", "max", ">", ",", EOI}] prec p4 [E ::= E · "+" E, {"+", "min", "<", ">", ","}] prec p0 [E ::= E · "<" E, {"+", "min", "<", ">", ","}] prec p3 [E ::= E · ">" E, {"+", "min", "<", ">", ","}] prec p3 @@ -195,6 +195,23 @@ IELR(1) States ">" : ShiftPrefix 17 prec p3 "," : ShiftPrefix 18 prec p4 Conflict contributions + Pos ::= E · "min" Pos "max" Pos + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + Pos ::= E · "<" Pos "," Pos ">" + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + EPair ::= E · "," E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E E ::= E · "+" E ">" : 27 : Reduce E ::= E "+" E @@ -269,10 +286,10 @@ IELR(1) States "ε" : Reduce S' ::= S "⊥" State 11 [11.0] Kernel - [Pos ::= Pos "+" · EPair, {")", "+", "-", "max", ",", EOI}] + [Pos ::= Pos "+" · EPair, {")", "+", "-", "max", ">", ",", EOI}] Added - [EPair ::= · E "," E, {")", "+", "-", "max", ",", EOI}] prec p4 - [EPair ::= · "(" EPair ")", {")", "+", "-", "max", ",", EOI}] + [EPair ::= · E "," E, {")", "+", "-", "max", ">", ",", EOI}] prec p4 + [EPair ::= · "(" EPair ")", {")", "+", "-", "max", ">", ",", EOI}] [E ::= · "var", {"+", "<", ">", ","}] [E ::= · E "+" E, {"+", "<", ">", ","}] prec p0 [E ::= · "(" E ")", {"+", "<", ">", ","}] @@ -284,12 +301,18 @@ IELR(1) States Gotos EPair : 23 E : 24 + Conflict contributions + Pos ::= Pos "+" · EPair + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E State 12 [12.0] Kernel - [Pos ::= Pos "-" · EPair, {")", "+", "-", "max", ",", EOI}] + [Pos ::= Pos "-" · EPair, {")", "+", "-", "max", ">", ",", EOI}] Added - [EPair ::= · E "," E, {")", "+", "-", "max", ",", EOI}] prec p4 - [EPair ::= · "(" EPair ")", {")", "+", "-", "max", ",", EOI}] + [EPair ::= · E "," E, {")", "+", "-", "max", ">", ",", EOI}] prec p4 + [EPair ::= · "(" EPair ")", {")", "+", "-", "max", ">", ",", EOI}] [E ::= · "var", {"+", "<", ">", ","}] [E ::= · E "+" E, {"+", "<", ">", ","}] prec p0 [E ::= · "(" E ")", {"+", "<", ">", ","}] @@ -301,6 +324,12 @@ IELR(1) States Gotos EPair : 25 E : 24 + Conflict contributions + Pos ::= Pos "-" · EPair + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E State 13 [13.0] Kernel [S ::= Pos EOI ·, {"⊥"}] @@ -329,7 +358,7 @@ IELR(1) States 41 : Reduce E ::= E "<" E State 15 [15.0] Kernel - [Pos ::= E "min" · Pos "max" Pos, {")", "+", "-", "max", ",", EOI}] prec p1 + [Pos ::= E "min" · Pos "max" Pos, {")", "+", "-", "max", ">", ",", EOI}] prec p1 Added [Pos ::= · EPair, {"+", "-", "max"}] [Pos ::= · Pos "+" EPair, {"+", "-", "max"}] @@ -351,9 +380,16 @@ IELR(1) States Pos : 28 EPair : 5 E : 6 + Conflict contributions + Pos ::= E "min" · Pos "max" Pos + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E State 16 [16.0] Kernel - [Pos ::= E "<" · Pos "," Pos ">", {")", "+", "-", "max", ",", EOI}] + [Pos ::= E "<" · Pos "," Pos ">", {")", "+", "-", "max", ">", ",", EOI}] [E ::= E "<" · E, {")", "+", "min", "<", ">", ","}] prec p3 Added [Pos ::= · EPair, {"+", "-", ","}] @@ -377,6 +413,12 @@ IELR(1) States EPair : 5 E : 30 Conflict contributions + Pos ::= E "<" · Pos "," Pos ">" + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E E ::= E "<" · E ">" : 27 : Reduce E ::= E "+" E @@ -406,7 +448,7 @@ IELR(1) States 41 : Reduce E ::= E "<" E State 18 [18.0] Kernel - [EPair ::= E "," · E, {")", "+", "-", "max", ",", EOI}] prec p4 + [EPair ::= E "," · E, {")", "+", "-", "max", ">", ",", EOI}] prec p4 Added [E ::= · "var", {")", "+", "-", "max", "<", ">", ",", EOI}] [E ::= · E "+" E, {")", "+", "-", "max", "<", ">", ",", EOI}] prec p0 @@ -421,6 +463,10 @@ IELR(1) States Conflict contributions EPair ::= E "," · E "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E State 19 [19.0] Kernel [Pos ::= "(" Pos "," · Pos ")", {")", "+", "-", "max", ">", ",", EOI}] @@ -506,7 +552,7 @@ IELR(1) States EOI : Reduce Pos ::= Pos "+" EPair State 24 [24.0] Kernel - [EPair ::= E · "," E, {")", "+", "-", "max", ",", EOI}] prec p4 + [EPair ::= E · "," E, {")", "+", "-", "max", ">", ",", EOI}] prec p4 [E ::= E · "+" E, {"+", "<", ">", ","}] prec p0 [E ::= E · "<" E, {"+", "<", ">", ","}] prec p3 [E ::= E · ">" E, {"+", "<", ">", ","}] prec p3 @@ -516,6 +562,11 @@ IELR(1) States ">" : ShiftPrefix 17 prec p3 "," : ShiftPrefix 18 prec p4 Conflict contributions + EPair ::= E · "," E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E E ::= E · "+" E ">" : 27 : Reduce E ::= E "+" E @@ -605,20 +656,34 @@ IELR(1) States Kernel [Pos ::= Pos · "+" EPair, {"+", "-", "max"}] [Pos ::= Pos · "-" EPair, {"+", "-", "max"}] - [Pos ::= E "min" Pos · "max" Pos, {")", "+", "-", "max", ",", EOI}] prec p1 + [Pos ::= E "min" Pos · "max" Pos, {")", "+", "-", "max", ">", ",", EOI}] prec p1 Actions "+" : ShiftPrefix 11 prec p0 "-" : ShiftPrefix 12 prec p0 "max" : ShiftPrefix 38 + Conflict contributions + Pos ::= E "min" Pos · "max" Pos + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E State 29 [29.0] Kernel [Pos ::= Pos · "+" EPair, {"+", "-", ","}] [Pos ::= Pos · "-" EPair, {"+", "-", ","}] - [Pos ::= E "<" Pos · "," Pos ">", {")", "+", "-", "max", ",", EOI}] + [Pos ::= E "<" Pos · "," Pos ">", {")", "+", "-", "max", ">", ",", EOI}] Actions "+" : ShiftPrefix 11 prec p0 "-" : ShiftPrefix 12 prec p0 "," : ShiftPrefix 39 prec p4 + Conflict contributions + Pos ::= E "<" Pos · "," Pos ">" + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E State 30 [30.0] Kernel [Pos ::= E · "min" Pos "max" Pos, {"+", "-", ","}] prec p1 @@ -751,7 +816,7 @@ IELR(1) States "+" : ShiftPrefix 14 prec p0 "<" : ShiftPrefix 36 prec p3 ">" : ShiftPrefix 17 prec p3 - "," : ShiftPrefix 41 prec p4 + "," : ShiftPrefix 18 prec p4 Conflict contributions E ::= E · "+" E ">" : @@ -781,7 +846,7 @@ IELR(1) States "var" : ShiftPrefix 1 "(" : ShiftPrefix 26 Gotos - E : 42 + E : 41 Conflict contributions E ::= E "<" · E "+" : 27 : Reduce E ::= E "+" E @@ -821,16 +886,16 @@ IELR(1) States 41 : Reduce E ::= E "<" E State 38 [38.0] Kernel - [Pos ::= E "min" Pos "max" · Pos, {")", "+", "-", "max", ",", EOI}] prec p1 + [Pos ::= E "min" Pos "max" · Pos, {")", "+", "-", "max", ">", ",", EOI}] prec p1 Added - [Pos ::= · EPair, {")", "+", "-", "max", ",", EOI}] - [Pos ::= · Pos "+" EPair, {")", "+", "-", "max", ",", EOI}] - [Pos ::= · Pos "-" EPair, {")", "+", "-", "max", ",", EOI}] - [Pos ::= · "(" Pos "," Pos ")", {")", "+", "-", "max", ",", EOI}] - [Pos ::= · E "min" Pos "max" Pos, {")", "+", "-", "max", ",", EOI}] prec p1 - [Pos ::= · E "<" Pos "," Pos ">", {")", "+", "-", "max", ",", EOI}] - [EPair ::= · E "," E, {")", "+", "-", "max", ",", EOI}] prec p4 - [EPair ::= · "(" EPair ")", {")", "+", "-", "max", ",", EOI}] + [Pos ::= · EPair, {")", "+", "-", "max", ">", ",", EOI}] + [Pos ::= · Pos "+" EPair, {")", "+", "-", "max", ">", ",", EOI}] + [Pos ::= · Pos "-" EPair, {")", "+", "-", "max", ">", ",", EOI}] + [Pos ::= · "(" Pos "," Pos ")", {")", "+", "-", "max", ">", ",", EOI}] + [Pos ::= · E "min" Pos "max" Pos, {")", "+", "-", "max", ">", ",", EOI}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {")", "+", "-", "max", ">", ",", EOI}] + [EPair ::= · E "," E, {")", "+", "-", "max", ">", ",", EOI}] prec p4 + [EPair ::= · "(" EPair ")", {")", "+", "-", "max", ">", ",", EOI}] [E ::= · "var", {"+", "min", "<", ">", ","}] [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] @@ -840,12 +905,19 @@ IELR(1) States "var" : ShiftPrefix 1 "(" : ShiftPrefix 2 Gotos - Pos : 43 + Pos : 42 EPair : 5 E : 6 + Conflict contributions + Pos ::= E "min" Pos "max" · Pos + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E State 39 [39.0] Kernel - [Pos ::= E "<" Pos "," · Pos ">", {")", "+", "-", "max", ",", EOI}] + [Pos ::= E "<" Pos "," · Pos ">", {")", "+", "-", "max", ">", ",", EOI}] Added [Pos ::= · EPair, {"+", "-", ">"}] [Pos ::= · Pos "+" EPair, {"+", "-", ">"}] @@ -864,9 +936,16 @@ IELR(1) States "var" : ShiftPrefix 1 "(" : ShiftPrefix 2 Gotos - Pos : 44 + Pos : 43 EPair : 5 - E : 45 + E : 6 + Conflict contributions + Pos ::= E "<" Pos "," · Pos ">" + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E State 40 [40.0] Kernel [Pos ::= "(" Pos "," Pos ")" ·, {")", "+", "-", "max", ">", ",", EOI}] @@ -878,21 +957,7 @@ IELR(1) States ">" : Reduce Pos ::= "(" Pos "," Pos ")" "," : Reduce Pos ::= "(" Pos "," Pos ")" EOI : Reduce Pos ::= "(" Pos "," Pos ")" - State 41 [18.1] - Kernel - [EPair ::= E "," · E, {")"}] prec p4 - Added - [E ::= · "var", {")", "+", "<", ">"}] - [E ::= · E "+" E, {")", "+", "<", ">"}] prec p0 - [E ::= · "(" E ")", {")", "+", "<", ">"}] - [E ::= · E "<" E, {")", "+", "<", ">"}] prec p3 - [E ::= · E ">" E, {")", "+", "<", ">"}] prec p3 - Actions - "var" : ShiftPrefix 1 - "(" : ShiftPrefix 26 - Gotos - E : 32 - State 42 [41.0] + State 41 [41.0] Kernel [E ::= E · "+" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p0 [E ::= E · "<" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 @@ -929,27 +994,19 @@ IELR(1) States 27 : Reduce E ::= E "+" E 31 : Reduce E ::= E ">" E 41 : Reduce E ::= E "<" E - State 43 [42.0] + State 42 [42.0] Kernel - [Pos ::= Pos · "+" EPair, {")", "+", "-", "max", ",", EOI}] - [Pos ::= Pos · "-" EPair, {")", "+", "-", "max", ",", EOI}] - [Pos ::= E "min" Pos "max" Pos ·, {")", "+", "-", "max", ",", EOI}] prec p1 + [Pos ::= Pos · "+" EPair, {")", "+", "-", "max", ">", ",", EOI}] + [Pos ::= Pos · "-" EPair, {")", "+", "-", "max", ">", ",", EOI}] + [Pos ::= E "min" Pos "max" Pos ·, {")", "+", "-", "max", ">", ",", EOI}] prec p1 Actions ")" : Reduce Pos ::= E "min" Pos "max" Pos prec p1 "+" : ShiftPrefix 11 prec p0 "-" : ShiftPrefix 12 prec p0 "max" : Reduce Pos ::= E "min" Pos "max" Pos prec p1 + ">" : Reduce Pos ::= E "min" Pos "max" Pos prec p1 "," : Reduce Pos ::= E "min" Pos "max" Pos prec p1 EOI : Reduce Pos ::= E "min" Pos "max" Pos prec p1 - State 44 [43.0] - Kernel - [Pos ::= Pos · "+" EPair, {"+", "-", ">"}] - [Pos ::= Pos · "-" EPair, {"+", "-", ">"}] - [Pos ::= E "<" Pos "," Pos · ">", {")", "+", "-", "max", ">", ",", EOI}] - Actions - "+" : ShiftPrefix 46 prec p0 - "-" : ShiftPrefix 47 prec p0 - ">" : ShiftPrefix 48 prec p3 Conflict contributions Pos ::= Pos · "+" EPair ">" : @@ -961,101 +1018,27 @@ IELR(1) States 27 : Reduce E ::= E "+" E 31 : Reduce E ::= E ">" E 41 : Reduce E ::= E "<" E - State 45 [6.1] - Kernel - [Pos ::= E · "min" Pos "max" Pos, {"+", "-", ">"}] prec p1 - [Pos ::= E · "<" Pos "," Pos ">", {"+", "-", ">"}] - [EPair ::= E · "," E, {"+", "-", ">"}] prec p4 - [E ::= E · "+" E, {"+", "min", "<", ">", ","}] prec p0 - [E ::= E · "<" E, {"+", "min", "<", ">", ","}] prec p3 - [E ::= E · ">" E, {"+", "min", "<", ">", ","}] prec p3 - Actions - "+" : ShiftPrefix 14 prec p0 - "min" : ShiftPrefix 49 prec p2 - "<" : ShiftPrefix 50 prec p3 - ">" : ShiftPrefix 17 prec p3 - "," : ShiftPrefix 51 prec p4 - Conflict contributions - Pos ::= E · "min" Pos "max" Pos - ">" : - 27 : Reduce E ::= E "+" E - 30 : Reduce E ::= E "<" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - Pos ::= E · "<" Pos "," Pos ">" - ">" : - 27 : Reduce E ::= E "+" E - 30 : Reduce E ::= E "<" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - EPair ::= E · "," E - ">" : - 27 : Reduce E ::= E "+" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - E ::= E · "+" E - ">" : - 27 : Reduce E ::= E "+" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - E ::= E · "<" E - ">" : - 27 : Reduce E ::= E "+" E - 30 : Reduce E ::= E "<" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - E ::= E · ">" E - ">" : - 27 : Reduce E ::= E "+" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - State 46 [11.1] + State 43 [43.0] Kernel - [Pos ::= Pos "+" · EPair, {"+", "-", ">"}] - Added - [EPair ::= · E "," E, {"+", "-", ">"}] prec p4 - [EPair ::= · "(" EPair ")", {"+", "-", ">"}] - [E ::= · "var", {"+", "<", ">", ","}] - [E ::= · E "+" E, {"+", "<", ">", ","}] prec p0 - [E ::= · "(" E ")", {"+", "<", ">", ","}] - [E ::= · E "<" E, {"+", "<", ">", ","}] prec p3 - [E ::= · E ">" E, {"+", "<", ">", ","}] prec p3 + [Pos ::= Pos · "+" EPair, {"+", "-", ">"}] + [Pos ::= Pos · "-" EPair, {"+", "-", ">"}] + [Pos ::= E "<" Pos "," Pos · ">", {")", "+", "-", "max", ">", ",", EOI}] Actions - "var" : ShiftPrefix 1 - "(" : ShiftPrefix 22 - Gotos - EPair : 23 - E : 52 + "+" : ShiftPrefix 11 prec p0 + "-" : ShiftPrefix 12 prec p0 + ">" : ShiftPrefix 44 prec p3 Conflict contributions - Pos ::= Pos "+" · EPair + Pos ::= Pos · "+" EPair ">" : 27 : Reduce E ::= E "+" E 31 : Reduce E ::= E ">" E 41 : Reduce E ::= E "<" E - State 47 [12.1] - Kernel - [Pos ::= Pos "-" · EPair, {"+", "-", ">"}] - Added - [EPair ::= · E "," E, {"+", "-", ">"}] prec p4 - [EPair ::= · "(" EPair ")", {"+", "-", ">"}] - [E ::= · "var", {"+", "<", ">", ","}] - [E ::= · E "+" E, {"+", "<", ">", ","}] prec p0 - [E ::= · "(" E ")", {"+", "<", ">", ","}] - [E ::= · E "<" E, {"+", "<", ">", ","}] prec p3 - [E ::= · E ">" E, {"+", "<", ">", ","}] prec p3 - Actions - "var" : ShiftPrefix 1 - "(" : ShiftPrefix 22 - Gotos - EPair : 25 - E : 52 - Conflict contributions - Pos ::= Pos "-" · EPair + Pos ::= Pos · "-" EPair ">" : 27 : Reduce E ::= E "+" E 31 : Reduce E ::= E ">" E 41 : Reduce E ::= E "<" E - State 48 [44.0] + State 44 [44.0] Kernel [Pos ::= E "<" Pos "," Pos ">" ·, {")", "+", "-", "max", ">", ",", EOI}] Actions @@ -1066,239 +1049,3 @@ IELR(1) States ">" : Reduce Pos ::= E "<" Pos "," Pos ">" "," : Reduce Pos ::= E "<" Pos "," Pos ">" EOI : Reduce Pos ::= E "<" Pos "," Pos ">" - State 49 [15.1] - Kernel - [Pos ::= E "min" · Pos "max" Pos, {"+", "-", ">"}] prec p1 - Added - [Pos ::= · EPair, {"+", "-", "max"}] - [Pos ::= · Pos "+" EPair, {"+", "-", "max"}] - [Pos ::= · Pos "-" EPair, {"+", "-", "max"}] - [Pos ::= · "(" Pos "," Pos ")", {"+", "-", "max"}] - [Pos ::= · E "min" Pos "max" Pos, {"+", "-", "max"}] prec p1 - [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", "max"}] - [EPair ::= · E "," E, {"+", "-", "max"}] prec p4 - [EPair ::= · "(" EPair ")", {"+", "-", "max"}] - [E ::= · "var", {"+", "min", "<", ">", ","}] - [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 - [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] - [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 - [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 - Actions - "var" : ShiftPrefix 1 - "(" : ShiftPrefix 2 - Gotos - Pos : 53 - EPair : 5 - E : 6 - Conflict contributions - Pos ::= E "min" · Pos "max" Pos - ">" : - 27 : Reduce E ::= E "+" E - 30 : Reduce E ::= E "<" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - State 50 [16.1] - Kernel - [Pos ::= E "<" · Pos "," Pos ">", {"+", "-", ">"}] - [E ::= E "<" · E, {"+", "min", "<", ">", ","}] prec p3 - Added - [Pos ::= · EPair, {"+", "-", ","}] - [Pos ::= · Pos "+" EPair, {"+", "-", ","}] - [Pos ::= · Pos "-" EPair, {"+", "-", ","}] - [Pos ::= · "(" Pos "," Pos ")", {"+", "-", ","}] - [Pos ::= · E "min" Pos "max" Pos, {"+", "-", ","}] prec p1 - [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", ","}] - [EPair ::= · E "," E, {"+", "-", ","}] prec p4 - [EPair ::= · "(" EPair ")", {"+", "-", ","}] - [E ::= · "var", {"+", "min", "<", ">", ","}] - [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 - [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] - [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 - [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 - Actions - "var" : ShiftPrefix 1 - "(" : ShiftPrefix 2 - Gotos - Pos : 54 - EPair : 5 - E : 30 - Conflict contributions - Pos ::= E "<" · Pos "," Pos ">" - ">" : - 27 : Reduce E ::= E "+" E - 30 : Reduce E ::= E "<" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - E ::= E "<" · E - ">" : - 27 : Reduce E ::= E "+" E - 30 : Reduce E ::= E "<" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - State 51 [18.2] - Kernel - [EPair ::= E "," · E, {"+", "-", ">"}] prec p4 - Added - [E ::= · "var", {"+", "-", "<", ">"}] - [E ::= · E "+" E, {"+", "-", "<", ">"}] prec p0 - [E ::= · "(" E ")", {"+", "-", "<", ">"}] - [E ::= · E "<" E, {"+", "-", "<", ">"}] prec p3 - [E ::= · E ">" E, {"+", "-", "<", ">"}] prec p3 - Actions - "var" : ShiftPrefix 1 - "(" : ShiftPrefix 26 - Gotos - E : 32 - Conflict contributions - EPair ::= E "," · E - "+" : 27 : Reduce E ::= E "+" E - ">" : - 27 : Reduce E ::= E "+" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - State 52 [24.1] - Kernel - [EPair ::= E · "," E, {"+", "-", ">"}] prec p4 - [E ::= E · "+" E, {"+", "<", ">", ","}] prec p0 - [E ::= E · "<" E, {"+", "<", ">", ","}] prec p3 - [E ::= E · ">" E, {"+", "<", ">", ","}] prec p3 - Actions - "+" : ShiftPrefix 14 prec p0 - "<" : ShiftPrefix 36 prec p3 - ">" : ShiftPrefix 17 prec p3 - "," : ShiftPrefix 51 prec p4 - Conflict contributions - EPair ::= E · "," E - ">" : - 27 : Reduce E ::= E "+" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - E ::= E · "+" E - ">" : - 27 : Reduce E ::= E "+" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - E ::= E · "<" E - ">" : - 27 : Reduce E ::= E "+" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - E ::= E · ">" E - ">" : - 27 : Reduce E ::= E "+" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - State 53 [28.1] - Kernel - [Pos ::= Pos · "+" EPair, {"+", "-", "max"}] - [Pos ::= Pos · "-" EPair, {"+", "-", "max"}] - [Pos ::= E "min" Pos · "max" Pos, {"+", "-", ">"}] prec p1 - Actions - "+" : ShiftPrefix 11 prec p0 - "-" : ShiftPrefix 12 prec p0 - "max" : ShiftPrefix 55 - Conflict contributions - Pos ::= E "min" Pos · "max" Pos - ">" : - 27 : Reduce E ::= E "+" E - 30 : Reduce E ::= E "<" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - State 54 [29.1] - Kernel - [Pos ::= Pos · "+" EPair, {"+", "-", ","}] - [Pos ::= Pos · "-" EPair, {"+", "-", ","}] - [Pos ::= E "<" Pos · "," Pos ">", {"+", "-", ">"}] - Actions - "+" : ShiftPrefix 11 prec p0 - "-" : ShiftPrefix 12 prec p0 - "," : ShiftPrefix 56 prec p4 - Conflict contributions - Pos ::= E "<" Pos · "," Pos ">" - ">" : - 27 : Reduce E ::= E "+" E - 30 : Reduce E ::= E "<" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - State 55 [38.1] - Kernel - [Pos ::= E "min" Pos "max" · Pos, {"+", "-", ">"}] prec p1 - Added - [Pos ::= · EPair, {"+", "-", ">"}] - [Pos ::= · Pos "+" EPair, {"+", "-", ">"}] - [Pos ::= · Pos "-" EPair, {"+", "-", ">"}] - [Pos ::= · "(" Pos "," Pos ")", {"+", "-", ">"}] - [Pos ::= · E "min" Pos "max" Pos, {"+", "-", ">"}] prec p1 - [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", ">"}] - [EPair ::= · E "," E, {"+", "-", ">"}] prec p4 - [EPair ::= · "(" EPair ")", {"+", "-", ">"}] - [E ::= · "var", {"+", "min", "<", ">", ","}] - [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 - [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] - [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 - [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 - Actions - "var" : ShiftPrefix 1 - "(" : ShiftPrefix 2 - Gotos - Pos : 57 - EPair : 5 - E : 45 - Conflict contributions - Pos ::= E "min" Pos "max" · Pos - ">" : - 27 : Reduce E ::= E "+" E - 30 : Reduce E ::= E "<" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - State 56 [39.1] - Kernel - [Pos ::= E "<" Pos "," · Pos ">", {"+", "-", ">"}] - Added - [Pos ::= · EPair, {"+", "-", ">"}] - [Pos ::= · Pos "+" EPair, {"+", "-", ">"}] - [Pos ::= · Pos "-" EPair, {"+", "-", ">"}] - [Pos ::= · "(" Pos "," Pos ")", {"+", "-", ">"}] - [Pos ::= · E "min" Pos "max" Pos, {"+", "-", ">"}] prec p1 - [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", ">"}] - [EPair ::= · E "," E, {"+", "-", ">"}] prec p4 - [EPair ::= · "(" EPair ")", {"+", "-", ">"}] - [E ::= · "var", {"+", "min", "<", ">", ","}] - [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 - [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] - [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 - [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 - Actions - "var" : ShiftPrefix 1 - "(" : ShiftPrefix 2 - Gotos - Pos : 44 - EPair : 5 - E : 45 - Conflict contributions - Pos ::= E "<" Pos "," · Pos ">" - ">" : - 27 : Reduce E ::= E "+" E - 30 : Reduce E ::= E "<" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - State 57 [42.1] - Kernel - [Pos ::= Pos · "+" EPair, {"+", "-", ">"}] - [Pos ::= Pos · "-" EPair, {"+", "-", ">"}] - [Pos ::= E "min" Pos "max" Pos ·, {"+", "-", ">"}] prec p1 - Actions - "+" : ShiftPrefix 46 prec p0 - "-" : ShiftPrefix 47 prec p0 - ">" : Reduce Pos ::= E "min" Pos "max" Pos prec p1 - Conflict contributions - Pos ::= Pos · "+" EPair - ">" : - 27 : Reduce E ::= E "+" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E - Pos ::= Pos · "-" EPair - ">" : - 27 : Reduce E ::= E "+" E - 31 : Reduce E ::= E ">" E - 41 : Reduce E ::= E "<" E diff --git a/bootstrap/test/hocc/IelrRemergeable_aielr_myes.expected.txt b/bootstrap/test/hocc/IelrRemergeable_aielr_mno.exected.txt similarity index 100% rename from bootstrap/test/hocc/IelrRemergeable_aielr_myes.expected.txt rename to bootstrap/test/hocc/IelrRemergeable_aielr_mno.exected.txt diff --git a/bootstrap/test/hocc/IelrRemergeable_aielr_myes.expected b/bootstrap/test/hocc/IelrRemergeable_aielr_mno.expected similarity index 78% rename from bootstrap/test/hocc/IelrRemergeable_aielr_myes.expected rename to bootstrap/test/hocc/IelrRemergeable_aielr_mno.expected index ad539ed17..41a2d75bb 100644 --- a/bootstrap/test/hocc/IelrRemergeable_aielr_myes.expected +++ b/bootstrap/test/hocc/IelrRemergeable_aielr_mno.expected @@ -1,4 +1,4 @@ -hocc: Parsing "./IelrRemergeable_aielr_myes.hmh" +hocc: Parsing "./IelrRemergeable_aielr_mno.hmh" hocc: Generating IELR(1) specification hocc: 5 precedences, 13 tokens, 5 non-terminals (1 start), 15 productions hocc: Generating LALR(1) specification as IELR(1) prerequisite @@ -12,9 +12,6 @@ hocc: Generating LR(1) item set closures (workq/total) 0/58 hocc: Generating 58 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+.+..+.+.+..+.+.+.++ hocc: 0 unreachable states -hocc: Searching for remergeable states: 13/13 -hocc: Remerging 13 LR(1) states -hocc: Reindexing 45 LR(1) states hocc: 0 unresolvable conflicts hocc: Generating text report -hocc: Writing "./hocc/IelrRemergeable_aielr_myes.txt" +hocc: Writing "./hocc/IelrRemergeable_aielr_mno.txt" diff --git a/bootstrap/test/hocc/IelrRemergeable_aielr_mno.expected.txt b/bootstrap/test/hocc/IelrRemergeable_aielr_mno.expected.txt new file mode 100644 index 000000000..299aeca5d --- /dev/null +++ b/bootstrap/test/hocc/IelrRemergeable_aielr_mno.expected.txt @@ -0,0 +1,1304 @@ +IelrRemergeable_aielr_mno grammar + +Precedences + left p0 + neutral p1 < p0 + neutral p2 < p0, p1 + left p3 < p0, p1, p2 + neutral p4 < p0, p1, p2, p3 +Tokens + token EPSILON "ε" + First: {"ε"} + Follow: {} + token PSEUDO_END "⊥" + First: {"⊥"} + Follow: {"ε"} + token RPAREN ")" + First: {")"} + Follow: {")", "+", "-", "max", "min", "<", ">", ",", EOI} + token PLUS "+" prec p0 + First: {"+"} + Follow: {"var", "("} + token MINUS "-" prec p0 + First: {"-"} + Follow: {"var", "("} + token MAX "max" + First: {"max"} + Follow: {"var", "("} + token MIN "min" prec p2 + First: {"min"} + Follow: {"var", "("} + token LT "<" prec p3 + First: {"<"} + Follow: {"var", "("} + token GT ">" prec p3 + First: {">"} + Follow: {")", "+", "-", "max", ">", ",", "var", "(", EOI} + token COMMA "," prec p4 + First: {","} + Follow: {"var", "("} + token VAR "var" + First: {"var"} + Follow: {")", "+", "-", "max", "min", "<", ">", ",", EOI} + token LPAREN "(" + First: {"("} + Follow: {"var", "("} + token EOI + First: {EOI} + Follow: {"⊥"} +Non-terminals + start S + First: {"var", "("} + Follow: {"⊥"} + Productions + S ::= Pos EOI + start S' + First: {"var", "("} + Follow: {"ε"} + Productions + S' ::= S "⊥" + nonterm Pos + First: {"var", "("} + Follow: {")", "+", "-", "max", ">", ",", EOI} + Productions + Pos ::= EPair + Pos ::= Pos "+" EPair + Pos ::= Pos "-" EPair + Pos ::= "(" Pos "," Pos ")" + Pos ::= E "min" Pos "max" Pos prec p1 + Pos ::= E "<" Pos "," Pos ">" + nonterm EPair + First: {"var", "("} + Follow: {")", "+", "-", "max", ">", ",", EOI} + Productions + EPair ::= E "," E prec p4 + EPair ::= "(" EPair ")" + nonterm E + First: {"var", "("} + Follow: {")", "+", "-", "max", "min", "<", ">", ",", EOI} + Productions + E ::= "var" + E ::= E "+" E prec p0 + E ::= "(" E ")" + E ::= E "<" E prec p3 + E ::= E ">" E prec p3 +IELR(1) States + State 0 [0.0] + Kernel + [S' ::= · S "⊥", {"ε"}] + Added + [S ::= · Pos EOI, {"⊥"}] + [Pos ::= · EPair, {"+", "-", EOI}] + [Pos ::= · Pos "+" EPair, {"+", "-", EOI}] + [Pos ::= · Pos "-" EPair, {"+", "-", EOI}] + [Pos ::= · "(" Pos "," Pos ")", {"+", "-", EOI}] + [Pos ::= · E "min" Pos "max" Pos, {"+", "-", EOI}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", EOI}] + [EPair ::= · E "," E, {"+", "-", EOI}] prec p4 + [EPair ::= · "(" EPair ")", {"+", "-", EOI}] + [E ::= · "var", {"+", "min", "<", ">", ","}] + [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] + [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 2 + Gotos + S : 3 + Pos : 4 + EPair : 5 + E : 6 + State 1 [1.0] + Kernel + [E ::= "var" ·, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] + Actions + ")" : Reduce E ::= "var" + "+" : Reduce E ::= "var" + "-" : Reduce E ::= "var" + "max" : Reduce E ::= "var" + "min" : Reduce E ::= "var" + "<" : Reduce E ::= "var" + ">" : Reduce E ::= "var" + "," : Reduce E ::= "var" + EOI : Reduce E ::= "var" + State 2 [2.0] + Kernel + [Pos ::= "(" · Pos "," Pos ")", {")", "+", "-", "max", ">", ",", EOI}] + [EPair ::= "(" · EPair ")", {")", "+", "-", "max", ">", ",", EOI}] + [E ::= "(" · E ")", {")", "+", "min", "<", ">", ","}] + Added + [Pos ::= · EPair, {"+", "-", ","}] + [Pos ::= · Pos "+" EPair, {"+", "-", ","}] + [Pos ::= · Pos "-" EPair, {"+", "-", ","}] + [Pos ::= · "(" Pos "," Pos ")", {"+", "-", ","}] + [Pos ::= · E "min" Pos "max" Pos, {"+", "-", ","}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", ","}] + [EPair ::= · E "," E, {")", "+", "-", ","}] prec p4 + [EPair ::= · "(" EPair ")", {")", "+", "-", ","}] + [E ::= · "var", {")", "+", "min", "<", ">", ","}] + [E ::= · E "+" E, {")", "+", "min", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {")", "+", "min", "<", ">", ","}] + [E ::= · E "<" E, {")", "+", "min", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {")", "+", "min", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 2 + Gotos + Pos : 7 + EPair : 8 + E : 9 + Conflict contributions + E ::= "(" · E ")" + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 3 [3.0] + Kernel + [S' ::= S · "⊥", {"ε"}] + Actions + "⊥" : ShiftPrefix 10 + State 4 [4.0] + Kernel + [S ::= Pos · EOI, {"⊥"}] + [Pos ::= Pos · "+" EPair, {"+", "-", EOI}] + [Pos ::= Pos · "-" EPair, {"+", "-", EOI}] + Actions + "+" : ShiftPrefix 11 prec p0 + "-" : ShiftPrefix 12 prec p0 + EOI : ShiftAccept 13 + State 5 [5.0] + Kernel + [Pos ::= EPair ·, {")", "+", "-", "max", ">", ",", EOI}] + Actions + ")" : Reduce Pos ::= EPair + "+" : Reduce Pos ::= EPair + "-" : Reduce Pos ::= EPair + "max" : Reduce Pos ::= EPair + ">" : Reduce Pos ::= EPair + "," : Reduce Pos ::= EPair + EOI : Reduce Pos ::= EPair + State 6 [6.0] + Kernel + [Pos ::= E · "min" Pos "max" Pos, {")", "+", "-", "max", ",", EOI}] prec p1 + [Pos ::= E · "<" Pos "," Pos ">", {")", "+", "-", "max", ",", EOI}] + [EPair ::= E · "," E, {")", "+", "-", "max", ",", EOI}] prec p4 + [E ::= E · "+" E, {"+", "min", "<", ">", ","}] prec p0 + [E ::= E · "<" E, {"+", "min", "<", ">", ","}] prec p3 + [E ::= E · ">" E, {"+", "min", "<", ">", ","}] prec p3 + Actions + "+" : ShiftPrefix 14 prec p0 + "min" : ShiftPrefix 15 prec p2 + "<" : ShiftPrefix 16 prec p3 + ">" : ShiftPrefix 17 prec p3 + "," : ShiftPrefix 18 prec p4 + Conflict contributions + E ::= E · "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "<" E + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · ">" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 7 [7.0] + Kernel + [Pos ::= Pos · "+" EPair, {"+", "-", ","}] + [Pos ::= Pos · "-" EPair, {"+", "-", ","}] + [Pos ::= "(" Pos · "," Pos ")", {")", "+", "-", "max", ">", ",", EOI}] + Actions + "+" : ShiftPrefix 11 prec p0 + "-" : ShiftPrefix 12 prec p0 + "," : ShiftPrefix 19 prec p4 + State 8 [8.0] + Kernel + [Pos ::= EPair ·, {"+", "-", ","}] + [EPair ::= "(" EPair · ")", {")", "+", "-", "max", ">", ",", EOI}] + Actions + ")" : ShiftPrefix 20 + "+" : Reduce Pos ::= EPair + "-" : Reduce Pos ::= EPair + "," : Reduce Pos ::= EPair + State 9 [9.0] + Kernel + [Pos ::= E · "min" Pos "max" Pos, {"+", "-", ","}] prec p1 + [Pos ::= E · "<" Pos "," Pos ">", {"+", "-", ","}] + [EPair ::= E · "," E, {")", "+", "-", ","}] prec p4 + [E ::= E · "+" E, {")", "+", "min", "<", ">", ","}] prec p0 + [E ::= "(" E · ")", {")", "+", "min", "<", ">", ","}] + [E ::= E · "<" E, {")", "+", "min", "<", ">", ","}] prec p3 + [E ::= E · ">" E, {")", "+", "min", "<", ">", ","}] prec p3 + Actions + ")" : ShiftPrefix 21 + "+" : ShiftPrefix 14 prec p0 + "min" : ShiftPrefix 15 prec p2 + "<" : ShiftPrefix 16 prec p3 + ">" : ShiftPrefix 17 prec p3 + "," : ShiftPrefix 18 prec p4 + Conflict contributions + E ::= E · "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "<" E + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · ">" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 10 [10.0] + Kernel + [S' ::= S "⊥" ·, {"ε"}] + Actions + "ε" : Reduce S' ::= S "⊥" + State 11 [11.0] + Kernel + [Pos ::= Pos "+" · EPair, {")", "+", "-", "max", ",", EOI}] + Added + [EPair ::= · E "," E, {")", "+", "-", "max", ",", EOI}] prec p4 + [EPair ::= · "(" EPair ")", {")", "+", "-", "max", ",", EOI}] + [E ::= · "var", {"+", "<", ">", ","}] + [E ::= · E "+" E, {"+", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "<", ">", ","}] + [E ::= · E "<" E, {"+", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 22 + Gotos + EPair : 23 + E : 24 + State 12 [12.0] + Kernel + [Pos ::= Pos "-" · EPair, {")", "+", "-", "max", ",", EOI}] + Added + [EPair ::= · E "," E, {")", "+", "-", "max", ",", EOI}] prec p4 + [EPair ::= · "(" EPair ")", {")", "+", "-", "max", ",", EOI}] + [E ::= · "var", {"+", "<", ">", ","}] + [E ::= · E "+" E, {"+", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "<", ">", ","}] + [E ::= · E "<" E, {"+", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 22 + Gotos + EPair : 25 + E : 24 + State 13 [13.0] + Kernel + [S ::= Pos EOI ·, {"⊥"}] + Actions + "⊥" : Reduce S ::= Pos EOI + State 14 [14.0] + Kernel + [E ::= E "+" · E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p0 + Added + [E ::= · "var", {")", "+", "-", "max", "min", "<", ">", ",", EOI}] + [E ::= · E "+" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p0 + [E ::= · "(" E ")", {")", "+", "-", "max", "min", "<", ">", ",", EOI}] + [E ::= · E "<" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + [E ::= · E ">" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 26 + Gotos + E : 27 + Conflict contributions + E ::= E "+" · E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 15 [15.0] + Kernel + [Pos ::= E "min" · Pos "max" Pos, {")", "+", "-", "max", ",", EOI}] prec p1 + Added + [Pos ::= · EPair, {"+", "-", "max"}] + [Pos ::= · Pos "+" EPair, {"+", "-", "max"}] + [Pos ::= · Pos "-" EPair, {"+", "-", "max"}] + [Pos ::= · "(" Pos "," Pos ")", {"+", "-", "max"}] + [Pos ::= · E "min" Pos "max" Pos, {"+", "-", "max"}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", "max"}] + [EPair ::= · E "," E, {"+", "-", "max"}] prec p4 + [EPair ::= · "(" EPair ")", {"+", "-", "max"}] + [E ::= · "var", {"+", "min", "<", ">", ","}] + [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] + [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 2 + Gotos + Pos : 28 + EPair : 5 + E : 6 + State 16 [16.0] + Kernel + [Pos ::= E "<" · Pos "," Pos ">", {")", "+", "-", "max", ",", EOI}] + [E ::= E "<" · E, {")", "+", "min", "<", ">", ","}] prec p3 + Added + [Pos ::= · EPair, {"+", "-", ","}] + [Pos ::= · Pos "+" EPair, {"+", "-", ","}] + [Pos ::= · Pos "-" EPair, {"+", "-", ","}] + [Pos ::= · "(" Pos "," Pos ")", {"+", "-", ","}] + [Pos ::= · E "min" Pos "max" Pos, {"+", "-", ","}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", ","}] + [EPair ::= · E "," E, {"+", "-", ","}] prec p4 + [EPair ::= · "(" EPair ")", {"+", "-", ","}] + [E ::= · "var", {")", "+", "min", "<", ">", ","}] + [E ::= · E "+" E, {")", "+", "min", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {")", "+", "min", "<", ">", ","}] + [E ::= · E "<" E, {")", "+", "min", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {")", "+", "min", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 2 + Gotos + Pos : 29 + EPair : 5 + E : 30 + Conflict contributions + E ::= E "<" · E + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 17 [17.0] + Kernel + [E ::= E ">" · E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + Added + [E ::= · "var", {")", "+", "-", "max", "min", "<", ">", ",", EOI}] + [E ::= · E "+" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p0 + [E ::= · "(" E ")", {")", "+", "-", "max", "min", "<", ">", ",", EOI}] + [E ::= · E "<" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + [E ::= · E ">" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 26 + Gotos + E : 31 + Conflict contributions + E ::= E ">" · E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 18 [18.0] + Kernel + [EPair ::= E "," · E, {")", "+", "-", "max", ",", EOI}] prec p4 + Added + [E ::= · "var", {")", "+", "-", "max", "<", ">", ",", EOI}] + [E ::= · E "+" E, {")", "+", "-", "max", "<", ">", ",", EOI}] prec p0 + [E ::= · "(" E ")", {")", "+", "-", "max", "<", ">", ",", EOI}] + [E ::= · E "<" E, {")", "+", "-", "max", "<", ">", ",", EOI}] prec p3 + [E ::= · E ">" E, {")", "+", "-", "max", "<", ">", ",", EOI}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 26 + Gotos + E : 32 + Conflict contributions + EPair ::= E "," · E + "+" : 27 : Reduce E ::= E "+" E + State 19 [19.0] + Kernel + [Pos ::= "(" Pos "," · Pos ")", {")", "+", "-", "max", ">", ",", EOI}] + Added + [Pos ::= · EPair, {")", "+", "-"}] + [Pos ::= · Pos "+" EPair, {")", "+", "-"}] + [Pos ::= · Pos "-" EPair, {")", "+", "-"}] + [Pos ::= · "(" Pos "," Pos ")", {")", "+", "-"}] + [Pos ::= · E "min" Pos "max" Pos, {")", "+", "-"}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {")", "+", "-"}] + [EPair ::= · E "," E, {")", "+", "-"}] prec p4 + [EPair ::= · "(" EPair ")", {")", "+", "-"}] + [E ::= · "var", {"+", "min", "<", ">", ","}] + [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] + [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 2 + Gotos + Pos : 33 + EPair : 5 + E : 6 + State 20 [20.0] + Kernel + [EPair ::= "(" EPair ")" ·, {")", "+", "-", "max", ">", ",", EOI}] + Actions + ")" : Reduce EPair ::= "(" EPair ")" + "+" : Reduce EPair ::= "(" EPair ")" + "-" : Reduce EPair ::= "(" EPair ")" + "max" : Reduce EPair ::= "(" EPair ")" + ">" : Reduce EPair ::= "(" EPair ")" + "," : Reduce EPair ::= "(" EPair ")" + EOI : Reduce EPair ::= "(" EPair ")" + State 21 [21.0] + Kernel + [E ::= "(" E ")" ·, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] + Actions + ")" : Reduce E ::= "(" E ")" + "+" : Reduce E ::= "(" E ")" + "-" : Reduce E ::= "(" E ")" + "max" : Reduce E ::= "(" E ")" + "min" : Reduce E ::= "(" E ")" + "<" : Reduce E ::= "(" E ")" + ">" : Reduce E ::= "(" E ")" + "," : Reduce E ::= "(" E ")" + EOI : Reduce E ::= "(" E ")" + State 22 [22.0] + Kernel + [EPair ::= "(" · EPair ")", {")", "+", "-", "max", ">", ",", EOI}] + [E ::= "(" · E ")", {")", "+", "<", ">", ","}] + Added + [EPair ::= · E "," E, {")"}] prec p4 + [EPair ::= · "(" EPair ")", {")"}] + [E ::= · "var", {")", "+", "<", ">", ","}] + [E ::= · E "+" E, {")", "+", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {")", "+", "<", ">", ","}] + [E ::= · E "<" E, {")", "+", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {")", "+", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 22 + Gotos + EPair : 34 + E : 35 + Conflict contributions + E ::= "(" · E ")" + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 23 [23.0] + Kernel + [Pos ::= Pos "+" EPair ·, {")", "+", "-", "max", ">", ",", EOI}] + Actions + ")" : Reduce Pos ::= Pos "+" EPair + "+" : Reduce Pos ::= Pos "+" EPair + "-" : Reduce Pos ::= Pos "+" EPair + "max" : Reduce Pos ::= Pos "+" EPair + ">" : Reduce Pos ::= Pos "+" EPair + "," : Reduce Pos ::= Pos "+" EPair + EOI : Reduce Pos ::= Pos "+" EPair + State 24 [24.0] + Kernel + [EPair ::= E · "," E, {")", "+", "-", "max", ",", EOI}] prec p4 + [E ::= E · "+" E, {"+", "<", ">", ","}] prec p0 + [E ::= E · "<" E, {"+", "<", ">", ","}] prec p3 + [E ::= E · ">" E, {"+", "<", ">", ","}] prec p3 + Actions + "+" : ShiftPrefix 14 prec p0 + "<" : ShiftPrefix 36 prec p3 + ">" : ShiftPrefix 17 prec p3 + "," : ShiftPrefix 18 prec p4 + Conflict contributions + E ::= E · "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "<" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · ">" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 25 [25.0] + Kernel + [Pos ::= Pos "-" EPair ·, {")", "+", "-", "max", ">", ",", EOI}] + Actions + ")" : Reduce Pos ::= Pos "-" EPair + "+" : Reduce Pos ::= Pos "-" EPair + "-" : Reduce Pos ::= Pos "-" EPair + "max" : Reduce Pos ::= Pos "-" EPair + ">" : Reduce Pos ::= Pos "-" EPair + "," : Reduce Pos ::= Pos "-" EPair + EOI : Reduce Pos ::= Pos "-" EPair + State 26 [26.0] + Kernel + [E ::= "(" · E ")", {")", "+", "-", "max", "min", "<", ">", ",", EOI}] + Added + [E ::= · "var", {")", "+", "<", ">"}] + [E ::= · E "+" E, {")", "+", "<", ">"}] prec p0 + [E ::= · "(" E ")", {")", "+", "<", ">"}] + [E ::= · E "<" E, {")", "+", "<", ">"}] prec p3 + [E ::= · E ">" E, {")", "+", "<", ">"}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 26 + Gotos + E : 37 + Conflict contributions + E ::= "(" · E ")" + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 27 [27.0] + Kernel + [E ::= E · "+" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p0 + [E ::= E "+" E ·, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p0 + [E ::= E · "<" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + [E ::= E · ">" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + Actions + ")" : Reduce E ::= E "+" E prec p0 + "+" : Reduce E ::= E "+" E prec p0 + "-" : Reduce E ::= E "+" E prec p0 + "max" : Reduce E ::= E "+" E prec p0 + "min" : Reduce E ::= E "+" E prec p0 + "<" : Reduce E ::= E "+" E prec p0 + ">" : Reduce E ::= E "+" E prec p0 + "," : Reduce E ::= E "+" E prec p0 + EOI : Reduce E ::= E "+" E prec p0 + Conflict contributions + E ::= E · "+" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E "+" E · + "+" : 27 : Reduce E ::= E "+" E + ">" : 27 : Reduce E ::= E "+" E + E ::= E · "<" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · ">" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 28 [28.0] + Kernel + [Pos ::= Pos · "+" EPair, {"+", "-", "max"}] + [Pos ::= Pos · "-" EPair, {"+", "-", "max"}] + [Pos ::= E "min" Pos · "max" Pos, {")", "+", "-", "max", ",", EOI}] prec p1 + Actions + "+" : ShiftPrefix 11 prec p0 + "-" : ShiftPrefix 12 prec p0 + "max" : ShiftPrefix 38 + State 29 [29.0] + Kernel + [Pos ::= Pos · "+" EPair, {"+", "-", ","}] + [Pos ::= Pos · "-" EPair, {"+", "-", ","}] + [Pos ::= E "<" Pos · "," Pos ">", {")", "+", "-", "max", ",", EOI}] + Actions + "+" : ShiftPrefix 11 prec p0 + "-" : ShiftPrefix 12 prec p0 + "," : ShiftPrefix 39 prec p4 + State 30 [30.0] + Kernel + [Pos ::= E · "min" Pos "max" Pos, {"+", "-", ","}] prec p1 + [Pos ::= E · "<" Pos "," Pos ">", {"+", "-", ","}] + [EPair ::= E · "," E, {"+", "-", ","}] prec p4 + [E ::= E · "+" E, {")", "+", "min", "<", ">", ","}] prec p0 + [E ::= E · "<" E, {")", "+", "min", "<", ">", ","}] prec p3 + [E ::= E "<" E ·, {")", "+", "min", "<", ">", ","}] prec p3 + [E ::= E · ">" E, {")", "+", "min", "<", ">", ","}] prec p3 + Actions + ")" : Reduce E ::= E "<" E prec p3 + "+" : ShiftPrefix 14 prec p0 + "min" : ShiftPrefix 15 prec p2 + "<" : Reduce E ::= E "<" E prec p3 + ">" : Reduce E ::= E "<" E prec p3 + "," : Reduce E ::= E "<" E prec p3 + Conflict contributions + E ::= E · "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "<" E + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E "<" E · + ">" : 30 : Reduce E ::= E "<" E + E ::= E · ">" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 31 [31.0] + Kernel + [E ::= E · "+" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p0 + [E ::= E · "<" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + [E ::= E · ">" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + [E ::= E ">" E ·, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + Actions + ")" : Reduce E ::= E ">" E prec p3 + "+" : ShiftPrefix 14 prec p0 + "-" : Reduce E ::= E ">" E prec p3 + "max" : Reduce E ::= E ">" E prec p3 + "min" : Reduce E ::= E ">" E prec p3 + "<" : Reduce E ::= E ">" E prec p3 + ">" : Reduce E ::= E ">" E prec p3 + "," : Reduce E ::= E ">" E prec p3 + EOI : Reduce E ::= E ">" E prec p3 + Conflict contributions + E ::= E · "+" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "<" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · ">" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E ">" E · + ">" : 31 : Reduce E ::= E ">" E + State 32 [32.0] + Kernel + [EPair ::= E "," E ·, {")", "+", "-", "max", ">", ",", EOI}] prec p4 + [E ::= E · "+" E, {")", "+", "-", "max", "<", ">", ",", EOI}] prec p0 + [E ::= E · "<" E, {")", "+", "-", "max", "<", ">", ",", EOI}] prec p3 + [E ::= E · ">" E, {")", "+", "-", "max", "<", ">", ",", EOI}] prec p3 + Actions + ")" : Reduce EPair ::= E "," E prec p4 + "+" : ShiftPrefix 14 prec p0 + "-" : Reduce EPair ::= E "," E prec p4 + "max" : Reduce EPair ::= E "," E prec p4 + "<" : ShiftPrefix 36 prec p3 + ">" : ShiftPrefix 17 prec p3 + "," : Reduce EPair ::= E "," E prec p4 + EOI : Reduce EPair ::= E "," E prec p4 + Conflict contributions + E ::= E · "+" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "<" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · ">" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 33 [33.0] + Kernel + [Pos ::= Pos · "+" EPair, {")", "+", "-"}] + [Pos ::= Pos · "-" EPair, {")", "+", "-"}] + [Pos ::= "(" Pos "," Pos · ")", {")", "+", "-", "max", ">", ",", EOI}] + Actions + ")" : ShiftPrefix 40 + "+" : ShiftPrefix 11 prec p0 + "-" : ShiftPrefix 12 prec p0 + State 34 [34.0] + Kernel + [EPair ::= "(" EPair · ")", {")", "+", "-", "max", ">", ",", EOI}] + Actions + ")" : ShiftPrefix 20 + State 35 [35.0] + Kernel + [EPair ::= E · "," E, {")"}] prec p4 + [E ::= E · "+" E, {")", "+", "<", ">", ","}] prec p0 + [E ::= "(" E · ")", {")", "+", "<", ">", ","}] + [E ::= E · "<" E, {")", "+", "<", ">", ","}] prec p3 + [E ::= E · ">" E, {")", "+", "<", ">", ","}] prec p3 + Actions + ")" : ShiftPrefix 21 + "+" : ShiftPrefix 14 prec p0 + "<" : ShiftPrefix 36 prec p3 + ">" : ShiftPrefix 17 prec p3 + "," : ShiftPrefix 41 prec p4 + Conflict contributions + E ::= E · "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "<" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · ">" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 36 [36.0] + Kernel + [E ::= E "<" · E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + Added + [E ::= · "var", {")", "+", "-", "max", "min", "<", ">", ",", EOI}] + [E ::= · E "+" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p0 + [E ::= · "(" E ")", {")", "+", "-", "max", "min", "<", ">", ",", EOI}] + [E ::= · E "<" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + [E ::= · E ">" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 26 + Gotos + E : 42 + Conflict contributions + E ::= E "<" · E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 37 [37.0] + Kernel + [E ::= E · "+" E, {")", "+", "<", ">"}] prec p0 + [E ::= "(" E · ")", {")", "+", "-", "max", "min", "<", ">", ",", EOI}] + [E ::= E · "<" E, {")", "+", "<", ">"}] prec p3 + [E ::= E · ">" E, {")", "+", "<", ">"}] prec p3 + Actions + ")" : ShiftPrefix 21 + "+" : ShiftPrefix 14 prec p0 + "<" : ShiftPrefix 36 prec p3 + ">" : ShiftPrefix 17 prec p3 + Conflict contributions + E ::= E · "+" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "<" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · ">" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 38 [38.0] + Kernel + [Pos ::= E "min" Pos "max" · Pos, {")", "+", "-", "max", ",", EOI}] prec p1 + Added + [Pos ::= · EPair, {")", "+", "-", "max", ",", EOI}] + [Pos ::= · Pos "+" EPair, {")", "+", "-", "max", ",", EOI}] + [Pos ::= · Pos "-" EPair, {")", "+", "-", "max", ",", EOI}] + [Pos ::= · "(" Pos "," Pos ")", {")", "+", "-", "max", ",", EOI}] + [Pos ::= · E "min" Pos "max" Pos, {")", "+", "-", "max", ",", EOI}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {")", "+", "-", "max", ",", EOI}] + [EPair ::= · E "," E, {")", "+", "-", "max", ",", EOI}] prec p4 + [EPair ::= · "(" EPair ")", {")", "+", "-", "max", ",", EOI}] + [E ::= · "var", {"+", "min", "<", ">", ","}] + [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] + [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 2 + Gotos + Pos : 43 + EPair : 5 + E : 6 + State 39 [39.0] + Kernel + [Pos ::= E "<" Pos "," · Pos ">", {")", "+", "-", "max", ",", EOI}] + Added + [Pos ::= · EPair, {"+", "-", ">"}] + [Pos ::= · Pos "+" EPair, {"+", "-", ">"}] + [Pos ::= · Pos "-" EPair, {"+", "-", ">"}] + [Pos ::= · "(" Pos "," Pos ")", {"+", "-", ">"}] + [Pos ::= · E "min" Pos "max" Pos, {"+", "-", ">"}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", ">"}] + [EPair ::= · E "," E, {"+", "-", ">"}] prec p4 + [EPair ::= · "(" EPair ")", {"+", "-", ">"}] + [E ::= · "var", {"+", "min", "<", ">", ","}] + [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] + [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 2 + Gotos + Pos : 44 + EPair : 5 + E : 45 + State 40 [40.0] + Kernel + [Pos ::= "(" Pos "," Pos ")" ·, {")", "+", "-", "max", ">", ",", EOI}] + Actions + ")" : Reduce Pos ::= "(" Pos "," Pos ")" + "+" : Reduce Pos ::= "(" Pos "," Pos ")" + "-" : Reduce Pos ::= "(" Pos "," Pos ")" + "max" : Reduce Pos ::= "(" Pos "," Pos ")" + ">" : Reduce Pos ::= "(" Pos "," Pos ")" + "," : Reduce Pos ::= "(" Pos "," Pos ")" + EOI : Reduce Pos ::= "(" Pos "," Pos ")" + State 41 [18.1] + Kernel + [EPair ::= E "," · E, {")"}] prec p4 + Added + [E ::= · "var", {")", "+", "<", ">"}] + [E ::= · E "+" E, {")", "+", "<", ">"}] prec p0 + [E ::= · "(" E ")", {")", "+", "<", ">"}] + [E ::= · E "<" E, {")", "+", "<", ">"}] prec p3 + [E ::= · E ">" E, {")", "+", "<", ">"}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 26 + Gotos + E : 32 + State 42 [41.0] + Kernel + [E ::= E · "+" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p0 + [E ::= E · "<" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + [E ::= E "<" E ·, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + [E ::= E · ">" E, {")", "+", "-", "max", "min", "<", ">", ",", EOI}] prec p3 + Actions + ")" : Reduce E ::= E "<" E prec p3 + "+" : ShiftPrefix 14 prec p0 + "-" : Reduce E ::= E "<" E prec p3 + "max" : Reduce E ::= E "<" E prec p3 + "min" : Reduce E ::= E "<" E prec p3 + "<" : Reduce E ::= E "<" E prec p3 + ">" : Reduce E ::= E "<" E prec p3 + "," : Reduce E ::= E "<" E prec p3 + EOI : Reduce E ::= E "<" E prec p3 + Conflict contributions + E ::= E · "+" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "<" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E "<" E · + ">" : 41 : Reduce E ::= E "<" E + E ::= E · ">" E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 43 [42.0] + Kernel + [Pos ::= Pos · "+" EPair, {")", "+", "-", "max", ",", EOI}] + [Pos ::= Pos · "-" EPair, {")", "+", "-", "max", ",", EOI}] + [Pos ::= E "min" Pos "max" Pos ·, {")", "+", "-", "max", ",", EOI}] prec p1 + Actions + ")" : Reduce Pos ::= E "min" Pos "max" Pos prec p1 + "+" : ShiftPrefix 11 prec p0 + "-" : ShiftPrefix 12 prec p0 + "max" : Reduce Pos ::= E "min" Pos "max" Pos prec p1 + "," : Reduce Pos ::= E "min" Pos "max" Pos prec p1 + EOI : Reduce Pos ::= E "min" Pos "max" Pos prec p1 + State 44 [43.0] + Kernel + [Pos ::= Pos · "+" EPair, {"+", "-", ">"}] + [Pos ::= Pos · "-" EPair, {"+", "-", ">"}] + [Pos ::= E "<" Pos "," Pos · ">", {")", "+", "-", "max", ">", ",", EOI}] + Actions + "+" : ShiftPrefix 46 prec p0 + "-" : ShiftPrefix 47 prec p0 + ">" : ShiftPrefix 48 prec p3 + Conflict contributions + Pos ::= Pos · "+" EPair + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + Pos ::= Pos · "-" EPair + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 45 [6.1] + Kernel + [Pos ::= E · "min" Pos "max" Pos, {"+", "-", ">"}] prec p1 + [Pos ::= E · "<" Pos "," Pos ">", {"+", "-", ">"}] + [EPair ::= E · "," E, {"+", "-", ">"}] prec p4 + [E ::= E · "+" E, {"+", "min", "<", ">", ","}] prec p0 + [E ::= E · "<" E, {"+", "min", "<", ">", ","}] prec p3 + [E ::= E · ">" E, {"+", "min", "<", ">", ","}] prec p3 + Actions + "+" : ShiftPrefix 14 prec p0 + "min" : ShiftPrefix 49 prec p2 + "<" : ShiftPrefix 50 prec p3 + ">" : ShiftPrefix 17 prec p3 + "," : ShiftPrefix 51 prec p4 + Conflict contributions + Pos ::= E · "min" Pos "max" Pos + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + Pos ::= E · "<" Pos "," Pos ">" + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + EPair ::= E · "," E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "<" E + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · ">" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 46 [11.1] + Kernel + [Pos ::= Pos "+" · EPair, {"+", "-", ">"}] + Added + [EPair ::= · E "," E, {"+", "-", ">"}] prec p4 + [EPair ::= · "(" EPair ")", {"+", "-", ">"}] + [E ::= · "var", {"+", "<", ">", ","}] + [E ::= · E "+" E, {"+", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "<", ">", ","}] + [E ::= · E "<" E, {"+", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 22 + Gotos + EPair : 23 + E : 52 + Conflict contributions + Pos ::= Pos "+" · EPair + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 47 [12.1] + Kernel + [Pos ::= Pos "-" · EPair, {"+", "-", ">"}] + Added + [EPair ::= · E "," E, {"+", "-", ">"}] prec p4 + [EPair ::= · "(" EPair ")", {"+", "-", ">"}] + [E ::= · "var", {"+", "<", ">", ","}] + [E ::= · E "+" E, {"+", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "<", ">", ","}] + [E ::= · E "<" E, {"+", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 22 + Gotos + EPair : 25 + E : 52 + Conflict contributions + Pos ::= Pos "-" · EPair + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 48 [44.0] + Kernel + [Pos ::= E "<" Pos "," Pos ">" ·, {")", "+", "-", "max", ">", ",", EOI}] + Actions + ")" : Reduce Pos ::= E "<" Pos "," Pos ">" + "+" : Reduce Pos ::= E "<" Pos "," Pos ">" + "-" : Reduce Pos ::= E "<" Pos "," Pos ">" + "max" : Reduce Pos ::= E "<" Pos "," Pos ">" + ">" : Reduce Pos ::= E "<" Pos "," Pos ">" + "," : Reduce Pos ::= E "<" Pos "," Pos ">" + EOI : Reduce Pos ::= E "<" Pos "," Pos ">" + State 49 [15.1] + Kernel + [Pos ::= E "min" · Pos "max" Pos, {"+", "-", ">"}] prec p1 + Added + [Pos ::= · EPair, {"+", "-", "max"}] + [Pos ::= · Pos "+" EPair, {"+", "-", "max"}] + [Pos ::= · Pos "-" EPair, {"+", "-", "max"}] + [Pos ::= · "(" Pos "," Pos ")", {"+", "-", "max"}] + [Pos ::= · E "min" Pos "max" Pos, {"+", "-", "max"}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", "max"}] + [EPair ::= · E "," E, {"+", "-", "max"}] prec p4 + [EPair ::= · "(" EPair ")", {"+", "-", "max"}] + [E ::= · "var", {"+", "min", "<", ">", ","}] + [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] + [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 2 + Gotos + Pos : 53 + EPair : 5 + E : 6 + Conflict contributions + Pos ::= E "min" · Pos "max" Pos + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 50 [16.1] + Kernel + [Pos ::= E "<" · Pos "," Pos ">", {"+", "-", ">"}] + [E ::= E "<" · E, {"+", "min", "<", ">", ","}] prec p3 + Added + [Pos ::= · EPair, {"+", "-", ","}] + [Pos ::= · Pos "+" EPair, {"+", "-", ","}] + [Pos ::= · Pos "-" EPair, {"+", "-", ","}] + [Pos ::= · "(" Pos "," Pos ")", {"+", "-", ","}] + [Pos ::= · E "min" Pos "max" Pos, {"+", "-", ","}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", ","}] + [EPair ::= · E "," E, {"+", "-", ","}] prec p4 + [EPair ::= · "(" EPair ")", {"+", "-", ","}] + [E ::= · "var", {"+", "min", "<", ">", ","}] + [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] + [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 2 + Gotos + Pos : 54 + EPair : 5 + E : 30 + Conflict contributions + Pos ::= E "<" · Pos "," Pos ">" + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E "<" · E + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 51 [18.2] + Kernel + [EPair ::= E "," · E, {"+", "-", ">"}] prec p4 + Added + [E ::= · "var", {"+", "-", "<", ">"}] + [E ::= · E "+" E, {"+", "-", "<", ">"}] prec p0 + [E ::= · "(" E ")", {"+", "-", "<", ">"}] + [E ::= · E "<" E, {"+", "-", "<", ">"}] prec p3 + [E ::= · E ">" E, {"+", "-", "<", ">"}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 26 + Gotos + E : 32 + Conflict contributions + EPair ::= E "," · E + "+" : 27 : Reduce E ::= E "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 52 [24.1] + Kernel + [EPair ::= E · "," E, {"+", "-", ">"}] prec p4 + [E ::= E · "+" E, {"+", "<", ">", ","}] prec p0 + [E ::= E · "<" E, {"+", "<", ">", ","}] prec p3 + [E ::= E · ">" E, {"+", "<", ">", ","}] prec p3 + Actions + "+" : ShiftPrefix 14 prec p0 + "<" : ShiftPrefix 36 prec p3 + ">" : ShiftPrefix 17 prec p3 + "," : ShiftPrefix 51 prec p4 + Conflict contributions + EPair ::= E · "," E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "+" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · "<" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + E ::= E · ">" E + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 53 [28.1] + Kernel + [Pos ::= Pos · "+" EPair, {"+", "-", "max"}] + [Pos ::= Pos · "-" EPair, {"+", "-", "max"}] + [Pos ::= E "min" Pos · "max" Pos, {"+", "-", ">"}] prec p1 + Actions + "+" : ShiftPrefix 11 prec p0 + "-" : ShiftPrefix 12 prec p0 + "max" : ShiftPrefix 55 + Conflict contributions + Pos ::= E "min" Pos · "max" Pos + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 54 [29.1] + Kernel + [Pos ::= Pos · "+" EPair, {"+", "-", ","}] + [Pos ::= Pos · "-" EPair, {"+", "-", ","}] + [Pos ::= E "<" Pos · "," Pos ">", {"+", "-", ">"}] + Actions + "+" : ShiftPrefix 11 prec p0 + "-" : ShiftPrefix 12 prec p0 + "," : ShiftPrefix 56 prec p4 + Conflict contributions + Pos ::= E "<" Pos · "," Pos ">" + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 55 [38.1] + Kernel + [Pos ::= E "min" Pos "max" · Pos, {"+", "-", ">"}] prec p1 + Added + [Pos ::= · EPair, {"+", "-", ">"}] + [Pos ::= · Pos "+" EPair, {"+", "-", ">"}] + [Pos ::= · Pos "-" EPair, {"+", "-", ">"}] + [Pos ::= · "(" Pos "," Pos ")", {"+", "-", ">"}] + [Pos ::= · E "min" Pos "max" Pos, {"+", "-", ">"}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", ">"}] + [EPair ::= · E "," E, {"+", "-", ">"}] prec p4 + [EPair ::= · "(" EPair ")", {"+", "-", ">"}] + [E ::= · "var", {"+", "min", "<", ">", ","}] + [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] + [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 2 + Gotos + Pos : 57 + EPair : 5 + E : 45 + Conflict contributions + Pos ::= E "min" Pos "max" · Pos + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 56 [39.1] + Kernel + [Pos ::= E "<" Pos "," · Pos ">", {"+", "-", ">"}] + Added + [Pos ::= · EPair, {"+", "-", ">"}] + [Pos ::= · Pos "+" EPair, {"+", "-", ">"}] + [Pos ::= · Pos "-" EPair, {"+", "-", ">"}] + [Pos ::= · "(" Pos "," Pos ")", {"+", "-", ">"}] + [Pos ::= · E "min" Pos "max" Pos, {"+", "-", ">"}] prec p1 + [Pos ::= · E "<" Pos "," Pos ">", {"+", "-", ">"}] + [EPair ::= · E "," E, {"+", "-", ">"}] prec p4 + [EPair ::= · "(" EPair ")", {"+", "-", ">"}] + [E ::= · "var", {"+", "min", "<", ">", ","}] + [E ::= · E "+" E, {"+", "min", "<", ">", ","}] prec p0 + [E ::= · "(" E ")", {"+", "min", "<", ">", ","}] + [E ::= · E "<" E, {"+", "min", "<", ">", ","}] prec p3 + [E ::= · E ">" E, {"+", "min", "<", ">", ","}] prec p3 + Actions + "var" : ShiftPrefix 1 + "(" : ShiftPrefix 2 + Gotos + Pos : 44 + EPair : 5 + E : 45 + Conflict contributions + Pos ::= E "<" Pos "," · Pos ">" + ">" : + 27 : Reduce E ::= E "+" E + 30 : Reduce E ::= E "<" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + State 57 [42.1] + Kernel + [Pos ::= Pos · "+" EPair, {"+", "-", ">"}] + [Pos ::= Pos · "-" EPair, {"+", "-", ">"}] + [Pos ::= E "min" Pos "max" Pos ·, {"+", "-", ">"}] prec p1 + Actions + "+" : ShiftPrefix 46 prec p0 + "-" : ShiftPrefix 47 prec p0 + ">" : Reduce Pos ::= E "min" Pos "max" Pos prec p1 + Conflict contributions + Pos ::= Pos · "+" EPair + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E + Pos ::= Pos · "-" EPair + ">" : + 27 : Reduce E ::= E "+" E + 31 : Reduce E ::= E ">" E + 41 : Reduce E ::= E "<" E diff --git a/bootstrap/test/hocc/Lyken.expected b/bootstrap/test/hocc/Lyken.expected index 0e77726ae..2d8544837 100644 --- a/bootstrap/test/hocc/Lyken.expected +++ b/bootstrap/test/hocc/Lyken.expected @@ -7,6 +7,8 @@ hocc: Generating 1_375 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+........+.....+.....+.....+...+....+..+.+.+.+.++ hocc: 35 unreachable states hocc: Reindexing 1_340 LR(1) states +hocc: Searching for remergeable states: 0/0 +hocc: 0 remergeable states hocc: 0 unresolvable conflicts hocc: 15 unused precedence set associativities: hocc: left pColon < pGenericParamOne diff --git a/bootstrap/test/hocc/Menhir21Longer.expected b/bootstrap/test/hocc/Menhir21Longer.expected index 05a9f3e15..498335ffa 100644 --- a/bootstrap/test/hocc/Menhir21Longer.expected +++ b/bootstrap/test/hocc/Menhir21Longer.expected @@ -6,8 +6,10 @@ hocc: Generating LR(1) item set closures (workq/total) 0/33 hocc: Generating 33 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+....+.+.+.++.++ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/0 +hocc: 0 remergeable states hocc: 0 conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/Menhir21Longer.txt" hocc: Writing "./hocc/Menhir21Longer.hmh" diff --git a/bootstrap/test/hocc/Menhir21Shorter.expected b/bootstrap/test/hocc/Menhir21Shorter.expected index fc30908c6..45b1feee3 100644 --- a/bootstrap/test/hocc/Menhir21Shorter.expected +++ b/bootstrap/test/hocc/Menhir21Shorter.expected @@ -6,8 +6,10 @@ hocc: Generating LR(1) item set closures (workq/total) 0/22 hocc: Generating 22 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/1 +hocc: 0 remergeable states hocc: 0 conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/Menhir21Shorter.txt" hocc: Writing "./hocc/Menhir21Shorter.hmh" diff --git a/bootstrap/test/hocc/MulAddParen.expected b/bootstrap/test/hocc/MulAddParen.expected index adbcf582d..2537703ec 100644 --- a/bootstrap/test/hocc/MulAddParen.expected +++ b/bootstrap/test/hocc/MulAddParen.expected @@ -6,8 +6,10 @@ hocc: Generating LR(1) item set closures (workq/total) 0/15 hocc: Generating 15 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+.++.+.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/0 +hocc: 0 remergeable states hocc: 0 conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/MulAddParen.txt" hocc: Writing "./hocc/MulAddParen.hmh" diff --git a/bootstrap/test/hocc/MulAddParenPrec.expected b/bootstrap/test/hocc/MulAddParenPrec.expected index 4db5acbad..f8f88ce77 100644 --- a/bootstrap/test/hocc/MulAddParenPrec.expected +++ b/bootstrap/test/hocc/MulAddParenPrec.expected @@ -20,6 +20,6 @@ hocc: E ::= E PLUS T prec p2 hocc: F ::= LPAREN E RPAREN prec p1 hocc: F ::= ID prec p1 hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/MulAddParenPrec.txt" hocc: Writing "./hocc/MulAddParenPrec.hmh" diff --git a/bootstrap/test/hocc/NestedEpsilon.expected b/bootstrap/test/hocc/NestedEpsilon.expected index b46f249a4..cfd228561 100644 --- a/bootstrap/test/hocc/NestedEpsilon.expected +++ b/bootstrap/test/hocc/NestedEpsilon.expected @@ -6,8 +6,8 @@ hocc: Generating LR(1) item set closures (workq/total) 0/9 hocc: Generating 9 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+.+++.+.+ hocc: 0 unreachable states -hocc: State subgraph remerging disabled due to unresolvable conflicts -hocc: Explicitly enable remerging (-remerge yes) to override +hocc: Searching for remergeable states: 0/0 +hocc: 0 remergeable states hocc: 1 unresolvable conflict in 1 state (0 ⊥, 0 shift-reduce, 1 reduce-reduce) hocc: Generating text report hocc: Writing "./hocc/NestedEpsilon.txt" diff --git a/bootstrap/test/hocc/PSEUDO_END_conflict.expected b/bootstrap/test/hocc/PSEUDO_END_conflict.expected index 6d53aab84..4dc4062a3 100644 --- a/bootstrap/test/hocc/PSEUDO_END_conflict.expected +++ b/bootstrap/test/hocc/PSEUDO_END_conflict.expected @@ -10,6 +10,6 @@ hocc: Searching for remergeable states: 0/0 hocc: 0 remergeable states hocc: 4 unresolvable conflicts in 4 states (4 ⊥, 0 shift-reduce, 0 reduce-reduce) hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/PSEUDO_END_conflict.txt" hocc: Writing "./hocc/PSEUDO_END_conflict.hmh" diff --git a/bootstrap/test/hocc/PagerG2.expected b/bootstrap/test/hocc/PagerG2.expected index 455fb69a1..b7a3b585a 100644 --- a/bootstrap/test/hocc/PagerG2.expected +++ b/bootstrap/test/hocc/PagerG2.expected @@ -7,8 +7,10 @@ hocc: Generating 27 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+.+.+.+ hocc: 1 unreachable state hocc: Reindexing 26 LR(1) states +hocc: Searching for remergeable states: 0/2 +hocc: 0 remergeable states hocc: 0 conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/PagerG2.txt" hocc: Writing "./hocc/PagerG2.hmh" diff --git a/bootstrap/test/hocc/PagerG2_aielr.expected b/bootstrap/test/hocc/PagerG2_aielr.expected index af3d09d3f..ecbcdc1ad 100644 --- a/bootstrap/test/hocc/PagerG2_aielr.expected +++ b/bootstrap/test/hocc/PagerG2_aielr.expected @@ -12,8 +12,10 @@ hocc: Generating LR(1) item set closures (workq/total) 0/26 hocc: Generating 26 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+...+.+.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 0/2 +hocc: 0 remergeable states hocc: 0 unresolvable conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/PagerG2_aielr.txt" hocc: Writing "./hocc/PagerG2_aielr.hmh" diff --git a/bootstrap/test/hocc/PagerG2_gno.expected b/bootstrap/test/hocc/PagerG2_gno.expected index 8265d7c47..a2b374fb5 100644 --- a/bootstrap/test/hocc/PagerG2_gno.expected +++ b/bootstrap/test/hocc/PagerG2_gno.expected @@ -4,6 +4,9 @@ hocc: 0 precedences, 10 tokens, 8 non-terminals (1 start), 14 productions hocc: LR(1) item set compatibility: weak hocc: Generating LR(1) item set closures (workq/total) 0/27 hocc: Generating 27 LR(1) states +hocc: Searching for remergeable states: 1/3 +hocc: Remerging 1 LR(1) state +hocc: Reindexing 26 LR(1) states hocc: 0 conflicts hocc: Generating text report hocc: Writing "./hocc/PagerG2_gno.txt" diff --git a/bootstrap/test/hocc/PagerG2_gno.expected.txt b/bootstrap/test/hocc/PagerG2_gno.expected.txt index 39b1f3187..df3d27459 100644 --- a/bootstrap/test/hocc/PagerG2_gno.expected.txt +++ b/bootstrap/test/hocc/PagerG2_gno.expected.txt @@ -108,7 +108,7 @@ PGM LR(1) States [Tn ::= · Ut Xn At, {At, Dt, Et, EOI}] Actions Tt : ShiftPrefix 5 - Ut : ShiftPrefix 19 + Ut : ShiftPrefix 6 Gotos Yn : 7 Zn : 8 @@ -125,7 +125,7 @@ PGM LR(1) States [Tn ::= · Ut Xn At, {At, Dt, Et, EOI}] Actions Tt : ShiftPrefix 10 - Ut : ShiftPrefix 19 + Ut : ShiftPrefix 6 Gotos Yn : 11 Zn : 12 @@ -153,7 +153,7 @@ PGM LR(1) States State 6 [6.0] Kernel [Yn ::= Ut · Xn, {Dt, Et}] - [Tn ::= Ut · Xn At, {EOI}] + [Tn ::= Ut · Xn At, {At, Dt, Et, EOI}] Added [Xn ::= · At Yn Dt, {At, Dt, Et}] [Xn ::= · At Zn Ct, {At, Dt, Et}] @@ -170,12 +170,12 @@ PGM LR(1) States Kernel [Xn ::= At Yn · Dt, {At, Dt, Et, EOI}] Actions - Dt : ShiftPrefix 20 + Dt : ShiftPrefix 19 State 8 [8.0] Kernel [Xn ::= At Zn · Ct, {At, Dt, Et, EOI}] Actions - Ct : ShiftPrefix 21 + Ct : ShiftPrefix 20 State 9 [9.0] Kernel [Xn ::= At Tn ·, {At, Dt, Et, EOI}] @@ -191,19 +191,19 @@ PGM LR(1) States Added [Wn ::= · Ut Vn, {Et}] Actions - Ut : ShiftPrefix 22 + Ut : ShiftPrefix 21 Gotos Wn : 17 State 11 [10.0] Kernel [Xn ::= Bt Yn · Et, {At, Dt, Et, EOI}] Actions - Et : ShiftPrefix 23 + Et : ShiftPrefix 22 State 12 [11.0] Kernel [Xn ::= Bt Zn · Dt, {At, Dt, Et, EOI}] Actions - Dt : ShiftPrefix 24 + Dt : ShiftPrefix 23 State 13 [12.0] Kernel [Xn ::= Bt Tn ·, {At, Dt, Et, EOI}] @@ -232,7 +232,7 @@ PGM LR(1) States Ct : Reduce Zn ::= Tt Ut Dt : Reduce Vn ::= epsilon Gotos - Vn : 25 + Vn : 24 State 17 [16.0] Kernel [Yn ::= Tt Wn ·, {Dt, Et}] @@ -244,26 +244,10 @@ PGM LR(1) States [Yn ::= Ut Xn ·, {Dt, Et}] [Tn ::= Ut Xn · At, {At, Dt, Et, EOI}] Actions - At : ShiftPrefix 26 + At : ShiftPrefix 25 Dt : Reduce Yn ::= Ut Xn Et : Reduce Yn ::= Ut Xn - State 19 [6.1] - Kernel - [Yn ::= Ut · Xn, {Dt, Et}] - [Tn ::= Ut · Xn At, {At, Dt, Et, EOI}] - Added - [Xn ::= · At Yn Dt, {At, Dt, Et}] - [Xn ::= · At Zn Ct, {At, Dt, Et}] - [Xn ::= · At Tn, {At, Dt, Et}] - [Xn ::= · Bt Yn Et, {At, Dt, Et}] - [Xn ::= · Bt Zn Dt, {At, Dt, Et}] - [Xn ::= · Bt Tn, {At, Dt, Et}] - Actions - At : ShiftPrefix 1 - Bt : ShiftPrefix 2 - Gotos - Xn : 18 - State 20 [18.0] + State 19 [18.0] Kernel [Xn ::= At Yn Dt ·, {At, Dt, Et, EOI}] Actions @@ -271,7 +255,7 @@ PGM LR(1) States Dt : Reduce Xn ::= At Yn Dt Et : Reduce Xn ::= At Yn Dt EOI : Reduce Xn ::= At Yn Dt - State 21 [19.0] + State 20 [19.0] Kernel [Xn ::= At Zn Ct ·, {At, Dt, Et, EOI}] Actions @@ -279,7 +263,7 @@ PGM LR(1) States Dt : Reduce Xn ::= At Zn Ct Et : Reduce Xn ::= At Zn Ct EOI : Reduce Xn ::= At Zn Ct - State 22 [15.1] + State 21 [15.1] Kernel [Zn ::= Tt Ut ·, {Dt}] [Wn ::= Ut · Vn, {Et}] @@ -289,8 +273,8 @@ PGM LR(1) States Dt : Reduce Zn ::= Tt Ut Et : Reduce Vn ::= epsilon Gotos - Vn : 25 - State 23 [20.0] + Vn : 24 + State 22 [20.0] Kernel [Xn ::= Bt Yn Et ·, {At, Dt, Et, EOI}] Actions @@ -298,7 +282,7 @@ PGM LR(1) States Dt : Reduce Xn ::= Bt Yn Et Et : Reduce Xn ::= Bt Yn Et EOI : Reduce Xn ::= Bt Yn Et - State 24 [21.0] + State 23 [21.0] Kernel [Xn ::= Bt Zn Dt ·, {At, Dt, Et, EOI}] Actions @@ -306,13 +290,13 @@ PGM LR(1) States Dt : Reduce Xn ::= Bt Zn Dt Et : Reduce Xn ::= Bt Zn Dt EOI : Reduce Xn ::= Bt Zn Dt - State 25 [22.0] + State 24 [22.0] Kernel [Wn ::= Ut Vn ·, {Dt, Et}] Actions Dt : Reduce Wn ::= Ut Vn Et : Reduce Wn ::= Ut Vn - State 26 [23.0] + State 25 [23.0] Kernel [Tn ::= Ut Xn At ·, {At, Dt, Et, EOI}] Actions diff --git a/bootstrap/test/hocc/PagerG3.expected b/bootstrap/test/hocc/PagerG3.expected index 0bf396381..809c91034 100644 --- a/bootstrap/test/hocc/PagerG3.expected +++ b/bootstrap/test/hocc/PagerG3.expected @@ -6,8 +6,11 @@ hocc: Generating LR(1) item set closures (workq/total) 0/19 hocc: Generating 19 LR(1) states hocc: Tracing automaton (.+=actions[+gotos])+....+.+.+ hocc: 0 unreachable states +hocc: Searching for remergeable states: 2/2 +hocc: Remerging 2 LR(1) states +hocc: Reindexing 17 LR(1) states hocc: 0 conflicts hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/PagerG3.txt" hocc: Writing "./hocc/PagerG3.hmh" diff --git a/bootstrap/test/hocc/PagerG3.expected.txt b/bootstrap/test/hocc/PagerG3.expected.txt index 9bbfc45ed..fa0728c42 100644 --- a/bootstrap/test/hocc/PagerG3.expected.txt +++ b/bootstrap/test/hocc/PagerG3.expected.txt @@ -92,93 +92,80 @@ PGM LR(1) States [Y ::= · T U V, {E}] [Z ::= · T U W, {D}] Actions - T : ShiftPrefix 7 + T : ShiftPrefix 4 Gotos - Y : 8 - Z : 9 + Y : 7 + Z : 8 State 3 [3.0] Kernel [X' ::= X · "⊥", {"ε"}] Actions - "⊥" : ShiftPrefix 10 + "⊥" : ShiftPrefix 9 State 4 [4.0] Kernel - [Y ::= T · U V, {D}] - [Z ::= T · U W, {C}] + [Y ::= T · U V, {D, E}] + [Z ::= T · U W, {C, D}] Actions - U : ShiftPrefix 11 + U : ShiftPrefix 10 State 5 [5.0] Kernel [X ::= A Y · D, {"⊥"}] Actions - D : ShiftAccept 12 + D : ShiftAccept 11 State 6 [6.0] Kernel [X ::= A Z · C, {"⊥"}] Actions - C : ShiftAccept 13 - State 7 [4.1] - Kernel - [Y ::= T · U V, {E}] - [Z ::= T · U W, {D}] - Actions - U : ShiftPrefix 14 - State 8 [7.0] + C : ShiftAccept 12 + State 7 [7.0] Kernel [X ::= B Y · E, {"⊥"}] Actions - E : ShiftAccept 15 - State 9 [8.0] + E : ShiftAccept 13 + State 8 [8.0] Kernel [X ::= B Z · D, {"⊥"}] Actions - D : ShiftAccept 16 - State 10 [9.0] + D : ShiftAccept 14 + State 9 [9.0] Kernel [X' ::= X "⊥" ·, {"ε"}] Actions "ε" : Reduce X' ::= X "⊥" - State 11 [10.0] + State 10 [10.0] Kernel - [Y ::= T U · V, {D}] - [Z ::= T U · W, {C}] + [Y ::= T U · V, {D, E}] + [Z ::= T U · W, {C, D}] Actions - V : ShiftPrefix 17 - W : ShiftPrefix 18 - State 12 [11.0] + V : ShiftPrefix 15 + W : ShiftPrefix 16 + State 11 [11.0] Kernel [X ::= A Y D ·, {"⊥"}] Actions "⊥" : Reduce X ::= A Y D - State 13 [12.0] + State 12 [12.0] Kernel [X ::= A Z C ·, {"⊥"}] Actions "⊥" : Reduce X ::= A Z C - State 14 [10.1] - Kernel - [Y ::= T U · V, {E}] - [Z ::= T U · W, {D}] - Actions - V : ShiftPrefix 17 - W : ShiftPrefix 18 - State 15 [13.0] + State 13 [13.0] Kernel [X ::= B Y E ·, {"⊥"}] Actions "⊥" : Reduce X ::= B Y E - State 16 [14.0] + State 14 [14.0] Kernel [X ::= B Z D ·, {"⊥"}] Actions "⊥" : Reduce X ::= B Z D - State 17 [15.0] + State 15 [15.0] Kernel [Y ::= T U V ·, {D, E}] Actions D : Reduce Y ::= T U V E : Reduce Y ::= T U V - State 18 [16.0] + State 16 [16.0] Kernel [Z ::= T U W ·, {C, D}] Actions diff --git a/bootstrap/test/hocc/Unused.expected b/bootstrap/test/hocc/Unused.expected index d78794bfc..aa464a59e 100644 --- a/bootstrap/test/hocc/Unused.expected +++ b/bootstrap/test/hocc/Unused.expected @@ -23,6 +23,6 @@ hocc: NUnusedA ::= NUnusedB prec pUnusedA hocc: NUnusedA ::= epsilon prec pUnusedA hocc: NUnusedB ::= TUnusedA hocc: Generating text report -hocc: Generating hocc report +hocc: Generating Hocc report hocc: Writing "./hocc/Unused.txt" hocc: Writing "./hocc/Unused.hmh" diff --git a/bootstrap/test/hocc/dune b/bootstrap/test/hocc/dune index 811bbef91..d4083be12 100644 --- a/bootstrap/test/hocc/dune +++ b/bootstrap/test/hocc/dune @@ -208,7 +208,7 @@ %{bin:hocc}) (action (with-accepted-exit-codes 0 - (with-outputs-to help_a.out (run %{bin:hocc} -v -verbose -w -warn -txt -text -hmh -hocc -a aplr -algorithm aplr -hm -hemlock -ml -ocaml -s Foo -src Foo -d bar -dstdir bar -h))))) + (with-outputs-to help_a.out (run %{bin:hocc} -v -verbose -w -warn -txt -text -hmh -hocc -y -yacc -a aplr -algorithm aplr -hm -hemlock -ml -ocaml -s Foo -src Foo -d bar -dstdir bar -h))))) (rule (alias runtest) (action (diff help_a.expected help_a.out))) @@ -218,7 +218,7 @@ %{bin:hocc}) (action (with-accepted-exit-codes 1 - (with-outputs-to help_b.out (run %{bin:hocc} -v -verbose -w -warn -txt -text -hmh -hocc -a aplr -algorithm aplr -hm -hemlock -ml -ocaml -s Foo -src Foo -d bar -dstdir bar -no-such-option))))) + (with-outputs-to help_b.out (run %{bin:hocc} -v -verbose -w -warn -txt -text -hmh -hocc -y -yacc -a aplr -algorithm aplr -hm -hemlock -ml -ocaml -s Foo -src Foo -d bar -dstdir bar -no-such-option))))) (rule (alias runtest) (action (diff help_b.expected help_b.out))) @@ -227,17 +227,18 @@ (deps (glob_files Hocc.hmh*) %{bin:hocc}) - (targets Hocc.out.txt Hocc.out.hmh) + (targets Hocc.out.txt Hocc.out.hmh Hocc.out.y) (action (with-accepted-exit-codes 0 - (with-outputs-to Hocc.out (run ./hocc_test %{bin:hocc} Hocc -v -w -txt -hmh))))) + (with-outputs-to Hocc.out (run ./hocc_test %{bin:hocc} Hocc -v -w -txt -hmh -yacc))))) (rule (alias runtest) (action (progn (diff Hocc.expected Hocc.out) (diff Hocc.expected.txt Hocc.out.txt) - (diff Hocc.expected.hmh Hocc.out.hmh)))) + (diff Hocc.expected.hmh Hocc.out.hmh) + (diff Hocc.expected.y Hocc.out.y)))) (rule (deps @@ -496,16 +497,16 @@ (deps (glob_files IelrRemergeable.hmh*) %{bin:hocc}) - (targets IelrRemergeable_aielr_myes.out.txt) + (targets IelrRemergeable_aielr_mno.out.txt) (action (with-accepted-exit-codes 0 - (with-outputs-to IelrRemergeable_aielr_myes.out (run ./hocc_test %{bin:hocc} IelrRemergeable -algorithm ielr -remerge yes -v -w -txt))))) + (with-outputs-to IelrRemergeable_aielr_mno.out (run ./hocc_test %{bin:hocc} IelrRemergeable -algorithm ielr -remerge no -v -w -txt))))) (rule (alias runtest) (action (progn - (diff IelrRemergeable_aielr_myes.expected IelrRemergeable_aielr_myes.out) - (diff IelrRemergeable_aielr_myes.expected.txt IelrRemergeable_aielr_myes.out.txt)))) + (diff IelrRemergeable_aielr_mno.expected IelrRemergeable_aielr_mno.out) + (diff IelrRemergeable_aielr_mno.expected.txt IelrRemergeable_aielr_mno.out.txt)))) (rule (deps diff --git a/bootstrap/test/hocc/help_a.expected b/bootstrap/test/hocc/help_a.expected index aadad6844..a12420434 100644 --- a/bootstrap/test/hocc/help_a.expected +++ b/bootstrap/test/hocc/help_a.expected @@ -7,8 +7,10 @@ Parameters: -w[arn] : Warn about unused grammar constructs. -txt | -text : Write a detailed automaton description in plain text format to "/hocc/.txt". - -hmh | -hocc : Write a complete grammar specification in hocc format to + -hmh | -hocc : Write a complete grammar specification in Hocc format to "/hocc/.hmh". + -y[acc] : Write a complete grammar specification in Yacc format to + "/hocc/.y". -a[lgorithm] : Use the specified orithm for generating an automaton. Defaults to aplr. - aplr: Adequacy Preservation LR(1) @@ -19,7 +21,8 @@ Parameters: -r[esolve] (yes|no) : Control conflict resolution enablement. Defaults to yes for aplr/ielr/lr algorithms, no for pgm/lalr algorithms. -[re]m[erge] (yes|no) : Control compatible state subgraph remerging enablement. - Defaults to yes for aplr algorithm, no otherwise. + Defaults to yes for aplr/ielr/pgm algorithms, no for + lr/lalr algorithms. -g[c] (pre|post|no) : Control unreachable state garbage collection enablement and ordering relative to remerging. Defaults to post-remerging. diff --git a/bootstrap/test/hocc/help_b.expected b/bootstrap/test/hocc/help_b.expected index 68ce1e30f..de5e83e16 100644 --- a/bootstrap/test/hocc/help_b.expected +++ b/bootstrap/test/hocc/help_b.expected @@ -8,8 +8,10 @@ Parameters: -w[arn] : Warn about unused grammar constructs. -txt | -text : Write a detailed automaton description in plain text format to "/hocc/.txt". - -hmh | -hocc : Write a complete grammar specification in hocc format to + -hmh | -hocc : Write a complete grammar specification in Hocc format to "/hocc/.hmh". + -y[acc] : Write a complete grammar specification in Yacc format to + "/hocc/.y". -a[lgorithm] : Use the specified orithm for generating an automaton. Defaults to aplr. - aplr: Adequacy Preservation LR(1) @@ -20,7 +22,8 @@ Parameters: -r[esolve] (yes|no) : Control conflict resolution enablement. Defaults to yes for aplr/ielr/lr algorithms, no for pgm/lalr algorithms. -[re]m[erge] (yes|no) : Control compatible state subgraph remerging enablement. - Defaults to yes for aplr algorithm, no otherwise. + Defaults to yes for aplr/ielr/pgm algorithms, no for + lr/lalr algorithms. -g[c] (pre|post|no) : Control unreachable state garbage collection enablement and ordering relative to remerging. Defaults to post-remerging. diff --git a/bootstrap/test/hocc/hocc_test b/bootstrap/test/hocc/hocc_test index 69104c48f..63d1fbfb8 100755 --- a/bootstrap/test/hocc/hocc_test +++ b/bootstrap/test/hocc/hocc_test @@ -95,5 +95,6 @@ mv_report() { } mv_report txt mv_report hmh +mv_report y exit ${exit_code} diff --git a/doc/reports/ielr1/ielr1.md b/doc/reports/ielr1/ielr1.md index 2f4fea692..8f1335812 100644 --- a/doc/reports/ielr1/ielr1.md +++ b/doc/reports/ielr1/ielr1.md @@ -1,19 +1,19 @@ -# IELR(1) as Implemented by `hocc` +# IELR(1) as Implemented by Hocc [This is a living version of an originally web-published technical report. [^evans2024]] -The `hocc` parser generator, which is part of the [Hemlock](https://github.com/BranchTaken/Hemlock) +The Hocc parser generator, which is part of the [Hemlock](https://github.com/BranchTaken/Hemlock) programming language project, implements several LR(1)-family parser generation algorithms, namely [LALR(1)](https://en.wikipedia.org/wiki/LALR_parser) [^deremer1969], [canonical LR(1)](https://en.wikipedia.org/wiki/LR_parser) [^knuth1965], PGM(1) [^pager1977][^fpottier], and IELR(1) [^denny2010]. These algorithms are amply documented and (re-)implemented, with the notable exception of IELR(1), which is documented only in the original paper and implemented only by the -original authors in [`bison`](https://www.gnu.org/software/bison/). This posed extreme -implementation challenges in the context of `hocc`. The IELR(1) paper is closely tied to the -particulars of the `bison` implementation, and perhaps for that reason the terminology and structure +original authors in [Bison](https://www.gnu.org/software/bison/). This posed extreme +implementation challenges in the context of Hocc. The IELR(1) paper is closely tied to the +particulars of the Bison implementation, and perhaps for that reason the terminology and structure are closely based on the idiosyncrasies of DeRemer's presentation of LALR(1). This terminology -diverges substantially from that of Pager's presentation of PGM(1), whence `hocc` took original -inspiration. This report recasts the IELR(1) algorithm as distilled during `hocc` implementation, +diverges substantially from that of Pager's presentation of PGM(1), whence Hocc took original +inspiration. This report recasts the IELR(1) algorithm as distilled during Hocc implementation, giving a pragmatic high-level perspective more conducive to straightforward (if less efficient) implementation than that provided by the original paper. @@ -41,15 +41,15 @@ parsers recognize the same grammars. The remainder of this report overviews the canonical LR(1) parser generation algorithm with a focus on concepts upon which IELR(1) builds, briefly describes LALR(1), then presents IELR(1) as -implemented by `hocc`. The perspective is primarily LR(1)-relative, which differs substantially from +implemented by Hocc. The perspective is primarily LR(1)-relative, which differs substantially from the LALR(1)-relative exposition of the original IELR(1) paper. ## Canonical LR(1) ### Terminology -The following common example "arithmetic" grammar in `hocc` format suffices for defining various -relevant terms as they are used in the `hocc` source code. +The following common example "arithmetic" grammar in Hocc format suffices for defining various +relevant terms as they are used in the Hocc source code. ```hocc hocc @@ -100,11 +100,11 @@ all LR(1) items. It is possible (and common in canonical LR(1) parsers) for non- isocores. Parser generators have long supported grammar disambiguation via precedence and associativity. For -example `mul` has higher precedence than `add`, both of which are left-associative. `hocc` differs +example `mul` has higher precedence than `add`, both of which are left-associative. Hocc differs from most parser generators in that precedences comprise an explicit optionally-disjoint directed acyclic graph, rather than a mostly implicit single linear precedence order. Furthermore, since -`hocc` supports neutral associativity (`%precedence` in -[`bison`](https://www.gnu.org/software/bison/manual/bison.html#Precedence-Decl)), non-associativity +Hocc supports neutral associativity (`%precedence` in +[Bison](https://www.gnu.org/software/bison/manual/bison.html#Precedence-Decl)), non-associativity is of limited practical use (`%nonassoc` in [YACC](https://en.wikipedia.org/wiki/Yacc)-family parser generators). These deviations from the status quo avoid masking grammar flaws and increase specification precision. @@ -217,8 +217,8 @@ LR(1) parser. Such parsers are **_LR(1)-inadequate_**. ## IELR(1) The IELR(1) algorithm is substantially more complicated than canonical LR(1) or LALR(1). The IELR(1) -paper [^denny2010] describes six stages as implemented by `bison`, three of which directly -correspond to stages in `hocc`: +paper [^denny2010] describes six stages as implemented by Bison, three of which directly +correspond to stages in Hocc: 1. Generate the LALR(1) state machine, with conflict resolution disabled so that later analysis can discover and analyze ambiguities. @@ -237,7 +237,7 @@ abstractions. The remainder of this section describes these two phases in detail A characteristic [finite state machine](https://en.wikipedia.org/wiki/Finite-state_machine) generated by any of the LR(1)-family algorithms is a [pushdown automaton](https://en.wikipedia.org/wiki/Pushdown_automaton). Such state machines maintain a stack -while traversing a [digraph](https://en.wikipedia.org/wiki/Directed_graph). The `hocc` code uses the +while traversing a [digraph](https://en.wikipedia.org/wiki/Directed_graph). The Hocc code uses the following terminology related to state machine digraphs: - **_state_**: Vertex, node @@ -307,7 +307,7 @@ hocc nonterm Vn ::= epsilon ``` -As analyzed by `hocc` in LALR(1)/IELR(1) mode, this results in the following state subgraphs +As analyzed by Hocc in LALR(1)/IELR(1) mode, this results in the following state subgraphs (inconsequential states omitted for brevity): ``` @@ -404,7 +404,7 @@ reduce action contribution can converge anywhere in the transitive predecessor g The useful G2 grammar annotations indicate that states 5 and 15 must be split in order to remove inadequacies. Following are lightly edited excerpts from [LALR(1)](G2_lalr1.txt) and -[IELR(1)](G2_ielr1.txt) `hocc` reports showing the state splits. +[IELR(1)](G2_ielr1.txt) Hocc reports showing the state splits. ``` LALR(1) @@ -505,7 +505,7 @@ backward through a state's added items to determine which kernel items are impli the conflict being traced. The naíve approach to this computation suffices, but for complicated grammars memoization is a superlinear optimization that can improve overall performance by over 10X. -The precise details of trace initialization are intricate enough that the `hocc` +The precise details of trace initialization are intricate enough that the Hocc [implementation](https://github.com/BranchTaken/Hemlock/tree/main/bootstrap/bin/hocc/) serves as a clearer explanation than would further verbiage. That said, it is worth calling out that lane tracing operates on kernel items rather than kernels as a whole, which can be especially confusing @@ -533,7 +533,7 @@ state nub, the goto nub is merged into the state nub, including its kernel attri ## Remerging -Redundant states can arise during IELR(1) state machine closure because `hocc` splits lanes that may +Redundant states can arise during IELR(1) state machine closure because Hocc splits lanes that may lead to differing conflict resolutions, even though some split lanes may reconverge. These redundancies can be removed via a limited form of state remerging that iteratively merges states with isomorphic isucc graphs. Specifically, two isocoric states are remergeable if for all action @@ -546,10 +546,10 @@ lookaheads one of the following holds: Iterative application of state remerging in practice works backward through the state graph, because remerging isocoric states' successors may enable subsequent remerging. -Although remerging was initially motivated by IELR(1) in `hocc`, it also minorly benefits PGM(1), +Although remerging was initially motivated by IELR(1) in Hocc, it also minorly benefits PGM(1), and majorly benefits canonical LR(1). Given the same grammar, canonical LR(1) tends to generate roughly ten times more states than does LALR(1)/PGM(1)/IELR(1). Initial results indicate that -remerging reduces that from a factor of ~10 to a factor of ~4. For example, consider `hocc` results +remerging reduces that from a factor of ~10 to a factor of ~4. For example, consider Hocc results for the `Gpic` grammar originally analyzed in the IELR(1) paper [^denny2010]. | Algoritm | # of states | Ratio | @@ -564,41 +564,40 @@ for the `Gpic` grammar originally analyzed in the IELR(1) paper [^denny2010]. \* — no remerging -Interestingly, `bison` generates 428 states for `Gpic` even though it lacks a remerging -implementation. `bison` presumably omits remergeable states by generating states in a different -order, but to my knowledge there is no tractable approach which universally eliminates remerging -utility. +Interestingly, Bison generates 428 states for `Gpic` even though it lacks a remerging +implementation. Bison presumably omits remergeable states by generating states in a different order, +but to my knowledge there is no tractable approach which universally eliminates remerging utility. ## Performance -The `hocc` implementation of IELR(1) is dramatically slower than that of `bison`. The following wall -clock times for the `Gpic` grammar are representative. Both `hocc` and `bison` are configured to -emit no reports nor generated code (`hocc` has remerging and unreachable state garbage collection +The Hocc implementation of IELR(1) is dramatically slower than that of Bison. The following wall +clock times for the `Gpic` grammar are representative. Both Hocc and Bison are configured to +emit no reports nor generated code (Hocc has remerging and unreachable state garbage collection disabled), and the reported numbers are the best of three runs on an AMD EPYC 7742 CPU running -Ubuntu Linux 24.04, using OCaml 5.4.0 with flambda enabled for `hocc` -main-0-g1cade600f4cfa931a9b481739a9a641ff3583637 versus the vendor-supplied `bison` 3.8.2. +Ubuntu Linux 24.04, using OCaml 5.4.0 with flambda enabled for Hocc +main-0-g1cade600f4cfa931a9b481739a9a641ff3583637 versus the vendor-supplied Bison 3.8.2. -| Algorithm | hocc | bison | +| Algorithm | Hocc | Bison | |:----------|------:|--------:| | LALR(1) | 0.964 | 0.017 | | PGM(1) | 1.052 | — | | IELR(1) | 5.576 | 0.029 | | LR(1) | 3.843 | 1.527 | -`bison` is a [C](https://en.wikipedia.org/wiki/C_(programming_language)) application that relies on -flat and linearly allocated mutable global data structures, whereas `hocc` is an +Bison is a [C](https://en.wikipedia.org/wiki/C_(programming_language)) application that relies on +flat and linearly allocated mutable global data structures, whereas Hocc is an [OCaml](https://ocaml.org/) application that relies on high-level purely functional data structures. -`hocc` uses maps in many places where a custom low-level data structure would perform much better, -albeit at the cost of code clarity and maintainability. More critically, `hocc` is implemented on -top of the `Basis` library, which is an OCaml-native standard library intended to correspond closely -to the standard library designed for the [Hemlock](https://github.com/BranchTaken/Hemlock) -programming language. OCaml unfortunately provides 63-bit integers as its default high-performance -integer type, but Hemlock's design calls for 64-bit integers. As a consequence, `Basis` ubiquitously -uses OCaml's boxed 64-bit integers, which imposes an epic load on OCaml's automatic memory -management subsystem. These `Basis`-related implementation quirks could easily account for ~10X of -the `hocc`-`bison` performance gap, saying nothing of the high-level data structure overhead. -Nonetheless, current performance meets practical requirements for Hemlock bootstrapping, and further -optimization is left as an exercise for the aspirational Hemlock-native `hocc` implementation. +Hocc uses maps in many places where a custom low-level data structure would perform much better, +albeit at the cost of code clarity and maintainability. More critically, Hocc is implemented on top +of the `Basis` library, which is an OCaml-native standard library intended to correspond closely to +the standard library designed for the [Hemlock](https://github.com/BranchTaken/Hemlock) programming +language. OCaml unfortunately provides 63-bit integers as its default high-performance integer type, +but Hemlock's design calls for 64-bit integers. As a consequence, `Basis` ubiquitously uses OCaml's +boxed 64-bit integers, which imposes an epic load on OCaml's automatic memory management subsystem. +These `Basis`-related implementation quirks could easily account for ~10X of the Hocc-Bison +performance gap, saying nothing of the high-level data structure overhead. Nonetheless, current +performance meets practical requirements for Hemlock bootstrapping, and further optimization is left +as an exercise for the aspirational Hemlock-native Hocc implementation. A basic IELR(1) implementation can get away without two of the refinements described in this report, namely useless annotation filtering and leftmost transitive closure memoization. That said, @@ -615,15 +614,15 @@ to substantial speedup, e.g. ~2.7X for `Gpic`. ## Conclusion This report is intended to help others bypass the morass that IELR(1) implementation turned out to -be in the context of `hocc`. My initial intention regarding IELR(1) was to demonstrate that it has +be in the context of Hocc. My initial intention regarding IELR(1) was to demonstrate that it has no practical utility relative to PGM(1), but careful rereading of the IELR(1) paper convinced me -otherwise. Full understanding was elusive, and the `hocc` implementation is in large part a +otherwise. Full understanding was elusive, and the Hocc implementation is in large part a re-invention given the benefits of an imperfectly understood paper and an existence proof in the -form of `bison`. +form of Bison. -Although `hocc` is primarily a Hemlock-targeting parser generator, it is also generally useful for +Although Hocc is primarily a Hemlock-targeting parser generator, it is also generally useful for grammar experimentation/validation due to its clean syntax when omitting embedded reduction code. -More importantly in the context of this report, `hocc` serves as a straightforward reference +More importantly in the context of this report, Hocc serves as a straightforward reference implementation of IELR(1), even to implementers who are unfamiliar with OCaml. Choice of data structures is key to implementation, and OCaml record syntax is self-evident to experienced programmers, e.g. `Prod.t` as defined in the `prod.mli` interface file: @@ -666,7 +665,7 @@ grammars with it. [^evans2024]: Jason Evans, - “IELR(1) as Implemented by `hocc`”, + “IELR(1) as Implemented by Hocc”, BranchTaken LLC, [https://branchtaken.com/reports/ielr1.html](https://branchtaken.com/reports/ielr1.html), July 2024. diff --git a/doc/tools/hocc.md b/doc/tools/hocc.md index f21154b70..f0bb09766 100644 --- a/doc/tools/hocc.md +++ b/doc/tools/hocc.md @@ -1,27 +1,28 @@ -# hocc +# Hocc -`hocc` is an [LR(1) parser generator](https://en.wikipedia.org/wiki/Canonical_LR_parser). Its name +Hocc is an [LR(1) parser generator](https://en.wikipedia.org/wiki/Canonical_LR_parser). Its name carries on a long tradition, to wit: -- [`yacc`](https://en.wikipedia.org/wiki/Yacc) stands for "Yet Another Compiler Compiler". Clearly - the name derives from "yack", as in, "Chuck's dinner didn't sit well and he yacked it." -- `hocc` stands for "Hardly Original Compiler Compiler". The name derives from "hock", as in, "Hank +- [Yacc](https://en.wikipedia.org/wiki/Yacc) stands for "Yet Another Compiler Compiler". Clearly the + name derives from "yack", as in, "Chuck's dinner didn't sit well and he yacked it." +- Hocc stands for "Hardly Original Compiler Compiler". The name derives from "hock", as in, "Hank hocked a loogie." Both programs interpret high-level human-written parser descriptions and produce output unfit for -human consumption. However `hocc` has several distinguishing features relative to `yacc`, aside from +human consumption. However Hocc has several distinguishing features relative to Yacc, aside from integrating with [Hemlock](https://github.com/BranchTaken/Hemlock) rather than [C](https://en.wikipedia.org/wiki/The_C_Programming_Language). -- `hocc` generates LR(1) rather than [LALR(1)](https://en.wikipedia.org/wiki/LALR_parser) parsers, - optionally using behavior-preserving algorithms that reduce the state machine size relative to the - canonical LR(1) algorithm [^knuth1965]. -- `hocc`'s precedence facilities are more precise and easier to use without inadvertently masking - grammar ambiguities. Whereas `yacc` supports only a single linear precedence ordering, `hocc` - supports arbitrarily many directed acyclic precedence graphs. Given this more powerful conflict - resolution mechanism, `hocc` refuses to generate parsers for ambiguous grammars. -- `hocc` supports an automated error recovery algorithm [^diekmann2020] based on minimum-cost repair - sequences. [XXX Not implemented.] +- Hocc defaults to generating compact LR(1) rather than + [LALR(1)](https://en.wikipedia.org/wiki/LALR_parser) parsers, using behavior-preserving algorithms + that reduce the state machine size relative to the canonical LR(1) algorithm [^knuth1965]. +- Hocc's precedence facilities are more precise and easier to use without inadvertently masking + grammar ambiguities. Whereas Yacc supports only a single linear precedence ordering, Hocc supports + arbitrarily many directed acyclic precedence graphs. Given this more powerful conflict resolution + mechanism, Hocc refuses to generate parsers for ambiguous grammars. +- Hocc precisely traces automata to garbage-collect unreachable states, actions, and gotos. Aside + from reducing generated parser size, this enables more thorough reporting about unused grammar + constructs. ## Command usage @@ -35,35 +36,38 @@ Parameters: - `-w[arn]`: Warn about unused grammar constructs. - `-txt` | `-text`: Write a detailed automaton description in plain text format to `/hocc/.txt`. -- `-hmh` | `-hocc`: Write a complete grammar specification in `hocc` format to +- `-hmh` | `-hocc`: Write a complete grammar specification in Hocc format to `/hocc/.hmh`, but with all non-terminal types and reduction code omitted. +- `-y[acc]` : Write a complete grammar specification in Yacc format to `/hocc/.y`, + but with all non-terminal types and reduction code omitted. Precedence/associativity + specifications are linearized per Yacc semantics, which may introduce implicit precedence + relations not present in the Hocc specification. - `-a[lgorithm] `: Use the specified ``orithm for generating an automaton. Defaults to `aplr`. + `aplr`: Adequacy Preservation LR(1) compact automaton that recognizes valid inputs identically - to `lr` automatons. APLR(1) generates an LR(1) automaton and then remerges compatible state + to `lr` automata. APLR(1) generates an LR(1) automaton and then remerges compatible state subgraphs such that LR(1)-relative adequacy is preserved. + `ielr`: Inadequacy Elimination LR(1) compact automaton [^denny2010] that recognizes valid inputs - identically to `lr` automatons. IELR(1) analyzes an LALR(1) automaton and then uses resulting + identically to `lr` automata. IELR(1) analyzes an LALR(1) automaton and then uses resulting metadata to generate an automaton with LR(1)-relative inadequacies eliminated via state splitting. + `lr`: Canonical LR(1) automaton [^knuth1965]. + `pgm`: Practical General Method LR(1) compact automaton [^pager1977] that recognizes valid - inputs identically to `lr` automatons, provided there are no precedence-resolved ambiguities in + inputs identically to `lr` automata, provided there are no precedence-resolved ambiguities in the grammar specification. PGM avoids LR(1)-relative inadequacy via preventative state splitting during automaton creation. + `lalr`: LALR(1) automaton [^deremer1969]. - `-r[esolve] (yes|no)`: Control conflict resolution enablement. Defaults to `yes` for `aplr`/`ielr`/`lr` algorithms, `no` for `pgm`/`lalr` algorithms. - `-[re]m[erge] (yes|no)`: Control compatible state subgraph remerging enablement. Defaults to `yes` - for `aplr` algorithm, `no` otherwise. + for `aplr`/`ielr`/`pgm` algorithm, `no` for `lr`/`lalr` algorithms. - `-g[c] (pre|post|no)`: Control unreachable state garbage collection enablement and ordering relative to remerging. Defaults to `post`-remerging, which is less thorough than `pre`-remerging but faster due to operating on a smaller automaton. - `-hm` | `-hemlock`: Generate a Hemlock-based parser implementation and write it to `/.hm[i]`. - `-ml` | `-ocaml`: Generate an OCaml-based parser implementation and write it to - `/.ml[i]`. This is brittle functionality intended only for Hemlock - bootstrapping. + `/.ml[i]`. This is brittle functionality intended only for Hemlock bootstrapping. - `-s[rc] `: Path and module name of input source, where inputs match `.hmh[i]` and `` comprises the source directory and module name, `[/]`. - `-d[stdir] `: Path to directory in which to place generated output, such that output file @@ -71,7 +75,7 @@ Parameters: Syntax errors in the input file may prevent file generation. Specification errors do not prevent report generation, but all specification errors must be resolved for parser generation to succeed. -Some syntax errors in the embedded Hemlock code may pass through `hocc` unnoticed. +Some syntax errors in the embedded Hemlock code may pass through Hocc unnoticed. Example invocations: @@ -81,7 +85,7 @@ Example invocations: ## Parser specification -The `hocc` specification grammar is layered onto Hemlock's grammar via the addition of several +The Hocc specification grammar is layered onto Hemlock's grammar via the addition of several contextual keywords and one operator: - Parser: `hocc` @@ -104,13 +108,13 @@ The `hocc` keyword introduces the `hocc` statement, and it cannot be otherwise u `hocc` statement. There are no other syntactic restrictions of note with regard to the keywords and operator. -The following subsections document specification semantics. See the `hocc` [grammar](#grammar) +The following subsections document specification semantics. See the Hocc [grammar](#grammar) specification for comprehensive syntax details. ### Tokens Token identifiers match `[_]*[A-Z][A-Za-z0-9_']*` in conformance with Hemlock's capitalized -identifier syntax. By convention the `hocc` documentation restricts token identifiers to +identifier syntax. By convention the Hocc documentation restricts token identifiers to `[A-Z][A-Z0-9_]*` to distinguish tokens from non-terminals, but other conventions can work just as well. @@ -153,7 +157,7 @@ hocc ### Non-terminals Non-terminal identifiers match `[_]*[A-Z][A-Za-z0-9_']*` in conformance with Hemlock's capitalized -identifier syntax. By convention the `hocc` documentation restricts non-terminal identifiers to +identifier syntax. By convention the Hocc documentation restricts non-terminal identifiers to `[A-Z][A-Za-z0-9]*` to distinguish non-terminals from tokens, but other conventions can work just as well. @@ -170,7 +174,7 @@ start symbol's name. For example, `start S ...` implies the `S'` wrapper symbol. Just as for tokens, non-terminals with variant contents must have a declared data type. A parser which universally utilizes implicitly typed non-terminals does not construct a parse tree, but it -may still be useful as a recognizer, or as an abstract grammar specification which `hocc` can verify +may still be useful as a recognizer, or as an abstract grammar specification which Hocc can verify without generating a parser. ```hocc @@ -264,7 +268,7 @@ hocc The following example uses richer pattern binding syntax to reduce boilerplate. Patterns support relevant Hemlock pattern syntax, with the notable exception of type constraints, which are out of -place in `hocc` proper because it makes no attempt at typing embedded code. +place in Hocc proper because it makes no attempt at typing embedded code. ```hocc type point: point = { @@ -298,8 +302,8 @@ hocc Ordinarily, the characteristic finite state machine (CFSM) corresponding to an LR(1) grammar delays each transition until the lookahead symbol becomes available. However this poses a challenge for start symbols because there is no concrete lookahead symbol past the end of input. The following -invalid grammar would infinitely recurse, and `hocc` reports a conflicting action for the -`PSEUDO_END` (`"⊥"`) symbol. +invalid grammar would infinitely recurse, and Hocc reports a conflicting action for the `PSEUDO_END` +(`"⊥"`) symbol. ```hocc # Invalid (infinite recursion). @@ -311,7 +315,7 @@ hocc ``` A typical solution to this challenge is to require the application to signal end of input to the -CFSM via a dedicated API. However `hocc` uses the same approach as Menhir [^fpottier] and instead +CFSM via a dedicated API. However Hocc uses the same approach as Menhir [^fpottier] and instead proactively (transitively) reduces when the current symbol unambiguously delimits a valid start symbol reduction. Some start symbols may trivially meet the requirements for proactive reduction, e.g. for a grammar which incrementally parses a file comprising newline-separated statements, each @@ -347,7 +351,7 @@ hocc ### Precedence Precedence identifiers match `[_]*[a-z][A-Za-z0-9_']*` in conformance with Hemlock's uncapitalized -identifier syntax. By convention the `hocc` documentation restricts precedence identifiers to +identifier syntax. By convention the Hocc documentation restricts precedence identifiers to `p[A-Z][A-Za-z0-9]*`. ```hocc @@ -359,11 +363,11 @@ hocc ``` A parser specification may contain conflicts wherein a parser state encodes multiple valid actions -for one or more inputs. `hocc` refuses to generate parsers which contain unresolved conflicts. -Parser specifications can often be refactored or expanded to eliminate conflicts, but such revisions -may reduce clarity and maintainability. Precedences provide a mechanism for conflict resolution, -i.e. explicit choice of actions. `hocc` attempts to resolve conflicts based on the precedences -assigned to tokens and productions. +for one or more inputs. Hocc refuses to generate parsers which contain unresolved conflicts. Parser +specifications can often be refactored or expanded to eliminate conflicts, but such revisions may +reduce clarity and maintainability. Precedences provide a mechanism for conflict resolution, i.e. +explicit choice of actions. Hocc attempts to resolve conflicts based on the precedences assigned to +tokens and productions. Each production can specify its precedence, or if all of a non-terminal's productions are to have the same precedence, the precedence can be more succinctly specified for the non-terminal as a @@ -882,7 +886,7 @@ parser states can be used as persistent reusable snapshots. ## Automaton description format -Per the [Command usage](#command-usage) documentation, `hocc` can emit a detailed automaton +Per the [Command usage](#command-usage) documentation, Hocc can emit a detailed automaton description. Following is a brief explanation of the automaton description format, using abridged output generated by `hocc -txt -a ielr1 -src Example`. @@ -981,15 +985,15 @@ Of note: - The algorithm used to generate the state machine is specified in the `States` section header, `IELR(1)` in this case. - The n states are indexed [0..n-1], [0..14-1] in this case. -- Isocore indexing is also reported for all algorithms that can generate non-singleton isocore - sets, i.e. all algorithms besides LALR(1). For a more complex grammar, the IELR(1) algorithm might +- Isocore indexing is also reported for all algorithms that can generate non-singleton isocore sets, + i.e. all algorithms besides LALR(1). For a more complex grammar, the IELR(1) algorithm might generate indexes like the following: ``` State 235 [234.0] State 297 [234.1] ``` These states are isocoric because they both have isocore index 234. Furthermore, IELR(1) generates - LALR(1) states as preliminary metadata, and `hocc` assures that IELR(1) isocore indexes match + LALR(1) states as preliminary metadata, and Hocc assures that IELR(1) isocore indexes match LALR(1) state indexes. - Each state comprises the following subsections (empty subsections omitted in output): + `Kernel`: Kernel LR(1) items @@ -1000,14 +1004,212 @@ Of note: contributions that inform isocore (in)compatibility (NB: conflict state is an LALR(1) state index) - Conflict contributions are best interpreted for an IELR(1) automaton generated with remerging - disabled (e.g. `hocc -txt -algorithm ielr -src Example`) in combination with a corresponding - LALR(1) automaton report generated with conflict resolution disabled (e.g. `hocc -txt -algorithm - lalr -resolve no -src Example`). This enables inspection of the conflicts which compel IELR(1) - state splitting. + disabled (e.g. `hocc -txt -algorithm ielr -remerge no -src Example`) in combination with a + corresponding LALR(1) automaton report generated with conflict resolution disabled (e.g. `hocc + -txt -algorithm lalr -resolve no -src Example`). This enables inspection of the conflicts which + compel IELR(1) state splitting. + +## Algorithms + +Hocc implements five parser automaton creation algorithms in the [**L**eft-to-right **R**ightmost +(LR) derivation family](https://en.wikipedia.org/wiki/LR_parser), all with one symbol of lookahead, +i.e. LR(1). The best-known options implemented by Hocc — [LALR(1) (LookAhead +LR(1))](https://en.wikipedia.org/wiki/LALR_parser) [^deremer1969] and [canonical +LR(1)](https://en.wikipedia.org/wiki/Canonical_LR_parser) [^knuth1965] — are to be avoided. LALR(1) +suffers algorithmic flaws, and canonical LR(1) generates relatively large automata. APLR(1) +(Adequacy Preservation LR(1)) and IELR(1) (Inadequacy Elimination LR(1)) [^denny2010] generate +compact automata that provide the full power of canonical LR(1) and can be used interchangeably, the +only practical consideration being which algorithm is faster at generating an automaton for a +particular input grammar. PGM LR(1) (Practical General Method LR(1)) [^pager1977] is a good choice +only if the input grammar completely avoids precedence/associativity. + +Following are descriptions of the high-level differences between the algorithms, as well as guidance +for how and when to utilize them. + +### Canonical LR(1) + +Canonical LR(k) automata (k lookahead symbols) are the most powerful [deterministic context-free +grammar (DCFG)](https://en.wikipedia.org/wiki/Deterministic_context-free_grammar) recognizers at our +disposal. LR(k) grammars can be reformulated as LR(1) grammars, so a single lookahead symbol poses +minimal inconvenience at the same time as avoiding significant implementation and performance +challenges. + +The canonical LR(1) algorithm (hereafter referred to just LR(1)) maintains precise information +regarding lookahead, but this requires many nearly identical automaton states. In order for two +states to be compatible, they must contain identical kernels (sets of LR(1) items, which in turn are +composed of LR(0) items and lookahead symbol sets). Identical kernels generate identical states, so +although LR(1) automata only have one state for each distinct kernel, there is typically a profusion +of distinct kernels. At the time of discovery computers fell woefully short of the capacity +necessary to make practical use of LR(1) automata, hence a rich literature pertaining to algorithms +which merge automaton states in order to fit within practical computational bounds. Most such +algorithms historically traded away some of the power inherent in LR(1), but there are some notable +exceptions. + +- Pager's PGM algorithm (1977) generates automata with no LR(1)-relative inadequacies, with the + caveat that the LR(1) grammar must be conflict-free (i.e. precedence and associativity may not be + used to resolve conflicts). +- IELR(1) (2009) generates automata with no LR(1)-relative inadequacies, with the caveat that the + algorithm assumes fully resolved LR(1) automata. +- APLR(1) (2026) generates automata with no LR(1)-relative inadequacies, even if there are + unresolved conflicts in the corresponding LR(1) automaton. + +There is one subtle consequence of state merging that affects all of the above algorithms (as well +as LALR(1) and many others), namely that it is possible for a sequence of reduce actions to lead to +a state that contains no action for the lookahead symbol (a syntax error). This can confound error +reporting because the parsing configuration of interest was that which existed prior to the first +such reduce action. Fortunately there is a straightforward solution, which is to capture the parser +state prior to reducing and restore the state if an error is encountered. Hocc supports only pure +semantic actions (i.e. no side effects are allowed), so the mitigation for this problem is simple +and inexpensive. + +### LALR(1) + +The **L**ook**A**head LR(1) algorithm takes an extreme approach and merges all states with equal +cores (kernels stripped of all lookahead symbols). This can introduce invasive conflicts, in which +case the resulting automaton may not recognize the same language as the corresponding LR(1) +automaton, even if all the invasive conflicts are subsequently resolved. + +Hocc implements LALR(1) because it is a building block for IELR(1), and it is exposed only for +diagnostic purposes. Do not use LALR(1) to generate parsers. + +### APLR(1) + +The Adequacy Preservation LR(1) algorithm originated in Hocc and is suitable for all practical uses. +The basic idea is to generate an LR(1) automaton, then discover all state subgraphs which can be +remerged without introducing LR(1)-relative inadequacies. Subgraph remergeability testing involves +some implementation subtleties (transitive graph properties, combinatorial logic, oh my), but the +underlying principle is just as simple as it sounds. + +APLR(1) is computationally challenged by large LR(1) automata, both because the LR(1) automaton is +expensive to generate and because remergeability testing requires more work. Heavily conflicted +LR(1) automata also complicate remergeability testing, so for some grammars it may be expedient to +use LR(1) or IELR(1) while diagnosing and resolving conflicts. + +### IELR(1) + +The Inadequacy Elimination LR(1) algorithm was first implemented in +[Bison](https://en.wikipedia.org/wiki/GNU_Bison), and Hocc implements a more general form of IELR(1) +[^evans2024]. The basic idea is to generate an LALR(1) automaton, perform “lane tracing” analyses to +determine what merged states may cause LR(1)-relative inadequacies, and then generate an IELR(1) +automaton with just enough state splitting to eliminate all LR(1)-relative inadequacies. The +original algorithm and Bison implementation assume that the corresponding canonical LR(1) automaton +is fully resolved (i.e. no unresolvable conflicts); if this assumption does not hold then the +algorithm effectively reverts to LALR(1) for the conflicted actions. + +Hocc's algorithm makes no assumptions about whether the corresponding canonical LR(1) automaton is +fully resolved, which means that generated automata actually eliminate +[GLR(1)](https://en.wikipedia.org/wiki/GLR_parser)-relative (Generalized LR(1)) inadequacies, thus +making the generated automata suitable for nondeterministic parsing. That said, Hocc intentionally +omits a GLR parsing API, so the main practical benefit of Hocc's algorithm is that there is no +confusion about whether unresolved conflicts exist in the corresponding LR(1) automaton versus being +mysterious conflicts. There are two disadvantages of Hocc's algorithm relative to Bison's. First, +lane tracing is much more computationally intensive because the fixpoint conditions are less +constrained. Second, due to the potential for cyclic interactions between state subgraphs it is +sometimes necessary to proactively split states “just in case”, only to later discover that there +were no interactions making the splits necessary. Fortunately the APLR(1) state remerging algorithm +works just as well on IELR(1) automata as it does on canonical LR(1) automata, and remerging +overhead is typically insignificant for IELR(1) automata because the IELR(1) automaton is typically +much smaller. + +Hocc's IELR(1) algorithm is computationally challenged by complicated conflict resolutions, because +the conflicts can cause a combinatorial explosion during lane tracing. That said, APLR(1) and +IELR(1) tend not to bog down on the same grammars, and the algorithms generate interchangeable +parsers (in practice usually identical), so choose the faster of IELR(1) and APLR(1) if parser +generation performance is an issue. + +### PGM LR(1) + +The Practical General Method generates an automaton without any LR(1)-relative inadequacies, so long +as precedence/associativity are not used to resolve conflicts. Hocc implements the “weak” state +compatibility test, which predicts whether a state split is necessary to avoid subsequent invasive +conflicts. The weak compatibility test is conservative, and in rare cases extra states may be +generated. However the APLR(1) state remerging algorithm works for PGM LR(1) automata, so there is +no need to resort to the more complicated “strong” state compatibility test to avoid unnecessary +splits. + +Only use the PGM LR(1) algorithm with grammars that avoid all use of precedence/associativity. In +other words, do not use the `prec`, `left`, `right`, nor `nonassoc` keywords. + +## Garbage collection + +Per the [Command usage](#command-usage) documentation, by default Hocc precisely traces and +garbage-collects (GCs) unreachable states, actions, and gotos. The precise tracing algorithm is +subtle and computationally intensive. Tracing uses the start states as the root set, and naïve +tracing would then compute a fixpoint by traversing all shift actions and gotos. However, gotos are +only reachable if a corresponding reduce action is reachable. + +Tracing tracks reachability at the granularity of individual actions and gotos rather than entire +states. Furthermore, goto reachability is a function of reachable paths between goto-containing +states and corresponding reduce actions, i.e. there must exist a reachable contiguous sequence of +transits; it does not suffice for all interposing states to be arbitrarily reachable. + +Absent conflict resolution, reduce actions are reachable by construction (with the exception of the +PGM algorithm), but practical grammars typically utilize precedence and/or associativity to resolve +conflicts. Conflict resolution is fundamentally about removing actions from the automaton, and +action removal can transitively cause entire states, individual actions, and individual gotos, to +become unreachable. + +How to trace reachable actions and gotos? One obvious approach is to simulate inputs that exercise +all possible paths through the automaton. Unfortunately this approach is computationally intractable +for nontrivial grammars because even with optimizations that merge equivalent input prefixes, +combinatorial explosions abound. Hocc avoids this quagmire by tracing bidirectionally. Shift actions +are traced in a straightforward manner, but reduce-goto paths are traced backward from reduce +actions to predecessor states which contain corresponding gotos. + +Tracing iterates toward a fixpoint by alternately tracing actions and gotos. Action tracing is +relatively inexpensive (standard [tracing GC marking +algorithm](https://en.wikipedia.org/wiki/Tracing_garbage_collection#Naive_mark-and-sweep)), so the +implementation reaches an action tracing fixpoint before switching to goto tracing, thus minimizing +the number of goto tracing phases required. + +The goto tracing phase iterates over transitively reachable reduce actions and attempts to trace +backward to corresponding goto actions. For example, the following reduce action extracted from the +`Example` automaton pops three right-hand side (RHS) elements off the stack (`Expr`, `MulOp`, +`Expr`) and replaces them with the left-hand side (LHS) `Expr`. + +```hocc + "*" : Reduce Expr ::= Expr MulOp Expr prec mul +``` + +In this example the RHS symbols are all nonterminals; therefore each was originally placed on the +stack by a reduce action, followed immediately by a goto state transition. Similarly, a token would +be placed on the stack by a shift action. Each symbol on the stack corresponds to a state +transition, and any goto corresponding to this reduce action must therefore be in a distance-three +predecessor state. + +How to find all the reachable corresponding gotos? A naïve approach would be to perform a +depth-limited backward traversal via traced transits and collect all the distance-three predecessors +which contain a goto for `Expr`. However this is intractable (absent marking) because there may be +many combinations of subpaths. The approach taken by Hocc is to perform what can be thought of as +[memoized](https://en.wikipedia.org/wiki/Memoization) [iterative +deepening](https://en.wikipedia.org/wiki/Iterative_deepening_depth-first_search). The reachable +predecessors at each depth are collected as sets, and this serves to deduplicate results, thus +requiring only a single traversal of each backward transit. Nonetheless, this is an expensive +computation, and Hocc implements additional optimizations: + +- The memoized backward tracing state sets are incrementally computed and shared among all reduce + actions within a state. This works even for reduce actions of differing RHS length. +- Most gotos are reachable, and it pays off to precalculate all reduce-goto correspondences as if + all transits were reachable so that a reduce action need no longer be traced once all of its + corresponding gotos have been reached. + +A reachable reduce-goto actually only extends to the successor state's action corresponding to the +reduce action's lookahead symbol. In the example above, the lookahead symbol is `"*"`, so successful +tracing marks only an action on `"*"`. That said, there may well be adjacent reduce actions on e.g. +`"/"` that reach sibling successor state actions. + +Hocc defaults to performing GC `post`-remerging because tracing large automata is slower than +tracing small automata, and GC can dominate total run time for grammars with huge state blowup (LR +vs APLR). Unfortunately, remerging can increase reachability, via lengthened reduce cascades that +culminate in syntax errors. Such cascades can be introduced by remerging regardless of whether GC is +performed first, so the main advantage of performing garbage collection `pre`-remerging is that +slightly more garbage may be collected, as opposed to becoming inadvertently reachable. A developer +may wish to use `pre` for production builds, but there is little point in doing so during grammar +development. ## Grammar -The `hocc` specification language grammar is equivalent to the following specification. +The Hocc specification language grammar is equivalent to the following specification. ```hocc hocc @@ -1251,6 +1453,13 @@ hocc ## Citations +[^evans2024]: + Jason Evans, + “IELR(1) as Implemented by Hocc”, + BranchTaken LLC, + [https://branchtaken.com/reports/ielr1.html](https://branchtaken.com/reports/ielr1.html), + July 2024. + [^knuth1965]: Donald Knuth, “On the Translation of Languages from Left to Right”, @@ -1261,11 +1470,6 @@ hocc “A Practical General Method for Constructing LR(k) Parsers”, Acta Informatica 7:249-268, 1977. -[^diekmann2020]: - Lukas Diekmann and Laurence Tratt, - “Don't Panic! Better, Fewer, Syntax Errors for LR Parsers,” - 34th European Conference on Object-Oriented Programming (ECOOP 2020), Article No. 6, pages 6:1–6:32. - [^fpottier]: François Pottier and Yann Régis-Gianas, “Menhir LR(1) Parser Generator,”