5 #include "TDictionary.hh"
6 #include "TTokenizer.hh"
8 static TDictionary::Entry undefinedEntry;
11 TDictionary::load(const char* uri)
13 DOM::DOMImplementation di;
15 DOM::Document doc = di.createDocumentFromURI(uri);
18 DOM::Element root = doc.get_documentElement();
23 for (DOM::Node p = root.get_firstChild(); p; p = p.get_nextSibling())
24 if (p.get_nodeType() == DOM::Node::ELEMENT_NODE && p.get_nodeName() == "entry")
28 assert(el.hasAttribute("name"));
30 std::string name = el.getAttribute("name");
31 if (entries.find(name) != entries.end())
32 cerr << "WARNING: entry `" << name << "' is being redefined" << endl;
36 if (el.hasAttribute("class"))
38 std::string cls = el.getAttribute("class");
39 if (cls == "o") entry.cls = OPERATOR;
40 else if (cls == "i") entry.cls = IDENTIFIER;
41 else if (cls == "n") entry.cls == NUMBER;
42 else entry.cls = MACRO;
47 if (el.hasAttribute("val"))
49 entry.value = el.getAttribute("val");
50 if (entry.cls == MACRO)
51 cerr << "WARNING: `" << name << "' has a specified value, but is classified as macro" << endl;
54 if (el.hasAttribute("pattern"))
56 if (entry.cls != MACRO)
57 cerr << "WARNING: `" << name << "' has a specified pattern, but is not classified as macro" << endl;
59 std::string pattern = el.getAttribute("pattern");
61 entry.leftOpen = entry.rightOpen = 1;
62 else if (pattern == "{")
64 else if (pattern == "}")
67 entry.pattern = tokenizer.tokenize(pattern);
70 if (el.hasAttribute("infix"))
72 std::istringstream is(el.getAttribute("infix"));
76 if (!el.hasAttribute("prefix")) entry.prefix = infix;
77 if (!el.hasAttribute("postfix")) entry.postfix = infix;
80 if (el.hasAttribute("prefix"))
82 std::istringstream is(el.getAttribute("prefix"));
85 entry.prefix = prefix;
86 if (!el.hasAttribute("infix"))
89 if (!el.hasAttribute("postfix")) entry.postfix = prefix;
93 if (el.hasAttribute("postfix"))
95 std::istringstream is(el.getAttribute("postfix"));
98 entry.postfix = postfix;
99 if (!el.hasAttribute("infix"))
101 entry.infix = postfix;
102 if (!el.hasAttribute("prefix")) entry.prefix = postfix;
106 if (el.hasAttribute("limits"))
108 std::istringstream is(el.getAttribute("limits"));
111 entry.limits = limits;
114 if (el.hasAttribute("embellishment"))
116 std::istringstream is(el.getAttribute("embellishment"));
117 unsigned embellishment;
119 entry.embellishment = embellishment;
122 if (el.hasAttribute("delimiter"))
124 if (entry.cls != OPERATOR && !entry.embellishment)
125 cerr << "WARNING: `" << name << "' delimiter ignored for non-operator" << endl;
127 std::istringstream is(el.getAttribute("delimiter"));
130 entry.delimiter = delimiter;
133 if (el.hasAttribute("table"))
135 if (entry.cls != MACRO)
136 cerr << "WARNING: `" << name << "' table ignored for non-macro" << endl;
138 std::istringstream is(el.getAttribute("table"));
144 entries[name] = entry;
148 const TDictionary::Entry&
149 TDictionary::find(const std::string& name) const
151 Dictionary::const_iterator p = entries.find(name);
152 if (p != entries.end()) return (*p).second;
155 cerr << "ERROR: unknown entry `" << name << "'" << endl;
156 return undefinedEntry;
161 TDictionary::Entry::paramDelimited(unsigned i) const
163 assert(i < pattern.size());
164 assert(pattern[i].category == TToken::PARAMETER);
165 // a parameter is delimited if it is NOT the last one
166 // AND the next argument is not a parameter
167 return i + 1 < pattern.size() && pattern[i + 1].category != TToken::PARAMETER;