104 | push name atts pending = ((name, atts), []) :: pending; |
104 | push name atts pending = ((name, atts), []) :: pending; |
105 |
105 |
106 fun pop ((("", _), _) :: _) = err_unbalanced "" |
106 fun pop ((("", _), _) :: _) = err_unbalanced "" |
107 | pop ((markup, body) :: pending) = add (XML.Elem (markup, rev body)) pending; |
107 | pop ((markup, body) :: pending) = add (XML.Elem (markup, rev body)) pending; |
108 |
108 |
|
109 val stack_init = [(("", []), [])]; |
109 |
110 |
110 (* parsing *) |
111 (* parsing *) |
111 |
112 |
112 fun parse_attrib s = |
113 fun parse_attrib s = |
113 (case first_field "=" s of |
114 (case first_field "=" s of |
117 |
118 |
118 fun parse_chunk ["", ""] = pop |
119 fun parse_chunk ["", ""] = pop |
119 | parse_chunk ("" :: name :: atts) = push name (map parse_attrib atts) |
120 | parse_chunk ("" :: name :: atts) = push name (map parse_attrib atts) |
120 | parse_chunk txts = fold (add o XML.Text) txts; |
121 | parse_chunk txts = fold (add o XML.Text) txts; |
121 |
122 |
|
123 fun preparse_chunk _ "" x = x |
|
124 | preparse_chunk f str (pending, results) = |
|
125 (case parse_chunk (String.fields (is_char Y) str) pending of |
|
126 [(("", _), [result])] => (stack_init, f result :: results) |
|
127 | foo => (foo, results)); |
|
128 |
122 in |
129 in |
123 |
130 |
124 fun parse_body source = |
131 fun parse_body source = |
125 (case fold parse_chunk (split_string source) [(("", []), [])] of |
132 (case fold parse_chunk (split_string source) stack_init of |
126 [(("", _), result)] => rev result |
133 [(("", _), result)] => rev result |
127 | ((name, _), _) :: _ => err_unbalanced name); |
134 | ((name, _), _) :: _ => err_unbalanced name); |
128 |
135 |
129 fun parse source = |
136 fun parse source = |
130 (case parse_body source of |
137 (case parse_body source of |
131 [result] => result |
138 [result] => result |
132 | [] => XML.Text "" |
139 | [] => XML.Text "" |
133 | _ => err "multiple results"); |
140 | _ => err "multiple results"); |
134 |
141 |
|
142 fun parse_file' f path = |
|
143 (case File.fold_fields (is_char X) (preparse_chunk f) |
|
144 path (stack_init, []) of |
|
145 ([(("", _), [])], result) => rev result |
|
146 | (((name, _), _) :: _, _) => err_unbalanced name); |
|
147 |
135 end; |
148 end; |
136 |
149 |
137 end; |
150 end; |
138 |
151 |