|
1 /* Title: Pure/Thy/thy_structure.scala |
|
2 Author: Makarius |
|
3 |
|
4 Nested structure of theory source. |
|
5 */ |
|
6 |
|
7 package isabelle |
|
8 |
|
9 |
|
10 import scala.collection.mutable |
|
11 import scala.annotation.tailrec |
|
12 |
|
13 |
|
14 object Thy_Structure |
|
15 { |
|
16 sealed abstract class Entry { def length: Int } |
|
17 case class Block(val name: String, val body: List[Entry]) extends Entry |
|
18 { |
|
19 val length: Int = (0 /: body)(_ + _.length) |
|
20 } |
|
21 case class Atom(val command: Command) extends Entry |
|
22 { |
|
23 def length: Int = command.length |
|
24 } |
|
25 |
|
26 def parse(syntax: Outer_Syntax, node_name: Document.Node.Name, text: CharSequence): Entry = |
|
27 { |
|
28 /* stack operations */ |
|
29 |
|
30 def buffer(): mutable.ListBuffer[Entry] = new mutable.ListBuffer[Entry] |
|
31 var stack: List[(Int, String, mutable.ListBuffer[Entry])] = |
|
32 List((0, node_name.toString, buffer())) |
|
33 |
|
34 @tailrec def close(level: Int => Boolean) |
|
35 { |
|
36 stack match { |
|
37 case (lev, name, body) :: (_, _, body2) :: rest if level(lev) => |
|
38 body2 += Block(name, body.toList) |
|
39 stack = stack.tail |
|
40 close(level) |
|
41 case _ => |
|
42 } |
|
43 } |
|
44 |
|
45 def result(): Entry = |
|
46 { |
|
47 close(_ => true) |
|
48 val (_, name, body) = stack.head |
|
49 Block(name, body.toList) |
|
50 } |
|
51 |
|
52 def add(command: Command) |
|
53 { |
|
54 syntax.heading_level(command) match { |
|
55 case Some(i) => |
|
56 close(_ > i) |
|
57 stack = (i + 1, command.source, buffer()) :: stack |
|
58 case None => |
|
59 } |
|
60 stack.head._3 += Atom(command) |
|
61 } |
|
62 |
|
63 |
|
64 /* result structure */ |
|
65 |
|
66 val spans = Thy_Syntax.parse_spans(syntax.scan(text)) |
|
67 spans.foreach(span => add(Command(Document_ID.none, node_name, Nil, span))) |
|
68 result() |
|
69 } |
|
70 } |
|
71 |