152 } |
152 } |
153 |
153 |
154 |
154 |
155 /* read -- lazy scanning */ |
155 /* read -- lazy scanning */ |
156 |
156 |
157 def read(reader: Reader[Char], start: Token.Pos): Thy_Header = |
157 def read(reader: Reader[Char], start: Token.Pos, strict: Boolean = true): Thy_Header = |
158 { |
158 { |
159 val token = Token.Parsers.token(bootstrap_keywords) |
159 val token = Token.Parsers.token(bootstrap_keywords) |
160 val toks = new mutable.ListBuffer[Token] |
160 def make_tokens(in: Reader[Char]): Stream[Token] = |
|
161 token(in) match { |
|
162 case Token.Parsers.Success(tok, rest) => tok #:: make_tokens(rest) |
|
163 case _ => Stream.empty |
|
164 } |
161 |
165 |
162 @tailrec def scan_to_begin(in: Reader[Char]) |
166 val tokens = |
163 { |
167 if (strict) make_tokens(reader) |
164 token(in) match { |
168 else make_tokens(reader).dropWhile(tok => !tok.is_command(Thy_Header.THEORY)) |
165 case Token.Parsers.Success(tok, rest) => |
|
166 toks += tok |
|
167 if (!tok.is_begin) scan_to_begin(rest) |
|
168 case _ => |
|
169 } |
|
170 } |
|
171 scan_to_begin(reader) |
|
172 |
169 |
173 parse(commit(header), Token.reader(toks.toList, start)) match { |
170 val tokens1 = tokens.takeWhile(tok => !tok.is_begin).toList |
|
171 val tokens2 = tokens.dropWhile(tok => !tok.is_begin).headOption.toList |
|
172 |
|
173 parse(commit(header), Token.reader(tokens1 ::: tokens2, start)) match { |
174 case Success(result, _) => result |
174 case Success(result, _) => result |
175 case bad => error(bad.toString) |
175 case bad => error(bad.toString) |
176 } |
176 } |
177 } |
|
178 |
|
179 |
|
180 /* line-oriented text */ |
|
181 |
|
182 def header_text(doc: Line.Document): String = |
|
183 { |
|
184 val keywords = bootstrap_syntax.keywords |
|
185 val toks = new mutable.ListBuffer[Token] |
|
186 val iterator = |
|
187 (for { |
|
188 (toks, _) <- |
|
189 doc.lines.iterator.scanLeft((List.empty[Token], Scan.Finished: Scan.Line_Context))( |
|
190 { |
|
191 case ((_, ctxt), line) => Token.explode_line(keywords, line.text, ctxt) |
|
192 }) |
|
193 tok <- toks.iterator ++ Iterator.single(Token.newline) |
|
194 } yield tok).dropWhile(tok => !tok.is_command(Thy_Header.THEORY)) |
|
195 |
|
196 @tailrec def until_begin |
|
197 { |
|
198 if (iterator.hasNext) { |
|
199 val tok = iterator.next |
|
200 toks += tok |
|
201 if (!tok.is_begin) until_begin |
|
202 } |
|
203 } |
|
204 until_begin |
|
205 Token.implode(toks.toList) |
|
206 } |
177 } |
207 } |
178 } |
208 |
179 |
209 |
180 |
210 sealed case class Thy_Header( |
181 sealed case class Thy_Header( |