// ptreeact.cc see license.txt for copyright and terms of use // code for ptreeact.h #include "ptreeact.h" // this module #include "ptreenode.h" // PTreeNode #include "parsetables.h" // ParseTables #include "trace.h" // trace // ------------------- ParseTreeLexer ------------------- ParseTreeLexer::ParseTreeLexer(LexerInterface *u, UserActions *a) : underlying(u), underToken(u->getTokenFunc()), actions(a) { // the underlying lexer is already primed copyFields(); } STATICDEF void ParseTreeLexer::nextToken(LexerInterface *lex) { ParseTreeLexer *ths = static_cast(lex); // call underlying token function ths->underToken(ths->underlying); // grab its fields ths->copyFields(); } void ParseTreeLexer::copyFields() { type = underlying->type; loc = underlying->loc; // leak underlying's 'sval'.. we'll just assume it doesn't matter // my sval is always a newly-allocated PTreeNode, with no children, // and named according to the name of the token yielded PTreeNode *ret = new PTreeNode(actions->terminalName(type)); sval = (SemanticValue)ret; } string ParseTreeLexer::tokenDesc() const { return underlying->tokenDesc(); } string ParseTreeLexer::tokenKindDesc(int kind) const { return underlying->tokenKindDesc(kind); } // ---------------------- ParseTreeActions ------------------- STATICDEF SemanticValue ParseTreeActions::reduce( UserActions *context, int productionId, SemanticValue const *svals SOURCELOCARG( SourceLoc loc ) ) { ParseTreeActions *ths = static_cast(context); // get info about this production ParseTables::ProdInfo const &info = ths->tables->getProdInfo(productionId); xassert(info.rhsLen <= PTreeNode::MAXCHILDREN); // make a bare PTreeNode, labeled with the LHS nonterminal name PTreeNode *ret = new PTreeNode(ths->underlying->nonterminalName(info.lhsIndex)); // add the children for (int i=0; i < info.rhsLen; i++) { ret->children[i] = (PTreeNode*)svals[i]; } ret->numChildren = info.rhsLen; return (SemanticValue)ret; } SemanticValue ParseTreeActions::mergeAlternativeParses( int ntIndex, SemanticValue left, SemanticValue right SOURCELOCARG( SourceLoc loc ) ) { trace("ptreeactMerge") << underlying->nonterminalName(ntIndex) << "\n"; // link the ambiguities together in the usual way PTreeNode *L = (PTreeNode*)left; PTreeNode *R = (PTreeNode*)right; L->addAlternative(R); return left; } char const *ParseTreeActions::terminalName(int termId) { return underlying->terminalName(termId); } char const *ParseTreeActions::nonterminalName(int termId) { return underlying->nonterminalName(termId); }