5 #include "TDictionary.hh"
6 #include "TTokenizer.hh"
7 #include "CLoggerConsole.hh"
9 static TDictionary::Entry undefinedEntry;
12 TDictionary::load(const char* uri)
14 DOM::DOMImplementation di;
16 DOM::Document doc = di.createDocumentFromURI(uri);
19 DOM::Element root = doc.get_documentElement();
22 CLoggerConsole logger;
23 TTokenizer tokenizer(logger);
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")
30 assert(el.hasAttribute("name"));
32 std::string name = el.getAttribute("name");
33 if (entries.find(name) != entries.end())
34 cerr << "WARNING: entry `" << name << "' is being redefined" << endl;
38 if (el.hasAttribute("class"))
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;
49 if (el.hasAttribute("val"))
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;
56 if (el.hasAttribute("pattern"))
58 if (entry.cls != MACRO)
59 cerr << "WARNING: `" << name << "' has a specified pattern, but is not classified as macro" << endl;
61 std::string pattern = el.getAttribute("pattern");
63 entry.leftOpen = entry.rightOpen = 1;
64 else if (pattern == "{")
66 else if (pattern == "}")
69 entry.pattern = tokenizer.tokenize(pattern);
72 if (el.hasAttribute("infix"))
74 std::istringstream is(el.getAttribute("infix"));
78 if (!el.hasAttribute("prefix")) entry.prefix = infix;
79 if (!el.hasAttribute("postfix")) entry.postfix = infix;
82 if (el.hasAttribute("prefix"))
84 std::istringstream is(el.getAttribute("prefix"));
87 entry.prefix = prefix;
88 if (!el.hasAttribute("infix"))
91 if (!el.hasAttribute("postfix")) entry.postfix = prefix;
95 if (el.hasAttribute("postfix"))
97 std::istringstream is(el.getAttribute("postfix"));
100 entry.postfix = postfix;
101 if (!el.hasAttribute("infix"))
103 entry.infix = postfix;
104 if (!el.hasAttribute("prefix")) entry.prefix = postfix;
108 if (el.hasAttribute("limits"))
110 std::istringstream is(el.getAttribute("limits"));
113 entry.limits = limits;
116 if (el.hasAttribute("embellishment"))
118 std::istringstream is(el.getAttribute("embellishment"));
119 unsigned embellishment;
121 entry.embellishment = embellishment;
124 if (el.hasAttribute("delimiter"))
126 if (entry.cls != OPERATOR && !entry.embellishment)
127 cerr << "WARNING: `" << name << "' delimiter ignored for non-operator" << endl;
129 std::istringstream is(el.getAttribute("delimiter"));
132 entry.delimiter = delimiter;
135 if (el.hasAttribute("table"))
137 if (entry.cls != MACRO)
138 cerr << "WARNING: `" << name << "' table ignored for non-macro" << endl;
140 std::istringstream is(el.getAttribute("table"));
146 entries[name] = entry;
150 const TDictionary::Entry&
151 TDictionary::find(const std::string& name) const
153 Dictionary::const_iterator p = entries.find(name);
154 if (p != entries.end()) return (*p).second;
157 cerr << "ERROR: unknown entry `" << name << "'" << endl;
158 return undefinedEntry;
163 TDictionary::Entry::paramDelimited(unsigned i) const
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;
173 TDictionary::Entry::lastDelimiter(unsigned i) const
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;
183 TDictionary::Entry::previousParam(unsigned i) const
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
189 // To know the position of the last parameter, call this
190 // method with i == pattern.size()
193 while (pattern[j].category != TToken::PARAMETER)
196 else return pattern.size();