]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_codesigning/antlr2/src/BaseAST.cpp
1 /* ANTLR Translator Generator
2 * Project led by Terence Parr at http://www.jGuru.com
3 * Software rights: http://www.antlr.org/license.html
5 * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/BaseAST.cpp#2 $
8 #include "antlr/config.hpp"
12 #include "antlr/AST.hpp"
13 #include "antlr/BaseAST.hpp"
15 ANTLR_USING_NAMESPACE(std
)
16 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
20 size_t BaseAST::getNumberOfChildren() const
22 RefBaseAST t
= this->down
;
37 void BaseAST::doWorkForFindAll(
38 ANTLR_USE_NAMESPACE(std
)vector
<RefAST
>& v
,
39 RefAST target
,bool partialMatch
)
41 // Start walking sibling lists, looking for matches.
42 for (RefAST sibling
=this;
44 sibling
=sibling
->getNextSibling())
46 if ( (partialMatch
&& sibling
->equalsTreePartial(target
)) ||
47 (!partialMatch
&& sibling
->equalsTree(target
)) ) {
50 // regardless of match or not, check any children for matches
51 if ( sibling
->getFirstChild() ) {
52 RefBaseAST(sibling
->getFirstChild())->doWorkForFindAll(v
, target
, partialMatch
);
57 /** Is t an exact structural and equals() match of this tree. The
58 * 'this' reference is considered the start of a sibling list.
60 bool BaseAST::equalsList(RefAST t
) const
62 // the empty tree is not a match of any non-null tree.
66 // Otherwise, start walking sibling lists. First mismatch, return false.
69 sibling
=sibling
->getNextSibling(), t
=t
->getNextSibling()) {
70 // as a quick optimization, check roots first.
71 if (!sibling
->equals(t
))
73 // if roots match, do full list match test on children.
74 if (sibling
->getFirstChild()) {
75 if (!sibling
->getFirstChild()->equalsList(t
->getFirstChild()))
78 // sibling has no kids, make sure t doesn't either
79 else if (t
->getFirstChild())
86 // one sibling list has more than the other
90 /** Is 'sub' a subtree of this list?
91 * The siblings of the root are NOT ignored.
93 bool BaseAST::equalsListPartial(RefAST sub
) const
95 // the empty tree is always a subset of any tree.
99 // Otherwise, start walking sibling lists. First mismatch, return false.
101 for (;sibling
&& sub
;
102 sibling
=sibling
->getNextSibling(), sub
=sub
->getNextSibling()) {
103 // as a quick optimization, check roots first.
104 if (!sibling
->equals(sub
))
106 // if roots match, do partial list match test on children.
107 if (sibling
->getFirstChild())
108 if (!sibling
->getFirstChild()->equalsListPartial(sub
->getFirstChild()))
113 // nothing left to match in this tree, but subtree has more
116 // either both are null or sibling has more, but subtree doesn't
120 /** Is tree rooted at 'this' equal to 't'? The siblings
121 * of 'this' are ignored.
123 bool BaseAST::equalsTree(RefAST t
) const
128 // if roots match, do full list match test on children.
129 if (getFirstChild()) {
130 if (!getFirstChild()->equalsList(t
->getFirstChild()))
133 // sibling has no kids, make sure t doesn't either
134 else if (t
->getFirstChild())
140 /** Is 'sub' a subtree of the tree rooted at 'this'? The siblings
141 * of 'this' are ignored.
143 bool BaseAST::equalsTreePartial(RefAST sub
) const
145 // the empty tree is always a subset of any tree.
152 // if roots match, do full list partial match test on children.
154 if (!getFirstChild()->equalsListPartial(sub
->getFirstChild()))
160 /** Walk the tree looking for all exact subtree matches. Return
161 * an ASTEnumerator that lets the caller walk the list
162 * of subtree roots found herein.
164 ANTLR_USE_NAMESPACE(std
)vector
<RefAST
> BaseAST::findAll(RefAST target
)
166 ANTLR_USE_NAMESPACE(std
)vector
<RefAST
> roots
;
168 // the empty tree cannot result in an enumeration
170 doWorkForFindAll(roots
,target
,false); // find all matches recursively
176 /** Walk the tree looking for all subtrees. Return
177 * an ASTEnumerator that lets the caller walk the list
178 * of subtree roots found herein.
180 ANTLR_USE_NAMESPACE(std
)vector
<RefAST
> BaseAST::findAllPartial(RefAST target
)
182 ANTLR_USE_NAMESPACE(std
)vector
<RefAST
> roots
;
184 // the empty tree cannot result in an enumeration
186 doWorkForFindAll(roots
,target
,true); // find all matches recursively
191 ANTLR_USE_NAMESPACE(std
)string
BaseAST::toStringList() const
193 ANTLR_USE_NAMESPACE(std
)string ts
="";
199 ts
+=getFirstChild()->toStringList();
208 if (getNextSibling())
209 ts
+=getNextSibling()->toStringList();
214 ANTLR_USE_NAMESPACE(std
)string
BaseAST::toStringTree() const
216 ANTLR_USE_NAMESPACE(std
)string ts
= "";
222 ts
+=getFirstChild()->toStringList();
233 #ifdef ANTLR_SUPPORT_XML
234 /* This whole XML output stuff needs a little bit more thought
235 * I'd like to store extra XML data in the node. e.g. for custom ast's
236 * with for instance symboltable references. This
237 * should be more pluggable..
238 * @returns boolean value indicating wether a closetag should be produced.
240 bool BaseAST::attributesToStream( ANTLR_USE_NAMESPACE(std
)ostream
& out
) const
242 out
<< "text=\"" << this->getText()
243 << "\" type=\"" << this->getType() << "\"";
248 void BaseAST::toStream( ANTLR_USE_NAMESPACE(std
)ostream
& out
) const
250 for( RefAST node
= this; node
!= 0; node
= node
->getNextSibling() )
252 out
<< "<" << this->typeName() << " ";
254 // Write out attributes and if there is extra data...
255 bool need_close_tag
= node
->attributesToStream( out
);
259 // got children so write them...
260 if( node
->getFirstChild() != 0 )
261 node
->getFirstChild()->toStream( out
);
263 // and a closing tag..
264 out
<< "</" << node
->typeName() << ">" << endl
;
270 // this is nasty, but it makes the code generation easier
271 ANTLR_API RefAST nullAST
;
273 #if defined(_MSC_VER) && !defined(__ICL) // Microsoft Visual C++
274 extern ANTLR_API AST
* const nullASTptr
= 0;
276 ANTLR_API AST
* const nullASTptr
= 0;
279 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE