author | immler@in.tum.de |
Thu, 05 Mar 2009 16:40:49 +0100 | |
changeset 34531 | db1c28e326fc |
parent 34526 | b504abb6eff6 |
child 34532 | aaafe9c4180b |
permissions | -rw-r--r-- |
34407 | 1 |
/* |
34485 | 2 |
* Document as list of commands, consisting of lists of tokens |
34407 | 3 |
* |
4 |
* @author Johannes Hölzl, TU Munich |
|
34485 | 5 |
* @author Makarius |
34407 | 6 |
*/ |
7 |
||
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
8 |
package isabelle.proofdocument |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
9 |
|
34526 | 10 |
import scala.collection.mutable.ListBuffer |
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
11 |
import java.util.regex.Pattern |
34485 | 12 |
import isabelle.prover.{Prover, Command} |
34531 | 13 |
import isabelle.utils.LinearSet |
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
14 |
|
34494 | 15 |
case class StructureChange( |
34526 | 16 |
val before_change: Option[Command], |
34494 | 17 |
val added_commands: List[Command], |
18 |
val removed_commands: List[Command]) |
|
34485 | 19 |
|
34483 | 20 |
object ProofDocument |
21 |
{ |
|
34485 | 22 |
// Be carefully when changing this regex. Not only must it handle the |
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
23 |
// spurious end of a token but also: |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
24 |
// Bug ID: 5050507 Pattern.matches throws StackOverflow Error |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
25 |
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507 |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
26 |
|
34483 | 27 |
val token_pattern = |
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
28 |
Pattern.compile( |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
29 |
"\\{\\*([^*]|\\*[^}]|\\*\\z)*(\\z|\\*\\})|" + |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
30 |
"\\(\\*([^*]|\\*[^)]|\\*\\z)*(\\z|\\*\\))|" + |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
31 |
"(\\?'?|')[A-Za-z_0-9.]*|" + |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
32 |
"[A-Za-z_0-9.]+|" + |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
33 |
"[!#$%&*+-/<=>?@^_|~]+|" + |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
34 |
"\"([^\\\\\"]?(\\\\(.|\\z))?)*+(\"|\\z)|" + |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
35 |
"`([^\\\\`]?(\\\\(.|\\z))?)*+(`|\\z)|" + |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
36 |
"[()\\[\\]{}:;]", Pattern.MULTILINE) |
34485 | 37 |
|
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
38 |
} |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
39 |
|
34505
87f4f70d61bb
ProofDocument: pass is_command_keyword directly, not via full-blown Prover object;
wenzelm
parents:
34496
diff
changeset
|
40 |
class ProofDocument(text: Text, is_command_keyword: String => Boolean) |
34483 | 41 |
{ |
34526 | 42 |
private var active = false |
34456 | 43 |
def activate() { |
44 |
if (!active) { |
|
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
45 |
active = true |
34526 | 46 |
text_changed(new Text.Change(0, content, content.length)) |
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
47 |
} |
34456 | 48 |
} |
34485 | 49 |
|
34526 | 50 |
text.changes += (change => text_changed(change)) |
34485 | 51 |
|
34531 | 52 |
var tokens = LinearSet.empty[Token] |
53 |
var commands = LinearSet.empty[Command] |
|
54 |
def content = Token.string_from_tokens(List() ++ tokens) |
|
34485 | 55 |
/** token view **/ |
56 |
||
34526 | 57 |
private def text_changed(change: Text.Change) |
34485 | 58 |
{ |
34531 | 59 |
val tokens = List() ++ this.tokens |
34526 | 60 |
val (begin, remaining) = tokens.span(_.stop < change.start) |
34531 | 61 |
val (removed, end_unshifted) = remaining.span(_.start <= change.start + change.removed) |
62 |
val end = for (t <- end_unshifted) yield t.shift(change.added.length - change.removed) |
|
34485 | 63 |
|
34526 | 64 |
val split_begin = removed.takeWhile(_.start < change.start). |
65 |
map (t => new Token(t.start, |
|
66 |
t.content.substring(0, change.start - t.start), |
|
67 |
t.kind)) |
|
68 |
val split_end = removed.dropWhile(_.stop < change.start + change.removed). |
|
69 |
map (t => new Token(change.start + change.added.length, |
|
70 |
t.content.substring(change.start + change.removed - t.start), |
|
71 |
t.kind)) |
|
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
72 |
|
34526 | 73 |
var invalid_tokens = split_begin ::: |
74 |
new Token(change.start, change.added, Token.Kind.OTHER) :: split_end ::: end |
|
75 |
var new_tokens = Nil: List[Token] |
|
76 |
var old_suffix = Nil: List[Token] |
|
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
77 |
|
34526 | 78 |
val match_start = invalid_tokens.first.start |
79 |
val matcher = ProofDocument.token_pattern.matcher(Token.string_from_tokens(invalid_tokens)) |
|
80 |
||
81 |
while (matcher.find() && invalid_tokens != Nil) { |
|
34485 | 82 |
val kind = |
34505
87f4f70d61bb
ProofDocument: pass is_command_keyword directly, not via full-blown Prover object;
wenzelm
parents:
34496
diff
changeset
|
83 |
if (is_command_keyword(matcher.group)) |
34485 | 84 |
Token.Kind.COMMAND_START |
34494 | 85 |
else if (matcher.end - matcher.start > 2 && matcher.group.substring(0, 2) == "(*") |
34485 | 86 |
Token.Kind.COMMENT |
87 |
else |
|
88 |
Token.Kind.OTHER |
|
34526 | 89 |
val new_token = new Token(match_start + matcher.start, matcher.group, kind) |
90 |
new_tokens ::= new_token |
|
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
91 |
|
34526 | 92 |
invalid_tokens = invalid_tokens dropWhile (_.stop < new_token.stop) |
93 |
invalid_tokens match { |
|
94 |
case t::ts => if(t.start == new_token.start && |
|
95 |
t.start > change.start + change.added.length) { |
|
96 |
old_suffix = ts |
|
97 |
invalid_tokens = Nil |
|
98 |
} |
|
99 |
case _ => |
|
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
100 |
} |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
101 |
} |
34526 | 102 |
val insert = new_tokens.reverse |
34531 | 103 |
this.tokens = (new LinearSet() ++ (begin ::: insert ::: old_suffix)).asInstanceOf[LinearSet[Token]] |
34526 | 104 |
|
105 |
token_changed(begin.lastOption, |
|
106 |
insert, |
|
107 |
removed, |
|
108 |
old_suffix.firstOption) |
|
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
109 |
} |
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
110 |
|
34485 | 111 |
/** command view **/ |
112 |
||
113 |
val structural_changes = new EventBus[StructureChange] |
|
114 |
||
34496
1b2995592bb9
renamed getNextCommandContaining to find_command_at;
wenzelm
parents:
34494
diff
changeset
|
115 |
def find_command_at(pos: Int): Command = { |
34485 | 116 |
for (cmd <- commands) { if (pos < cmd.stop) return cmd } |
117 |
return null |
|
118 |
} |
|
119 |
||
34526 | 120 |
private def token_changed(before_change: Option[Token], |
121 |
inserted_tokens: List[Token], |
|
122 |
removed_tokens: List[Token], |
|
123 |
after_change: Option[Token]) |
|
34485 | 124 |
{ |
34531 | 125 |
val commands = List() ++ this.commands |
34526 | 126 |
val (begin, remaining) = |
127 |
before_change match { |
|
128 |
case None => (Nil, commands) |
|
129 |
case Some(bc) => commands.break(_.tokens.contains(bc)) |
|
130 |
} |
|
131 |
val (_removed, _end) = |
|
132 |
after_change match { |
|
133 |
case None => (remaining, Nil) |
|
134 |
case Some(ac) => remaining.break(_.tokens.contains(ac)) |
|
135 |
} |
|
136 |
val (removed, end) = _end match { |
|
137 |
case Nil => (_removed, Nil) |
|
138 |
case acc::end => if (after_change.isDefined && after_change.get.kind == Token.Kind.COMMAND_START) |
|
139 |
(_removed, _end) |
|
140 |
else (_removed ::: List(acc), end) |
|
34485 | 141 |
} |
34526 | 142 |
val all_removed_tokens = for(c <- removed; t <- c.tokens) yield t |
143 |
val (pseudo_new_pre, rest) = |
|
144 |
if (! before_change.isDefined) (Nil, all_removed_tokens) |
|
145 |
else { |
|
146 |
val (a, b) = all_removed_tokens.span (_ != before_change.get) |
|
147 |
b match { |
|
148 |
case Nil => (a, Nil) |
|
149 |
case bc::rest => (a ::: List(bc), b) |
|
150 |
} |
|
34485 | 151 |
} |
34526 | 152 |
val pseudo_new_post = rest.dropWhile(Some(_) != after_change) |
34485 | 153 |
|
34526 | 154 |
def tokens_to_commands(tokens: List[Token]): List[Command]= { |
155 |
tokens match { |
|
156 |
case Nil => Nil |
|
157 |
case t::ts => |
|
158 |
val (cmd,rest) = ts.span(_.kind != Token.Kind.COMMAND_START) |
|
159 |
new Command(t::cmd) :: tokens_to_commands (rest) |
|
34485 | 160 |
} |
161 |
} |
|
162 |
||
34526 | 163 |
System.err.println("ins_tokens: " + inserted_tokens) |
164 |
val new_commands = tokens_to_commands(pseudo_new_pre ::: inserted_tokens ::: pseudo_new_post) |
|
165 |
System.err.println("new_commands: " + new_commands) |
|
34485 | 166 |
|
34531 | 167 |
this.commands = (LinearSet() ++ (begin ::: new_commands ::: end)).asInstanceOf[LinearSet[Command]] |
34526 | 168 |
val before = begin match {case Nil => None case _ => Some (begin.last)} |
169 |
structural_changes.event(new StructureChange(before, new_commands, removed)) |
|
34485 | 170 |
} |
34318
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff
changeset
|
171 |
} |