summaryrefslogtreecommitdiffstats
path: root/poxml/antlr/src/BaseAST.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'poxml/antlr/src/BaseAST.cpp')
-rw-r--r--poxml/antlr/src/BaseAST.cpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/poxml/antlr/src/BaseAST.cpp b/poxml/antlr/src/BaseAST.cpp
new file mode 100644
index 00000000..4080e0e8
--- /dev/null
+++ b/poxml/antlr/src/BaseAST.cpp
@@ -0,0 +1,320 @@
+/**
+ * <b>SOFTWARE RIGHTS</b>
+ * <p>
+ * ANTLR 2.6.0 MageLang Insitute, 1998
+ * <p>
+ * We reserve no legal rights to the ANTLR--it is fully in the
+ * public domain. An individual or company may do whatever
+ * they wish with source code distributed with ANTLR or the
+ * code generated by ANTLR, including the incorporation of
+ * ANTLR, or its output, into commerical software.
+ * <p>
+ * We encourage users to develop software with ANTLR. However,
+ * we do ask that credit is given to us for developing
+ * ANTLR. By "credit", we mean that if you use ANTLR or
+ * incorporate any source code into one of your programs
+ * (commercial product, research project, or otherwise) that
+ * you acknowledge this fact somewhere in the documentation,
+ * research report, etc... If you like ANTLR and have
+ * developed a nice tool with the output, please mention that
+ * you developed it using ANTLR. In addition, we ask that the
+ * headers remain intact in our source code. As long as these
+ * guidelines are kept, we expect to continue enhancing this
+ * system and expect to make other tools available as they are
+ * completed.
+ * <p>
+ * The ANTLR gang:
+ * @version ANTLR 2.6.0 MageLang Insitute, 1998
+ * @author Terence Parr, <a href=http://www.MageLang.com>MageLang Institute</a>
+ * @author <br>John Lilley, <a href=http://www.Empathy.com>Empathy Software</a>
+ * @author <br><a href="mailto:pete@yamuna.demon.co.uk">Pete Wells</a>
+ */
+
+#include "antlr/BaseAST.hpp"
+
+ANTLR_BEGIN_NAMESPACE(antlr)
+
+//bool BaseAST::verboseStringConversion;
+//ANTLR_USE_NAMESPACE(std)vector<ANTLR_USE_NAMESPACE(std)string> BaseAST::tokenNames;
+
+void BaseAST::addChild(RefAST c)
+{
+ if (!c)
+ return;
+ RefBaseAST tmp=down;
+ if (tmp) {
+ while (tmp->right)
+ tmp=tmp->right;
+ tmp->right=c;
+ } else {
+ down=c;
+ }
+}
+
+void BaseAST::doWorkForFindAll(
+ ANTLR_USE_NAMESPACE(std)vector<RefAST>& v,
+ RefAST target,bool partialMatch)
+{
+ // Start walking sibling lists, looking for matches.
+ for (RefAST sibling=this;
+ sibling;
+ sibling=sibling->getNextSibling())
+ {
+ if ( (partialMatch && sibling->equalsTreePartial(target)) ||
+ (!partialMatch && sibling->equalsTree(target)) ) {
+ v.push_back(sibling);
+ }
+ // regardless of match or not, check any children for matches
+ if ( sibling->getFirstChild() ) {
+ RefBaseAST(sibling->getFirstChild())->doWorkForFindAll(v, target, partialMatch);
+ }
+ }
+
+}
+
+/** Is node t equal to this in terms of token type and text? */
+bool BaseAST::equals(RefAST t) const
+{
+ if (!t)
+ return false;
+ return (getText() == t->getText()) && (getType() == t->getType());
+}
+
+/** Is t an exact structural and equals() match of this tree. The
+ * 'this' reference is considered the start of a sibling list.
+ */
+bool BaseAST::equalsList(RefAST t) const
+{
+ // the empty tree is not a match of any non-null tree.
+ if (!t)
+ return false;
+
+ // Otherwise, start walking sibling lists. First mismatch, return false.
+ RefAST sibling=this;
+ for (;sibling && t;
+ sibling=sibling->getNextSibling(), t=t->getNextSibling()) {
+ // as a quick optimization, check roots first.
+ if (!sibling->equals(t))
+ return false;
+ // if roots match, do full list match test on children.
+ if (sibling->getFirstChild()) {
+ if (!sibling->getFirstChild()->equalsList(t->getFirstChild()))
+ return false;
+ }
+ // sibling has no kids, make sure t doesn't either
+ else if (t->getFirstChild())
+ return false;
+ }
+
+ if (!sibling && !t)
+ return true;
+
+ // one sibling list has more than the other
+ return false;
+}
+
+/** Is 'sub' a subtree of this list?
+ * The siblings of the root are NOT ignored.
+ */
+bool BaseAST::equalsListPartial(RefAST sub) const
+{
+ // the empty tree is always a subset of any tree.
+ if (!sub)
+ return true;
+
+ // Otherwise, start walking sibling lists. First mismatch, return false.
+ RefAST sibling=this;
+ for (;sibling && sub;
+ sibling=sibling->getNextSibling(), sub=sub->getNextSibling()) {
+ // as a quick optimization, check roots first.
+ if (!sibling->equals(sub))
+ return false;
+ // if roots match, do partial list match test on children.
+ if (sibling->getFirstChild())
+ if (!sibling->getFirstChild()->equalsListPartial(sub->getFirstChild()))
+ return false;
+ }
+
+ if (!sibling && sub)
+ // nothing left to match in this tree, but subtree has more
+ return false;
+
+ // either both are null or sibling has more, but subtree doesn't
+ return true;
+}
+
+/** Is tree rooted at 'this' equal to 't'? The siblings
+ * of 'this' are ignored.
+ */
+bool BaseAST::equalsTree(RefAST t) const
+{
+ // check roots first
+ if (!equals(t))
+ return false;
+ // if roots match, do full list match test on children.
+ if (getFirstChild()) {
+ if (!getFirstChild()->equalsList(t->getFirstChild()))
+ return false;
+ }
+ // sibling has no kids, make sure t doesn't either
+ else if (t->getFirstChild())
+ return false;
+
+ return true;
+}
+
+/** Is 'sub' a subtree of the tree rooted at 'this'? The siblings
+ * of 'this' are ignored.
+ */
+bool BaseAST::equalsTreePartial(RefAST sub) const
+{
+ // the empty tree is always a subset of any tree.
+ if (!sub)
+ return true;
+
+ // check roots first
+ if (!equals(sub))
+ return false;
+ // if roots match, do full list partial match test on children.
+ if (getFirstChild())
+ if (!getFirstChild()->equalsListPartial(sub->getFirstChild()))
+ return false;
+
+ return true;
+}
+
+/** Walk the tree looking for all exact subtree matches. Return
+ * an ASTEnumerator that lets the caller walk the list
+ * of subtree roots found herein.
+ */
+ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAll(RefAST target)
+{
+ ANTLR_USE_NAMESPACE(std)vector<RefAST> roots;
+
+ // the empty tree cannot result in an enumeration
+ if (target) {
+ doWorkForFindAll(roots,target,false); // find all matches recursively
+ }
+
+ return roots;
+}
+
+/** Walk the tree looking for all subtrees. Return
+ * an ASTEnumerator that lets the caller walk the list
+ * of subtree roots found herein.
+ */
+ANTLR_USE_NAMESPACE(std)vector<RefAST> BaseAST::findAllPartial(RefAST target)
+{
+ ANTLR_USE_NAMESPACE(std)vector<RefAST> roots;
+
+ // the empty tree cannot result in an enumeration
+ if (target) {
+ doWorkForFindAll(roots,target,true); // find all matches recursively
+ }
+
+ return roots;
+}
+
+RefAST BaseAST::getFirstChild() const
+{
+ return RefAST(down);
+}
+
+RefAST BaseAST::getNextSibling() const
+{
+ return RefAST(right);
+}
+
+ANTLR_USE_NAMESPACE(std)string BaseAST::getText() const
+{
+ return "";
+}
+
+int BaseAST::getType() const
+{
+ return 0;
+}
+
+void BaseAST::removeChildren()
+{
+ down=nullAST;
+}
+
+void BaseAST::setFirstChild(RefAST c)
+{
+ down=c;
+}
+
+void BaseAST::setNextSibling(RefAST n)
+{
+ right=n;
+}
+
+void BaseAST::setText(const ANTLR_USE_NAMESPACE(std)string& txt)
+{
+}
+
+void BaseAST::setType(int type)
+{
+}
+
+//void BaseAST::setVerboseStringConversion(bool verbose,
+// const ANTLR_USE_NAMESPACE(std)vector<ANTLR_USE_NAMESPACE(std)string>& names)
+//{
+// verboseStringConversion = verbose;
+// tokenNames = names;
+//}
+
+ANTLR_USE_NAMESPACE(std)string BaseAST::toString() const
+{
+// if ( verboseStringConversion &&
+// !getText().equalsIgnoreCase(tokenNames[getType()]) &&
+// !getText().equalsIgnoreCase(Tool.stripFrontBack(tokenNames[getType()],"\"","\"")) ) {
+// b.append('[');
+// b.append(getText());
+// b.append(",<");
+// b.append(tokenNames[getType()]);
+// b.append(">]");
+// return b.toString();
+// }
+ return getText();
+}
+
+ANTLR_USE_NAMESPACE(std)string BaseAST::toStringList() const
+{
+ ANTLR_USE_NAMESPACE(std)string ts="";
+ if (getFirstChild()) {
+ ts+=" ( ";
+ ts+=toString();
+ ts+=getFirstChild()->toStringList();
+ ts+=" )";
+ } else {
+ ts+=" ";
+ ts+=toString();
+ }
+ if (getNextSibling())
+ ts+=getNextSibling()->toStringList();
+ return ts;
+}
+
+ANTLR_USE_NAMESPACE(std)string BaseAST::toStringTree() const
+{
+ ANTLR_USE_NAMESPACE(std)string ts="";
+ if (getFirstChild()) {
+ ts+=" ( ";
+ ts+=toString();
+ ts+=getFirstChild()->toStringList();
+ ts+=" )";
+ } else {
+ ts+=" ";
+ ts+=toString();
+ }
+ return ts;
+}
+
+// this is nasty, but it makes the code generation easier
+RefAST nullAST;
+AST* const nullASTptr=0;
+
+ANTLR_END_NAMESPACE
+