]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/DEVEL/mathml_editor/src/TDictionary.cc
Initial revision
[helm.git] / helm / DEVEL / mathml_editor / src / TDictionary.cc
diff --git a/helm/DEVEL/mathml_editor/src/TDictionary.cc b/helm/DEVEL/mathml_editor/src/TDictionary.cc
new file mode 100644 (file)
index 0000000..303d743
--- /dev/null
@@ -0,0 +1,168 @@
+
+#include <sstream>
+
+#include "dom.hh"
+#include "TDictionary.hh"
+#include "TTokenizer.hh"
+
+static TDictionary::Entry undefinedEntry;
+
+void
+TDictionary::load(const char* uri)
+{
+  DOM::DOMImplementation di;
+
+  DOM::Document doc = di.createDocumentFromURI(uri);
+  assert(doc);
+
+  DOM::Element root = doc.get_documentElement();
+  assert(root);
+
+  TTokenizer tokenizer;
+
+  for (DOM::Node p = root.get_firstChild(); p; p = p.get_nextSibling())
+    if (p.get_nodeType() == DOM::Node::ELEMENT_NODE && p.get_nodeName() == "entry")
+      {
+       DOM::Element el = p;
+       assert(el);
+       assert(el.hasAttribute("name"));
+
+       std::string name = el.getAttribute("name");
+       if (entries.find(name) != entries.end())
+         cerr << "WARNING: entry `" << name << "' is being redefined" << endl;
+
+       Entry entry;
+
+       if (el.hasAttribute("class"))
+         {
+           std::string cls = el.getAttribute("class");
+           if (cls == "o") entry.cls = OPERATOR;
+           else if (cls == "i") entry.cls = IDENTIFIER;
+           else if (cls == "n") entry.cls == NUMBER;
+           else entry.cls = MACRO;
+         }
+       else
+         entry.cls = MACRO;
+
+       if (el.hasAttribute("val"))
+         {
+           entry.value = el.getAttribute("val");
+           if (entry.cls == MACRO)
+             cerr << "WARNING: `" << name << "' has a specified value, but is classified as macro" << endl;
+         }
+
+       if (el.hasAttribute("pattern"))
+         {
+           if (entry.cls != MACRO)
+             cerr << "WARNING: `" << name << "' has a specified pattern, but is not classified as macro" << endl;
+
+           std::string pattern = el.getAttribute("pattern");
+           if (pattern == "{}")
+             entry.leftOpen = entry.rightOpen = 1;
+           else if (pattern == "{")
+             entry.leftOpen = 1;
+           else if (pattern == "}")
+             entry.rightOpen = 1;
+           else
+             entry.pattern = tokenizer.tokenize(pattern);
+         }
+
+       if (el.hasAttribute("infix"))
+         {
+           std::istringstream is(el.getAttribute("infix"));
+           unsigned infix;
+           is >> infix;
+           entry.infix = infix;
+           if (!el.hasAttribute("prefix")) entry.prefix = infix;
+           if (!el.hasAttribute("postfix")) entry.postfix = infix;
+         }
+
+       if (el.hasAttribute("prefix"))
+         {
+           std::istringstream is(el.getAttribute("prefix"));
+           unsigned prefix;
+           is >> prefix;
+           entry.prefix = prefix;
+           if (!el.hasAttribute("infix"))
+             {
+               entry.infix = prefix;
+               if (!el.hasAttribute("postfix")) entry.postfix = prefix;
+             }
+         }
+
+       if (el.hasAttribute("postfix"))
+         {
+           std::istringstream is(el.getAttribute("postfix"));
+           unsigned postfix;
+           is >> postfix;
+           entry.postfix = postfix;
+           if (!el.hasAttribute("infix"))
+             {
+               entry.infix = postfix;
+               if (!el.hasAttribute("prefix")) entry.prefix = postfix;
+             }
+         }
+
+       if (el.hasAttribute("limits"))
+         {
+           std::istringstream is(el.getAttribute("limits"));
+           unsigned limits;
+           is >> limits;
+           entry.limits = limits;
+         }
+
+       if (el.hasAttribute("embellishment"))
+         {
+           std::istringstream is(el.getAttribute("embellishment"));
+           unsigned embellishment;
+           is >> embellishment;
+           entry.embellishment = embellishment;
+         }
+
+       if (el.hasAttribute("delimiter"))
+         {
+           if (entry.cls != OPERATOR && !entry.embellishment)
+             cerr << "WARNING: `" << name << "' delimiter ignored for non-operator" << endl;
+
+           std::istringstream is(el.getAttribute("delimiter"));
+           unsigned delimiter;
+           is >> delimiter;
+           entry.delimiter = delimiter;
+         }
+
+       if (el.hasAttribute("table"))
+         {
+           if (entry.cls != MACRO)
+             cerr << "WARNING: `" << name << "' table ignored for non-macro" << endl;
+           
+           std::istringstream is(el.getAttribute("table"));
+           unsigned table;
+           is >> table;
+           entry.table = table;
+         }
+
+       entries[name] = entry;
+      }
+}
+
+const TDictionary::Entry&
+TDictionary::find(const std::string& name) const
+{
+  Dictionary::const_iterator p = entries.find(name);
+  if (p != entries.end()) return (*p).second;
+  else
+    {
+      cerr << "ERROR: unknown entry `" << name << "'" << endl;
+      return undefinedEntry;
+    }
+}
+
+bool
+TDictionary::Entry::paramDelimited(unsigned i) const
+{
+  assert(i < pattern.size());
+  assert(pattern[i].category == TToken::PARAMETER);
+  // a parameter is delimited if it is NOT the last one
+  // AND the next argument is not a parameter
+  return i + 1 < pattern.size() && pattern[i + 1].category != TToken::PARAMETER;
+}