src/Pure/Thy/thy_header.scala
changeset 64825 e78b62c289bb
parent 64824 330ec9bc4b75
child 64854 f5aa712e6250
equal deleted inserted replaced
64824:330ec9bc4b75 64825:e78b62c289bb
   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(