author | clasohm |
Fri, 06 May 1994 13:50:36 +0200 | |
changeset 362 | 6bea8fdc0e70 |
parent 345 | 7007562172b1 |
child 367 | b734dc03067e |
permissions | -rw-r--r-- |
18 | 1 |
(* Title: Pure/Syntax/parser.ML |
46 | 2 |
ID: $Id$ |
345 | 3 |
Author: Sonia Mahjoub, Markus Wenzel and Carsten Clasohm, TU Muenchen |
18 | 4 |
|
5 |
Isabelle's main parser (used for terms and typs). |
|
6 |
||
7 |
TODO: |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
8 |
extend_gram: remove 'roots' arg |
18 | 9 |
*) |
10 |
||
11 |
signature PARSER = |
|
12 |
sig |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
13 |
structure Lexicon: LEXICON |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
14 |
structure SynExt: SYN_EXT |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
15 |
local open Lexicon SynExt SynExt.Ast in |
18 | 16 |
type gram |
17 |
val empty_gram: gram |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
18 |
val extend_gram: gram -> string list -> xprod list -> gram |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
19 |
val merge_grams: gram -> gram -> gram |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
20 |
val pretty_gram: gram -> Pretty.T list |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
21 |
datatype parsetree = |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
22 |
Node of string * parsetree list | |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
23 |
Tip of token |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
24 |
val parse: gram -> string -> token list -> parsetree list |
18 | 25 |
end |
26 |
end; |
|
27 |
||
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
28 |
functor ParserFun(structure Symtab: SYMTAB and Lexicon: LEXICON |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
29 |
and SynExt: SYN_EXT) = |
18 | 30 |
struct |
31 |
||
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
32 |
structure Pretty = SynExt.Ast.Pretty; |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
33 |
structure Lexicon = Lexicon; |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
34 |
structure SynExt = SynExt; |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
35 |
open Lexicon SynExt; |
18 | 36 |
|
37 |
||
38 |
(** datatype gram **) |
|
39 |
||
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
40 |
datatype symb = |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
41 |
Terminal of token | |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
42 |
Nonterminal of string * int; |
18 | 43 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
44 |
datatype refsymb = Term of token | Nonterm of rhss_ref * int |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
45 |
(*reference to production list instead of name*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
46 |
and gram = Gram of (string * (symb list * string * int)) list * |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
47 |
(string * rhss_ref) list |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
48 |
withtype rhss_ref = (token option * (refsymb list * string * int) list) list ref |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
49 |
(*lookahead table: token and productions*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
50 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
51 |
(* convert productions to reference grammar with lookaheads and eliminate |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
52 |
chain productions *) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
53 |
fun mk_gram prods = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
54 |
let (*get reference on list of all possible rhss for nonterminal lhs |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
55 |
(if it doesn't exist a new one is created and added to the nonterminal |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
56 |
list)*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
57 |
fun get_rhss ref_prods lhs = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
58 |
case assoc (ref_prods, lhs) of |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
59 |
None => |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
60 |
let val l = ref [(None, [])] |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
61 |
in (l, (lhs, l) :: ref_prods) end |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
62 |
| Some l => (l, ref_prods); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
63 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
64 |
(*convert symb list to refsymb list*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
65 |
fun mk_refsymbs ref_prods [] rs = (rs, ref_prods) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
66 |
| mk_refsymbs ref_prods (Terminal tk :: symbs) rs = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
67 |
mk_refsymbs ref_prods symbs (rs @ [Term tk]) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
68 |
| mk_refsymbs ref_prods (Nonterminal (name, prec) :: symbs) rs = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
69 |
let val (rhss, ref_prods') = get_rhss ref_prods name |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
70 |
in mk_refsymbs ref_prods' symbs (rs @ [Nonterm (rhss, prec)]) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
71 |
end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
72 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
73 |
(*convert prod list to (string * rhss_ref) list |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
74 |
without computing lookaheads*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
75 |
fun mk_ref_gram [] ref_prods = ref_prods |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
76 |
| mk_ref_gram ((lhs, (rhs, name, prec)) :: ps) ref_prods = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
77 |
let val (rhs', ref_prods') = get_rhss ref_prods lhs; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
78 |
val (dummy, rhss) = hd (!rhs'); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
79 |
val (ref_symbs, ref_prods'') = mk_refsymbs ref_prods' rhs []; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
80 |
in rhs' := [(dummy, (ref_symbs, name, prec) :: rhss)]; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
81 |
mk_ref_gram ps ref_prods'' |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
82 |
end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
83 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
84 |
(*eliminate chain productions*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
85 |
fun elim_chain ref_gram = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
86 |
let (*make a list of pairs representing chain productions and delete |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
87 |
these productions*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
88 |
fun list_chain [] = [] |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
89 |
| list_chain ((_, rhss_ref) :: ps) = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
90 |
let fun lists [] new_rhss chains = (new_rhss, chains) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
91 |
| lists (([Nonterm (id2, ~1)], _, ~1) :: rs) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
92 |
new_rhss chains = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
93 |
lists rs new_rhss ((rhss_ref, id2) :: chains) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
94 |
| lists (rhs :: rs) new_rhss chains = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
95 |
lists rs (rhs :: new_rhss) chains; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
96 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
97 |
val (dummy, rhss) = hd (!rhss_ref); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
98 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
99 |
val (new_rhss, chains) = lists rhss [] []; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
100 |
in rhss_ref := [(dummy, new_rhss)]; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
101 |
chains @ (list_chain ps) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
102 |
end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
103 |
|
345 | 104 |
(*convert a list of pairs to an association list |
105 |
by using the first element as the key*) |
|
106 |
fun mk_assoc pairs = |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
107 |
let fun doit [] result = result |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
108 |
| doit ((id1, id2) :: ps) result = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
109 |
doit ps |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
110 |
(overwrite (result, (id1, id2 :: (assocs result id1)))); |
345 | 111 |
in doit pairs [] end; |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
112 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
113 |
(*replace reference by list of rhss in chain pairs*) |
345 | 114 |
fun deref (id1, ids) = |
115 |
let fun deref1 [] = [] |
|
116 |
| deref1 (id :: ids) = |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
117 |
let val (_, rhss) = hd (!id); |
345 | 118 |
in rhss @ (deref1 ids) end; |
119 |
in (id1, deref1 ids) end; |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
120 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
121 |
val chain_pairs = |
345 | 122 |
map deref (transitive_closure (mk_assoc (list_chain ref_gram))); |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
123 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
124 |
(*add new rhss to productions*) |
345 | 125 |
fun elim (rhss_ref, rhss) = |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
126 |
let val (dummy, old_rhss) = hd (!rhss_ref); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
127 |
in rhss_ref := [(dummy, old_rhss @ rhss)] end; |
345 | 128 |
in map elim chain_pairs; |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
129 |
ref_gram |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
130 |
end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
131 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
132 |
val ref_gram = elim_chain (mk_ref_gram prods []); |
18 | 133 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
134 |
(*make a list of all lambda NTs |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
135 |
(i.e. nonterminals that can produce lambda*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
136 |
val lambdas = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
137 |
let fun lambda [] result = result |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
138 |
| lambda ((_, rhss_ref) :: nts) result = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
139 |
if rhss_ref mem result then |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
140 |
lambda nts result |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
141 |
else |
345 | 142 |
let (*list all NTs that can be produced by a rhs |
143 |
containing only lambda NTs*) |
|
144 |
fun only_lambdas [] result = result |
|
145 |
| only_lambdas ((_, rhss_ref) :: ps) result = |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
146 |
let fun only (symbs, _, _) = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
147 |
forall (fn (Nonterm (id, _)) => id mem result |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
148 |
| (Term _) => false) symbs; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
149 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
150 |
val (_, rhss) = hd (!rhss_ref); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
151 |
in if not (rhss_ref mem result) andalso |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
152 |
exists only rhss then |
345 | 153 |
only_lambdas ref_gram (rhss_ref :: result) |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
154 |
else |
345 | 155 |
only_lambdas ps result |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
156 |
end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
157 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
158 |
val (_, rhss) = hd (!rhss_ref); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
159 |
in if exists (fn (symbs, _, _) => null symbs) rhss |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
160 |
then lambda nts |
345 | 161 |
(only_lambdas ref_gram (rhss_ref :: result)) |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
162 |
else lambda nts result |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
163 |
end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
164 |
in lambda ref_gram [] end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
165 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
166 |
(*list all nonterminals on which the lookahead depends (due to lambda |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
167 |
NTs this can be more than one) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
168 |
and report if there is a terminal at the 'start'*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
169 |
fun rhss_start [] skipped = (None, skipped) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
170 |
| rhss_start (Term tk :: _) skipped = (Some tk, skipped) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
171 |
| rhss_start (Nonterm (rhss_ref, _) :: rest) skipped = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
172 |
if rhss_ref mem lambdas then |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
173 |
rhss_start rest (rhss_ref ins skipped) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
174 |
else |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
175 |
(None, rhss_ref ins skipped); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
176 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
177 |
(*list all terminals that can start the given rhss*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
178 |
fun look_rhss starts rhss_ref = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
179 |
let fun look [] _ = [] |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
180 |
| look ((symbs, _, _) :: todos) done = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
181 |
let val (start_token, skipped) = rhss_start symbs []; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
182 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
183 |
(*process all nonterminals on which the lookahead |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
184 |
depends and build the new todo and done lists for |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
185 |
the look function*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
186 |
fun look2 [] todos = look todos (done union skipped) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
187 |
| look2 (rhss_ref :: ls) todos = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
188 |
if rhss_ref mem done then look2 ls todos |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
189 |
else case assoc (starts, rhss_ref) of |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
190 |
Some tks => tks union (look2 ls todos) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
191 |
| None => let val (_, rhss) = hd (!rhss_ref); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
192 |
in look2 ls (rhss union todos) end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
193 |
in case start_token of |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
194 |
Some tk => start_token ins (look2 skipped todos) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
195 |
| None => look2 skipped todos |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
196 |
end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
197 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
198 |
val (_, rhss) = hd (!rhss_ref); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
199 |
in look rhss [rhss_ref] end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
200 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
201 |
(*make a table that contains all possible starting terminals |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
202 |
for each nonterminal*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
203 |
fun mk_starts [] starts = starts |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
204 |
| mk_starts ((_, rhss_ref) :: ps) starts = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
205 |
mk_starts ps ((rhss_ref, look_rhss starts rhss_ref) :: starts); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
206 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
207 |
val starts = mk_starts ref_gram []; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
208 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
209 |
(*add list of allowed starting tokens to productions*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
210 |
fun mk_lookahead (_, rhss_ref) = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
211 |
let (*add item to lookahead list (a list containing pairs of token and |
345 | 212 |
rhss that can be started with it*) |
213 |
fun add_start new_rhs tokens table = |
|
214 |
let fun add [] [] = [] |
|
215 |
| add (tk :: tks) [] = |
|
216 |
(tk, [new_rhs]) :: (add tks []) |
|
217 |
| add tokens ((tk, rhss) :: ss) = |
|
218 |
if tk mem tokens then |
|
219 |
(tk, new_rhs :: rhss) :: (add (tokens \ tk) ss) |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
220 |
else |
345 | 221 |
(tk, rhss) :: (add tokens ss); |
222 |
in add tokens table end; |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
223 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
224 |
(*combine all lookaheads of a list of nonterminals*) |
345 | 225 |
fun combine_starts rhss_refs = |
226 |
foldr (op union) |
|
227 |
((map (fn rhss_ref => let val Some tks = assoc (starts, rhss_ref) |
|
228 |
in tks end) rhss_refs), []); |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
229 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
230 |
(*get lookahead for a rhs and update lhs' lookahead list*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
231 |
fun look_rhss [] table = table |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
232 |
| look_rhss ((rhs as (symbs, id, prec)) :: rs) table = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
233 |
let val (start_token, skipped) = rhss_start symbs []; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
234 |
val starts = case start_token of |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
235 |
Some tk => Some tk |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
236 |
ins (combine_starts skipped) |
345 | 237 |
| None => if skipped subset lambdas then |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
238 |
[None] |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
239 |
else |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
240 |
combine_starts skipped; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
241 |
in look_rhss rs (add_start rhs starts table) end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
242 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
243 |
val (_, rhss) = hd (!rhss_ref); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
244 |
in rhss_ref := look_rhss rhss [] end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
245 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
246 |
in map mk_lookahead ref_gram; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
247 |
Gram (prods, ref_gram) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
248 |
end; |
18 | 249 |
|
250 |
||
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
251 |
(* empty, extend, merge grams *) |
18 | 252 |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
253 |
val empty_gram = mk_gram []; |
18 | 254 |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
255 |
fun extend_gram (gram1 as Gram (prods1, _)) _ xprods2 = |
18 | 256 |
let |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
257 |
fun symb_of (Delim s) = Some (Terminal (Token s)) |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
258 |
| symb_of (Argument (s, p)) = |
18 | 259 |
(case predef_term s of |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
260 |
None => Some (Nonterminal (s, p)) |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
261 |
| Some tk => Some (Terminal tk)) |
18 | 262 |
| symb_of _ = None; |
263 |
||
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
264 |
fun prod_of (XProd (lhs, xsymbs, const, pri)) = |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
265 |
(lhs, (mapfilter symb_of xsymbs, const, pri)); |
18 | 266 |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
267 |
val prods2 = distinct (map prod_of xprods2); |
18 | 268 |
in |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
269 |
if prods2 subset prods1 then gram1 |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
270 |
else mk_gram (extend_list prods1 prods2) |
18 | 271 |
end; |
272 |
||
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
273 |
fun merge_grams (gram1 as Gram (prods1, _)) (gram2 as Gram (prods2, _)) = |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
274 |
if prods2 subset prods1 then gram1 |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
275 |
else if prods1 subset prods2 then gram2 |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
276 |
else mk_gram (merge_lists prods1 prods2); |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
277 |
|
18 | 278 |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
279 |
(* pretty_gram *) |
18 | 280 |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
281 |
fun pretty_gram (Gram (prods, _)) = |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
282 |
let |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
283 |
fun pretty_name name = [Pretty.str (name ^ " =")]; |
18 | 284 |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
285 |
fun pretty_symb (Terminal (Token s)) = Pretty.str (quote s) |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
286 |
| pretty_symb (Terminal tok) = Pretty.str (str_of_token tok) |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
287 |
| pretty_symb (Nonterminal (s, p)) = |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
288 |
Pretty.str (s ^ "[" ^ string_of_int p ^ "]"); |
18 | 289 |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
290 |
fun pretty_const "" = [] |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
291 |
| pretty_const c = [Pretty.str ("=> " ^ quote c)]; |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
292 |
|
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
293 |
fun pretty_pri p = [Pretty.str ("(" ^ string_of_int p ^ ")")]; |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
294 |
|
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
295 |
fun pretty_prod (name, (symbs, const, pri)) = |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
296 |
Pretty.block (Pretty.breaks (pretty_name name @ |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
297 |
map pretty_symb symbs @ pretty_const const @ pretty_pri pri)); |
18 | 298 |
in |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
299 |
map pretty_prod prods |
18 | 300 |
end; |
301 |
||
302 |
||
303 |
||
304 |
(** parse **) |
|
305 |
||
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
306 |
datatype parsetree = |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
307 |
Node of string * parsetree list | |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
308 |
Tip of token; |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
309 |
|
18 | 310 |
type state = |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
311 |
rhss_ref * int (*lhs: identification and production precedence*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
312 |
* parsetree list (*already parsed nonterminals on rhs*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
313 |
* refsymb list (*rest of rhs*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
314 |
* string (*name of production*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
315 |
* int; (*index for previous state list*) |
18 | 316 |
|
317 |
type earleystate = state list Array.array; |
|
318 |
||
319 |
||
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
320 |
(*Get all rhss with precedence >= minPrec*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
321 |
fun getRHS minPrec = filter (fn (_, _, prec:int) => prec >= minPrec); |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
322 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
323 |
(*Get all rhss with precedence >= minPrec and < maxPrec*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
324 |
fun getRHS' minPrec maxPrec = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
325 |
filter (fn (_, _, prec:int) => prec >= minPrec andalso prec < maxPrec); |
18 | 326 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
327 |
(*Make states using a list of rhss*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
328 |
fun mkStates i minPrec lhsID rhss = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
329 |
let fun mkState (rhs, id, prodPrec) = (lhsID, prodPrec, [], rhs, id, i); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
330 |
in map mkState rhss end; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
331 |
|
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
332 |
(*Add parse tree to list and eliminate duplicates |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
333 |
saving the maximum precedence*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
334 |
fun conc (t, prec:int) [] = (None, [(t, prec)]) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
335 |
| conc (t, prec) ((t', prec') :: ts) = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
336 |
if t = t' then |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
337 |
(Some prec', if prec' >= prec then (t', prec') :: ts |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
338 |
else (t, prec) :: ts) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
339 |
else |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
340 |
let val (n, ts') = conc (t, prec) ts |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
341 |
in (n, (t', prec') :: ts') end; |
18 | 342 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
343 |
(*Update entry in used*) |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
344 |
fun update_tree ((B, (i, ts)) :: used) (A, t) = |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
345 |
if A = B then |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
346 |
let val (n, ts') = conc t ts |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
347 |
in ((A, (i, ts')) :: used, n) end |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
348 |
else |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
349 |
let val (used', n) = update_tree used (A, t) |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
350 |
in ((B, (i, ts)) :: used', n) end; |
18 | 351 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
352 |
(*Replace entry in used*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
353 |
fun update_index (A, prec) used = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
354 |
let fun update((hd as (B, (_, ts))) :: used, used') = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
355 |
if A = B |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
356 |
then used' @ ((A, (prec, ts)) :: used) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
357 |
else update (used, hd :: used') |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
358 |
in update (used, []) end; |
18 | 359 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
360 |
fun getS A maxPrec Si = |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
361 |
filter |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
362 |
(fn (_, _, _, Nonterm (B, prec) :: _, _, _) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
363 |
=> A = B andalso prec <= maxPrec |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
364 |
| _ => false) Si; |
18 | 365 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
366 |
fun getS' A maxPrec minPrec Si = |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
367 |
filter |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
368 |
(fn (_, _, _, Nonterm (B, prec) :: _, _, _) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
369 |
=> A = B andalso prec > minPrec andalso prec <= maxPrec |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
370 |
| _ => false) Si; |
18 | 371 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
372 |
fun getStates Estate i ii A maxPrec = |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
373 |
filter |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
374 |
(fn (_, _, _, Nonterm (B, prec) :: _, _, _) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
375 |
=> A = B andalso prec <= maxPrec |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
376 |
| _ => false) |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
377 |
(Array.sub (Estate, ii)); |
18 | 378 |
|
379 |
||
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
380 |
fun movedot_term (A, j, ts, Term a :: sa, id, i) c = |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
381 |
if valued_token c then |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
382 |
(A, j, (ts @ [Tip c]), sa, id, i) |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
383 |
else (A, j, ts, sa, id, i); |
18 | 384 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
385 |
fun movedot_nonterm ts (A, j, tss, Nonterm _ :: sa, id, i) = |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
386 |
(A, j, tss @ ts, sa, id, i); |
18 | 387 |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
388 |
fun movedot_lambda _ [] = [] |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
389 |
| movedot_lambda (B, j, tss, Nonterm (A, k) :: sa, id, i) ((t, ki) :: ts) = |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
390 |
if k <= ki then |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
391 |
(B, j, tss @ t, sa, id, i) :: |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
392 |
movedot_lambda (B, j, tss, Nonterm (A, k) :: sa, id, i) ts |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
393 |
else movedot_lambda (B, j, tss, Nonterm (A, k) :: sa, id, i) ts; |
18 | 394 |
|
395 |
||
396 |
||
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
397 |
fun PROCESSS Estate i c states = |
18 | 398 |
let |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
399 |
fun get_lookahead rhss_ref = token_assoc (!rhss_ref, c); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
400 |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
401 |
fun processS used [] (Si, Sii) = (Si, Sii) |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
402 |
| processS used (S :: States) (Si, Sii) = |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
403 |
(case S of |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
404 |
(_, _, _, Nonterm (rhss_ref, minPrec) :: _, _, _) => |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
405 |
let (*predictor operation*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
406 |
val (used_new, States_new) = |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
407 |
(case assoc (used, rhss_ref) of |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
408 |
Some (usedPrec, l) => (*nonterminal has been processed*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
409 |
if usedPrec <= minPrec then |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
410 |
(*wanted precedence has been processed*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
411 |
(used, movedot_lambda S l) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
412 |
else (*wanted precedence hasn't been parsed yet*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
413 |
let val rhss = get_lookahead rhss_ref; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
414 |
val States' = mkStates i minPrec rhss_ref |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
415 |
(getRHS' minPrec usedPrec rhss); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
416 |
in (update_index (rhss_ref, minPrec) used, |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
417 |
movedot_lambda S l @ States') |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
418 |
end |
18 | 419 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
420 |
| None => (*nonterminal is parsed for the first time*) |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
421 |
let val rhss = get_lookahead rhss_ref; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
422 |
val States' = mkStates i minPrec rhss_ref |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
423 |
(getRHS minPrec rhss); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
424 |
in ((rhss_ref, (minPrec, [])) :: used, States') end) |
18 | 425 |
in |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
426 |
processS used_new (States_new @ States) (S :: Si, Sii) |
18 | 427 |
end |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
428 |
| (_, _, _, Term a :: _, _, _) => (*scanner operation*) |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
429 |
processS used States |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
430 |
(S :: Si, |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
431 |
if matching_tokens (a, c) then movedot_term S c :: Sii else Sii) |
18 | 432 |
|
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
433 |
| (A, prec, ts, [], id, j) => (*completer operation*) |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
434 |
let |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
435 |
val tt = if id = "" then ts else [Node (id, ts)] |
18 | 436 |
in |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
437 |
if j = i then (*lambda production?*) |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
438 |
let |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
439 |
val (used', O) = update_tree used (A, (tt, prec)); |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
440 |
in |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
441 |
(case O of |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
442 |
None => |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
443 |
let |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
444 |
val Slist = getS A prec Si; |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
445 |
val States' = map (movedot_nonterm tt) Slist; |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
446 |
in |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
447 |
processS used' (States' @ States) (S :: Si, Sii) |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
448 |
end |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
449 |
| Some n => |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
450 |
if n >= prec then |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
451 |
processS used' States (S :: Si, Sii) |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
452 |
else |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
453 |
let |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
454 |
val Slist = getS' A prec n Si; |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
455 |
val States' = map (movedot_nonterm tt) Slist; |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
456 |
in |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
457 |
processS used' (States' @ States) (S :: Si, Sii) |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
458 |
end) |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
459 |
end |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
460 |
else |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
461 |
processS used |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
462 |
(map (movedot_nonterm tt) (getStates Estate i j A prec) @ States) |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
463 |
(S :: Si, Sii) |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
464 |
end) |
18 | 465 |
in |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
466 |
processS [] states ([], []) |
18 | 467 |
end; |
468 |
||
469 |
||
470 |
||
362 | 471 |
fun syntax_error toks allowed = |
472 |
error |
|
473 |
((if toks = [] then |
|
474 |
"error: unexpected end of input\n" |
|
475 |
else |
|
476 |
"Syntax error at: " ^ quote (space_implode " " (map str_of_token toks)) |
|
477 |
^ "\n") |
|
478 |
^ "Expected tokens: " |
|
479 |
^ space_implode ", " (map (quote o str_of_token) allowed)); |
|
18 | 480 |
|
362 | 481 |
fun produce stateset i indata prev_token = |
482 |
(*the argument prev_token is only used for error messages*) |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
483 |
(case Array.sub (stateset, i) of |
362 | 484 |
[] => let (*compute a list of allowed starting tokens |
485 |
for a list of nonterminals*) |
|
486 |
fun get_starts [] = [] |
|
487 |
| get_starts (rhss_ref :: refs) = |
|
488 |
let fun get [] = [] |
|
489 |
| get ((Some tok, _) :: rhss) = |
|
490 |
tok :: (get rhss) |
|
491 |
| get ((None, _) :: rhss) = |
|
492 |
get rhss; |
|
493 |
in (get (!rhss_ref)) union (get_starts refs) end; |
|
494 |
||
495 |
val NTs = map (fn (_, _, _, Nonterm (a, _) :: _, _, _) => a) |
|
496 |
(filter (fn (_, _, _, Nonterm _ :: _, _, _) => true |
|
497 |
| _ => false) (Array.sub (stateset, i-1))); |
|
498 |
val allowed = get_starts NTs union |
|
499 |
(map (fn (_, _, _, Term a :: _, _, _) => a) |
|
500 |
(filter (fn (_, _, _, Term _ :: _, _, _) => true |
|
501 |
| _ => false) (Array.sub (stateset, i-1)))); |
|
502 |
(*terminals have to be searched for |
|
503 |
because of lambda productions*) |
|
504 |
in syntax_error (if prev_token = EndToken then indata |
|
505 |
else prev_token :: indata) allowed |
|
506 |
end |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
507 |
| s => |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
508 |
(case indata of |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
509 |
[] => Array.sub (stateset, i) |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
510 |
| c :: cs => |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
511 |
let |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
512 |
val (si, sii) = PROCESSS stateset i c s; |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
513 |
in |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
514 |
Array.update (stateset, i, si); |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
515 |
Array.update (stateset, i + 1, sii); |
362 | 516 |
produce stateset (i + 1) cs c |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
517 |
end)); |
18 | 518 |
|
519 |
||
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
520 |
val get_trees = mapfilter (fn (_, _, [pt], _, _, _) => Some pt | _ => None); |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
521 |
|
18 | 522 |
|
523 |
fun earley grammar startsymbol indata = |
|
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
524 |
let |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
525 |
val rhss_ref = case assoc (grammar, startsymbol) of |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
526 |
Some r => r |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
527 |
| None => error ("parse: Unknown startsymbol " ^ |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
528 |
quote startsymbol); |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
529 |
val S0 = [(ref [], 0, [], [Nonterm (rhss_ref, 0), Term EndToken], "", 0)]; |
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
530 |
val s = length indata + 1; |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
531 |
val Estate = Array.array (s, []); |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
532 |
in |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
533 |
Array.update (Estate, 0, S0); |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
534 |
let |
362 | 535 |
val l = produce Estate 0 indata EndToken(*dummy*); |
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
536 |
val p_trees = get_trees l; |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
537 |
in p_trees end |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
538 |
end; |
18 | 539 |
|
540 |
||
237
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
541 |
fun parse (Gram (_, prod_tab)) start toks = |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
542 |
(case earley prod_tab start toks of |
a7d3e712767a
MAJOR INTERNAL CHANGE: extend and merge operations of syntax tables
wenzelm
parents:
46
diff
changeset
|
543 |
[] => sys_error "parse: no parse trees" |
330
2fda15dd1e0f
changed the way a grammar is generated to allow the new parser to work;
clasohm
parents:
258
diff
changeset
|
544 |
| pts => pts); |
18 | 545 |
|
546 |
end; |
|
547 |