27901
|
1 |
/* Title: Pure/General/symbol.scala
|
|
2 |
ID: $Id$
|
|
3 |
Author: Makarius
|
|
4 |
|
|
5 |
Basic support for Isabelle symbols.
|
|
6 |
*/
|
|
7 |
|
|
8 |
package isabelle
|
|
9 |
|
|
10 |
import java.util.regex.Pattern
|
27918
|
11 |
import java.io.File
|
|
12 |
import scala.io.Source
|
|
13 |
import scala.collection.mutable.HashMap
|
27901
|
14 |
|
|
15 |
|
|
16 |
object Symbol {
|
|
17 |
|
27918
|
18 |
/* Regexp utils */
|
27901
|
19 |
|
|
20 |
private def compile(s: String) =
|
|
21 |
Pattern.compile(s, Pattern.COMMENTS | Pattern.DOTALL)
|
|
22 |
|
27918
|
23 |
|
|
24 |
/* Symbol regexps */
|
|
25 |
|
27901
|
26 |
private val symbol_src = """ \\ \\? < (?:
|
|
27 |
\^? [A-Za-z][A-Za-z0-9_']* |
|
|
28 |
\^raw: [\x20-\x7e\u0100-\uffff && [^.>]]* ) >"""
|
|
29 |
|
|
30 |
private val bad_symbol_src = "(?!" + symbol_src + ")" +
|
27918
|
31 |
""" \\ \\? < (?: (?! \s | [\"`\\] | \(\* | \*\) | \{\* | \*\} ) . )*"""
|
27901
|
32 |
|
|
33 |
val symbol_pattern = compile(symbol_src)
|
|
34 |
val bad_symbol_pattern = compile(bad_symbol_src)
|
|
35 |
val pattern = compile(symbol_src + "|" + bad_symbol_src + "| .")
|
27918
|
36 |
|
|
37 |
|
|
38 |
/* Symbol interpretation tables */
|
|
39 |
|
|
40 |
private val empty_pattern = compile(""" ^\s* (?: \#.* )? $ """)
|
|
41 |
private val blank_pattern = compile(""" \s+ """)
|
|
42 |
private val key_pattern = compile(""" (.+): """)
|
|
43 |
|
|
44 |
class Interpretation extends HashMap[String, List[(String, String)]] {
|
|
45 |
|
|
46 |
class BadEntry(val line: String) extends Exception
|
|
47 |
|
|
48 |
def read_line(line: String) = {
|
|
49 |
def err() = throw new BadEntry ("Bad symbol specification: " + line)
|
|
50 |
|
|
51 |
def read_pairs(props: List[String]): List[(String, String)] = {
|
|
52 |
props match {
|
|
53 |
case Nil => Nil
|
|
54 |
case _ :: Nil => err()
|
|
55 |
case key :: value :: rest => {
|
|
56 |
val key_matcher = key_pattern.matcher(key)
|
|
57 |
if (key_matcher.matches) { (key_matcher.group(1) -> value) :: read_pairs(rest) }
|
|
58 |
else err ()
|
|
59 |
}
|
|
60 |
}
|
|
61 |
}
|
|
62 |
|
|
63 |
if (!empty_pattern.matcher(line).matches) {
|
|
64 |
blank_pattern.split(line).toList match {
|
|
65 |
case Nil => err()
|
|
66 |
case symbol :: props => this + (symbol -> read_pairs(props))
|
|
67 |
}
|
|
68 |
}
|
|
69 |
}
|
|
70 |
|
|
71 |
for (base <- List(IsabelleSystem.ISABELLE_HOME, IsabelleSystem.ISABELLE_HOME_USER)) {
|
|
72 |
val file = new File(base + File.separator + "etc" + File.separator + "symbols")
|
|
73 |
if (file.canRead) {
|
|
74 |
for (line <- Source.fromFile(file).getLines) read_line(line)
|
|
75 |
}
|
|
76 |
}
|
|
77 |
}
|
|
78 |
|
27901
|
79 |
}
|