]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/mathml_editor/src/TDictionary.cc
* code cleanup
[helm.git] / helm / DEVEL / mathml_editor / src / TDictionary.cc
1
2 #include <sstream>
3
4 #include "dom.hh"
5 #include "TDictionary.hh"
6 #include "TTokenizer.hh"
7 #include "CLoggerConsole.hh"
8
9 static TDictionary::Entry undefinedEntry;
10
11 void
12 TDictionary::load(const char* uri)
13 {
14   DOM::DOMImplementation di;
15
16   DOM::Document doc = di.createDocumentFromURI(uri);
17   assert(doc);
18
19   DOM::Element root = doc.get_documentElement();
20   assert(root);
21
22   CLoggerConsole logger;
23   TTokenizer tokenizer(logger);
24
25   for (DOM::Node p = root.get_firstChild(); p; p = p.get_nextSibling())
26     if (p.get_nodeType() == DOM::Node::ELEMENT_NODE && p.get_nodeName() == "entry")
27       {
28         DOM::Element el = p;
29         assert(el);
30         assert(el.hasAttribute("name"));
31
32         std::string name = el.getAttribute("name");
33         if (entries.find(name) != entries.end())
34           cerr << "WARNING: entry `" << name << "' is being redefined" << endl;
35
36         Entry entry;
37
38         if (el.hasAttribute("class"))
39           {
40             std::string cls = el.getAttribute("class");
41             if (cls == "o") entry.cls = OPERATOR;
42             else if (cls == "i") entry.cls = IDENTIFIER;
43             else if (cls == "n") entry.cls == NUMBER;
44             else entry.cls = MACRO;
45           }
46         else
47           entry.cls = MACRO;
48
49         if (el.hasAttribute("val"))
50           {
51             entry.value = el.getAttribute("val");
52             if (entry.cls == MACRO)
53               cerr << "WARNING: `" << name << "' has a specified value, but is classified as macro" << endl;
54           }
55
56         if (el.hasAttribute("pattern"))
57           {
58             if (entry.cls != MACRO)
59               cerr << "WARNING: `" << name << "' has a specified pattern, but is not classified as macro" << endl;
60
61             std::string pattern = el.getAttribute("pattern");
62             if (pattern == "{}")
63               entry.leftOpen = entry.rightOpen = 1;
64             else if (pattern == "{")
65               entry.leftOpen = 1;
66             else if (pattern == "}")
67               entry.rightOpen = 1;
68             else
69               entry.pattern = tokenizer.tokenize(pattern);
70           }
71
72         if (el.hasAttribute("infix"))
73           {
74             std::istringstream is(el.getAttribute("infix"));
75             unsigned infix;
76             is >> infix;
77             entry.infix = infix;
78             if (!el.hasAttribute("prefix")) entry.prefix = infix;
79             if (!el.hasAttribute("postfix")) entry.postfix = infix;
80           }
81
82         if (el.hasAttribute("prefix"))
83           {
84             std::istringstream is(el.getAttribute("prefix"));
85             unsigned prefix;
86             is >> prefix;
87             entry.prefix = prefix;
88             if (!el.hasAttribute("infix"))
89               {
90                 entry.infix = prefix;
91                 if (!el.hasAttribute("postfix")) entry.postfix = prefix;
92               }
93           }
94
95         if (el.hasAttribute("postfix"))
96           {
97             std::istringstream is(el.getAttribute("postfix"));
98             unsigned postfix;
99             is >> postfix;
100             entry.postfix = postfix;
101             if (!el.hasAttribute("infix"))
102               {
103                 entry.infix = postfix;
104                 if (!el.hasAttribute("prefix")) entry.prefix = postfix;
105               }
106           }
107
108         if (el.hasAttribute("limits"))
109           {
110             std::istringstream is(el.getAttribute("limits"));
111             unsigned limits;
112             is >> limits;
113             entry.limits = limits;
114           }
115
116         if (el.hasAttribute("embellishment"))
117           {
118             std::istringstream is(el.getAttribute("embellishment"));
119             unsigned embellishment;
120             is >> embellishment;
121             entry.embellishment = embellishment;
122           }
123
124         if (el.hasAttribute("delimiter"))
125           {
126             if (entry.cls != OPERATOR && !entry.embellishment)
127               cerr << "WARNING: `" << name << "' delimiter ignored for non-operator" << endl;
128
129             std::istringstream is(el.getAttribute("delimiter"));
130             unsigned delimiter;
131             is >> delimiter;
132             entry.delimiter = delimiter;
133           }
134
135         if (el.hasAttribute("table"))
136           {
137             if (entry.cls != MACRO)
138               cerr << "WARNING: `" << name << "' table ignored for non-macro" << endl;
139
140             std::istringstream is(el.getAttribute("table"));
141             unsigned table;
142             is >> table;
143             entry.table = table;
144           }
145
146         entries[name] = entry;
147       }
148 }
149
150 const TDictionary::Entry&
151 TDictionary::find(const std::string& name) const
152 {
153   Dictionary::const_iterator p = entries.find(name);
154   if (p != entries.end()) return (*p).second;
155   else
156     {
157       cerr << "ERROR: unknown entry `" << name << "'" << endl;
158       return undefinedEntry;
159     }
160 }
161
162 bool
163 TDictionary::Entry::paramDelimited(unsigned i) const
164 {
165   assert(i < pattern.size());
166   assert(pattern[i].category == TToken::PARAMETER);
167   // a parameter is delimited if it is NOT the last one
168   // AND the next argument is not a parameter
169   return i + 1 < pattern.size() && pattern[i + 1].category != TToken::PARAMETER;
170 }
171
172 bool
173 TDictionary::Entry::lastDelimiter(unsigned i) const
174 {
175   assert(i < pattern.size());
176   assert(pattern[i].category != TToken::PARAMETER);
177   // a token is the last delimiter if it is the last token 
178   // of the pattern or if the next token is a parameter)
179   return i + 1 == pattern.size() || pattern[i + 1].category == TToken::PARAMETER;
180 }
181
182 unsigned
183 TDictionary::Entry::previousParam(unsigned i) const
184 {
185   // this method return the position in the pattern of the 
186   // parameter placed in a position preceding i.
187   // If no preceding i parameter present, the method return
188   // pattern.size().
189   // To know the position of the last parameter, call this 
190   // method with i == pattern.size()
191   unsigned j = i - 1;
192
193   while (pattern[j].category != TToken::PARAMETER)
194     {
195       if (j) j--;
196       else return pattern.size();
197     }
198   return j;
199 }