예제 #1
0
void SCsTranslator::processSentenceAssign(pANTLR3_BASE_TREE node)
{
    unsigned int nodesCount = node->getChildCount(node);
    assert(nodesCount == 2);

    pANTLR3_BASE_TREE node_left = (pANTLR3_BASE_TREE)node->getChild(node, 0);
    pANTLR3_BASE_TREE node_right = (pANTLR3_BASE_TREE)node->getChild(node, 1);

    pANTLR3_COMMON_TOKEN tok_left = node_left->getToken(node_left);
    pANTLR3_COMMON_TOKEN tok_right = node_left->getToken(node_right);

    assert(tok_left && tok_right);

    if (tok_left->type != ID_SYSTEM)
    {
        THROW_EXCEPT(Exception::ERR_PARSE,
                     "Unsupported type of tokens at the left side of assignment sentence",
                     mParams.fileName,
                     tok_left->getLine(tok_left));
    }

    if (tok_right->type == ID_SYSTEM)
    {
        mAssignments[GET_NODE_TEXT(node_left)] = GET_NODE_TEXT(node_right);
    }
    else
    {
        String left_idtf = (GET_NODE_TEXT(node_left));
        sElement *el = parseElementTree(node_right, &left_idtf);
    }
}
예제 #2
0
void SCsTranslator::processSentenceLevel1(pANTLR3_BASE_TREE node)
{
    unsigned int nodesCount = node->getChildCount(node);
    assert(nodesCount == 3);

    pANTLR3_BASE_TREE node_obj = (pANTLR3_BASE_TREE)node->getChild(node, 0);
    pANTLR3_BASE_TREE node_pred = (pANTLR3_BASE_TREE)node->getChild(node, 1);
    pANTLR3_BASE_TREE node_subj = (pANTLR3_BASE_TREE)node->getChild(node, 2);

    pANTLR3_COMMON_TOKEN tok_pred = node_pred->getToken(node_pred);

    if (tok_pred->type != ID_SYSTEM)
    {
        THROW_EXCEPT(Exception::ERR_PARSE,
                     String("Invalid predicate '") + ((const char*) node_pred->getText(node_pred)->chars) + "' in simple sentence",
                     mParams.fileName,
                     tok_pred->getLine(tok_pred));
    }

    sElement *el_obj = parseElementTree(node_obj);
    sElement *el_subj = parseElementTree(node_subj);

    // determine arc type
    sc_type type = sc_type_edge_common;
    String pred = GET_NODE_TEXT(node_pred);
    size_t n = pred.find_first_of("#");
    if (n != pred.npos)
        type = _getArcPreffixType(pred.substr(0, n));

    _addEdge(el_obj, el_subj, type, false, pred);
}
ActualParamDef::ActualParamDef(const pANTLR3_BASE_TREE node)
    : ASTNode(node)
{
    assert(node->getType(node) == N_ACTUAL_PARAM);
    assert(node->getChildCount(node) == 2);

    pANTLR3_BASE_TREE n;

    {
        // param name
        n = (pANTLR3_BASE_TREE) node->getChild(node, 0);
        assert(n->getType(n) == N_PARAM_NAME);
        assert(n->getChildCount(n) == 1);

        n = (pANTLR3_BASE_TREE) n->getChild(n, 0);

        m_ParamName = (wchar_t*) n->getText(n)->chars;
    }

    {
        // value
        n = (pANTLR3_BASE_TREE) node->getChild(node, 1);
        assert(n->getType(n) == N_VALUE);

        createValueDef(n, m_pValue);
    }
}
	ArrayInitValueDef::ArrayInitValueDef(const pANTLR3_BASE_TREE node)
		: ValueDef(ARRAY_INIT, node)
	{
		assert(node->getType(node) == N_ARRAY_INIT_VAL);
		assert(node->getChildCount(node) == 2);

		pANTLR3_BASE_TREE n, c;

		{
			// type
			n = (pANTLR3_BASE_TREE) node->getChild(node, 0);
			assert(n->getType(n) == N_ARRAY_TYPE);
			
			m_pDeclaredType = boost::shared_ptr<Type>(static_cast<Type*>(new ArrayType(n)));
		}

		{
			// array values
			n = (pANTLR3_BASE_TREE) node->getChild(node, 1);
			assert(n->getType(n) == N_ARRAY_VALUES);

			m_Values.clear();

			int childCount = n->getChildCount(n);
			for (int i = 0; i < childCount; i++)
			{
				c = (pANTLR3_BASE_TREE) n->getChild(n, i);

				boost::shared_ptr<ValueDef> pValueDef;
				createValueDef(c, pValueDef);

				m_Values.push_back(pValueDef);
			}
		}
	}
	IntegerLiteralValueDef::IntegerLiteralValueDef(const pANTLR3_BASE_TREE node)
		: LiteralValueDef(INTEGER_LITERAL, node)
	{
		assert(node->getType(node) == N_INT_LITERAL);
		assert(node->getChildCount(node) == 1);

		pANTLR3_BASE_TREE n = (pANTLR3_BASE_TREE) node->getChild(node, 0);

		assert(n->getType(n) == INTL);

		wchar_t* szStr = (wchar_t*) n->getText(n)->chars;
		
		int value;

		try
		{
			value = boost::lexical_cast<int, wchar_t*>(szStr);
		}
		catch (const std::exception&)
		{
			boost::wformat f(L"Invalid integer value: %1% at line %2%");
			f % szStr % node->getLine(node);
			ParserException e(f.str());
			throw e;
		}

		m_IntValue = value;
	}
예제 #6
0
void SCsTranslator::dumpNode(pANTLR3_BASE_TREE node, std::ofstream &stream)
{
    StringStream ss;
    ss << node;

    String s_root = ss.str().substr(3);
    pANTLR3_COMMON_TOKEN tok = node->getToken(node);
    if (tok)
    {
        stream << s_root << " [shape=box];" << std::endl;
        String label((const char*) node->getText(node)->chars);
        std::replace(label.begin(), label.end(), '"', '\'');
        stream << s_root << " [label=\"" << label << "\"];" << std::endl;
    }
    else
        stream << s_root << " [shape=circle];" << std::endl;

    uint32 n = node->getChildCount(node);
    for (uint32 i = 0; i < n; ++i)
    {
        pANTLR3_BASE_TREE child = (pANTLR3_BASE_TREE) node->getChild(node, i);
        StringStream s1;
        s1 << child;

        stream << s_root << " -> " << s1.str().substr(3) << ";" << std::endl;
        dumpNode(child, stream);
    }
}
예제 #7
0
/** Transform ^(nil x) to x 
 */
static	pANTLR3_BASE_TREE	
   rulePostProcessing	(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE root)
{
    pANTLR3_BASE_TREE saveRoot;

    // Keep track of the root we are given. If it is a nilNode, then we
    // can reuse it rather than orphaning it!
    //
    saveRoot = root;

	if (root != NULL && root->isNilNode(root))
	{
		if	(root->getChildCount(root) == 0)
		{
			root = NULL;
		}
		else if	(root->getChildCount(root) == 1)
		{
			root = (pANTLR3_BASE_TREE)root->getChild(root, 0);
			root->setParent(root, NULL);
			root->setChildIndex(root, -1);

            // The root we were given was a nil node, wiht one child, which means it has
            // been abandoned and would be lost in the node factory. However
            // nodes can be flagged as resuable to prevent this terrible waste
            //
            saveRoot->reuse(saveRoot);
		}
	}

	return root;
}
예제 #8
0
/** Transform ^(nil x) to x 
 */
static	pANTLR3_BASE_TREE	
   rulePostProcessing	(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE root)
{

	if (root != NULL && root->isNil(root) && root->getChildCount(root) == 1)
	{
		root = root->getChild(root, 0);
	}

	return root;
}
예제 #9
0
void SCsTranslator::processSentenceLevel2_7(pANTLR3_BASE_TREE node)
{
    String connector = GET_NODE_TEXT(node);


    // determine object
    pANTLR3_BASE_TREE node_obj = (pANTLR3_BASE_TREE)node->getChild(node, 0);
    sElement *el_obj = _createElement(GET_NODE_TEXT(node_obj), 0);

    // no we need to parse attributes and predicates
    processAttrsIdtfList(true, node, el_obj, connector, false);
}
예제 #10
0
void emerson_createTreeMirrorImage(pANTLR3_BASE_TREE ptr)
{

    if(ptr!= NULL && ptr->children != NULL)
    {

        ANTLR3_UINT32 n = ptr->getChildCount(ptr);
        if(n == 1)
        {
            emerson_createTreeMirrorImage((pANTLR3_BASE_TREE)(ptr->getChild(ptr, 0)));
        }
        if(n == 2)  // should it be checked
        {
            pANTLR3_BASE_TREE right = (pANTLR3_BASE_TREE)(ptr->getChild(ptr, 1));
            emerson_createTreeMirrorImage( (pANTLR3_BASE_TREE)(ptr->getChild(ptr, 0)));
            emerson_createTreeMirrorImage( (pANTLR3_BASE_TREE)(ptr->getChild(ptr, 1)) );
            ptr->setChild(ptr, 1, ptr->getChild(ptr, 0));
            ptr->setChild(ptr, 0, right);
        }
    }
}
	ObjectInitValueDef::ObjectInitValueDef(const pANTLR3_BASE_TREE node)
		: ValueDef(OBJECT_INIT, node)
	{
		assert(node->getType(node) == N_OBJECT_INIT_VAL);
		assert(node->getChildCount(node) == 2);

		pANTLR3_BASE_TREE n, c;

		{
			// class name
			n = (pANTLR3_BASE_TREE) node->getChild(node, 0);
			assert(n->getType(n) == N_CLASS_NAME);
			assert(n->getChildCount(n) == 1);

			n = (pANTLR3_BASE_TREE) n->getChild(n, 0);
			assert(n->getType(n) == ID);

			wchar_t* szClassName = (wchar_t*) n->getText(n)->chars;
			m_ClassName = szClassName;
		}

		{
			m_ActualParamsMap.clear();

			// actual params
			n = (pANTLR3_BASE_TREE) node->getChild(node, 1);
			assert(n->getType(n) == N_ACTUAL_PARAMS);

			int childCount = n->getChildCount(n);
			for (int i = 0; i < childCount; i++)
			{
				c = (pANTLR3_BASE_TREE) n->getChild(n, i);
				assert(c->getType(c) == N_ACTUAL_PARAM);

				ActualParamDefPtr pActualParamDef(new ActualParamDef(c));
				m_ActualParamsMap[pActualParamDef->getParamName()] = pActualParamDef;
			}
		}
	}
static  void
toStringWork    (pANTLR3_TREE_NODE_STREAM tns, pANTLR3_BASE_TREE p, pANTLR3_BASE_TREE stop, pANTLR3_STRING buf)
{

        ANTLR3_UINT32   n;
        ANTLR3_UINT32   c;

        if      (!p->isNilNode(p) )
        {
                pANTLR3_STRING  text;

                text    = p->toString(p);

                if  (text == NULL)
                {
                        text = tns->ctns->stringFactory->newRaw(tns->ctns->stringFactory);

                        text->addc      (text, ' ');
                        text->addi      (text, p->getType(p));
                }

                buf->appendS(buf, text);
        }

        if      (p == stop)
        {
                return;         /* Finished */
        }

        n = p->getChildCount(p);

        if      (n > 0 && ! p->isNilNode(p) )
        {
                buf->addc   (buf, ' ');
                buf->addi   (buf, ANTLR3_TOKEN_DOWN);
        }

        for     (c = 0; c<n ; c++)
        {
                pANTLR3_BASE_TREE   child;

                child = p->getChild(p, c);
                tns->toStringWork(tns, child, stop, buf);
        }

        if      (n > 0 && ! p->isNilNode(p) )
        {
                buf->addc   (buf, ' ');
                buf->addi   (buf, ANTLR3_TOKEN_UP);
        }
}
예제 #13
0
/** If oldRoot is a nil root, just copy or move the children to newRoot.
 *  If not a nil root, make oldRoot a child of newRoot.
 *
 * \code
 *    old=^(nil a b c), new=r yields ^(r a b c)
 *    old=^(a b c), new=r yields ^(r ^(a b c))
 * \endcode
 *
 *  If newRoot is a nil-rooted single child tree, use the single
 *  child as the new root node.
 *
 * \code
 *    old=^(nil a b c), new=^(nil r) yields ^(r a b c)
 *    old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
 * \endcode
 *
 *  If oldRoot was null, it's ok, just return newRoot (even if isNilNode).
 *
 * \code
 *    old=null, new=r yields r
 *    old=null, new=^(nil r) yields ^(nil r)
 * \endcode
 *
 *  Return newRoot.  Throw an exception if newRoot is not a
 *  simple node or nil root with a single child node--it must be a root
 *  node.  If newRoot is <code>^(nil x)</endcode> return x as newRoot.
 *
 *  Be advised that it's ok for newRoot to point at oldRoot's
 *  children; i.e., you don't have to copy the list.  We are
 *  constructing these nodes so we should have this control for
 *  efficiency.
 */
static	pANTLR3_BASE_TREE	
becomeRoot	(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree)
{
	/* Protect against tree rewrites if we are in some sort of error
	 * state, but have tried to recover. In C we can end up with a null pointer
	 * for a tree that was not produced.
	 */
	if	(newRootTree == NULL)
	{
		return	oldRootTree;
	}

	/* root is just the new tree as is if there is no
	 * current root tree.
	 */
	if	(oldRootTree == NULL)
	{
		return	newRootTree;
	}

	/* Produce ^(nil real-node)
	 */
	if	(newRootTree->isNilNode(newRootTree))
	{
		if	(newRootTree->getChildCount(newRootTree) > 1)
		{
			/* TODO: Handle tree exceptions 
			 */
			ANTLR3_FPRINTF(stderr, "More than one node as root! TODO: Create tree exception hndling\n");
			return newRootTree;
		}

		/* The new root is the first child
		 */
		newRootTree = newRootTree->getChild(newRootTree, 0);
	}

	/* Add old root into new root. addChild takes care of the case where oldRoot
	 * is a flat list (nill rooted tree). All children of oldroot are added to
	 * new root.
	 */
	newRootTree->addChild(newRootTree, oldRootTree);

	/* Always returns new root structure
	 */
	return	newRootTree;

}
std::string MySQLRecognitionBase::dumpTree(pANTLR3_UINT8 *tokenNames, pANTLR3_BASE_TREE tree, const std::string &indentation)
{
  std::string result;

  ANTLR3_UINT32 char_pos = tree->getCharPositionInLine(tree);
  ANTLR3_UINT32 line = tree->getLine(tree);
  pANTLR3_STRING token_text = tree->getText(tree);

  pANTLR3_COMMON_TOKEN token = tree->getToken(tree);
  const char* utf8 = (const char*)token_text->chars;
  if (token != NULL)
  {
    ANTLR3_UINT32 token_type = token->getType(token);

    pANTLR3_UINT8 token_name;
    if (token_type == EOF)
      token_name = (pANTLR3_UINT8)"EOF";
    else
      token_name = tokenNames[token_type];

#ifdef ANTLR3_USE_64BIT
    result = base::strfmt("%s(line: %i, offset: %i, length: %" PRId64 ", index: %" PRId64 ", %s[%i])    %s\n",
                          indentation.c_str(), line, char_pos, token->stop - token->start + 1, token->index, token_name,
                          token_type, utf8);
#else
    result = base::strfmt("%s(line: %i, offset: %i, length: %i, index: %i, %s[%i])    %s\n",
                          indentation.c_str(), line, char_pos, token->stop - token->start + 1, token->index, token_name,
                          token_type, utf8);
#endif

  }
  else
  {
    result = base::strfmt("%s(line: %i, offset: %i, nil)    %s\n", indentation.c_str(), line, char_pos, utf8);
  }

  for (ANTLR3_UINT32 index = 0; index < tree->getChildCount(tree); index++)
  {
    pANTLR3_BASE_TREE child = (pANTLR3_BASE_TREE)tree->getChild(tree, index);
    std::string child_text = dumpTree(tokenNames, child, indentation + "\t");
    result += child_text;
  }
  return result;
}
예제 #15
0
/** Transform ^(nil x) to x 
 */
static	pANTLR3_BASE_TREE	
   rulePostProcessing	(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE root)
{
	if (root != NULL && root->isNilNode(root))
	{
		if	(root->getChildCount(root) == 0)
		{
			root = NULL;
		}
		else if	(root->getChildCount(root) == 1)
		{
			root = root->getChild(root, 0);
			root->setParent(root, NULL);
			root->setChildIndex(root, -1);
		}
	}

	return root;
}
예제 #16
0
/// Set the parent and child indexes for some of the children of the
/// supplied tree, starting with the child at the supplied index.
///
static	void
freshenPACIndexes	(pANTLR3_BASE_TREE tree, ANTLR3_UINT32 offset)
{
	ANTLR3_UINT32	count;
	ANTLR3_UINT32	c;

	count	= tree->getChildCount(tree);		// How many children do we have 

	// Loop from the supplied index and set the indexes and parent
	//
	for	(c = offset; c < count; c++)
	{
		pANTLR3_BASE_TREE	child;

		child = tree->getChild(tree, c);

		child->setChildIndex(child, c);
		child->setParent(child, tree);
	}
}
예제 #17
0
static ANTLR3_UINT32	    getCharPositionInLine	(pANTLR3_BASE_TREE tree)
{
	pANTLR3_COMMON_TOKEN    token;

	token   = ((pANTLR3_COMMON_TREE)(tree->super))->token;

	if	(token == NULL || token->getCharPositionInLine(token) == -1)
	{
		if  (tree->getChildCount(tree) > 0)
		{
			pANTLR3_BASE_TREE	child;

			child   = (pANTLR3_BASE_TREE)tree->getChild(tree, 0);

			return child->getCharPositionInLine(child);
		}
		return 0;
	}
	return  token->getCharPositionInLine(token);
}
예제 #18
0
void SCsTranslator::processAttrsIdtfList(bool ignore_first, pANTLR3_BASE_TREE node, sElement *el_obj, const String &connector, bool generate_order)
{

    sc_type type_connector = _getTypeByConnector(connector);

    tElementSet var_attrs, const_attrs;
    tElementSet subjects;
    uint32 n = node->getChildCount(node);
    uint32 idx = 1;
    for (uint32 i = ignore_first ? 1 : 0; i < n; ++i)
    {
        pANTLR3_BASE_TREE child = (pANTLR3_BASE_TREE)node->getChild(node, i);
        pANTLR3_COMMON_TOKEN tok = child->getToken(child);
        assert(tok);

        // skip internal sentences
        if (tok->type == SEP_LINT) continue;

        if (tok->type == SEP_ATTR_CONST || tok->type == SEP_ATTR_VAR)
        {
            if (!subjects.empty())
            {
                GENERATE_ATTRS(idx)
                subjects.clear();
                const_attrs.clear();
                var_attrs.clear();
            }
            pANTLR3_BASE_TREE nd = (pANTLR3_BASE_TREE)child->getChild(child, 0);
            sElement *el = _addNode(GET_NODE_TEXT(nd));
            if (tok->type == SEP_ATTR_CONST)
                const_attrs.insert(el);
            else
                var_attrs.insert(el);
        } else
        {
            subjects.insert(parseElementTree(child));
        }
    }
    GENERATE_ATTRS(idx)
}
예제 #19
0
static ANTLR3_UINT32	    getLine			(pANTLR3_BASE_TREE tree)
{
	pANTLR3_COMMON_TREE	    cTree;
	pANTLR3_COMMON_TOKEN    token;

	cTree   = (pANTLR3_COMMON_TREE)(tree->super);

	token   = cTree->token;

	if	(token == NULL || token->getLine(token) == 0)
	{
		if  (tree->getChildCount(tree) > 0)
		{
			pANTLR3_BASE_TREE	child;

			child   = (pANTLR3_BASE_TREE)tree->getChild(tree, 0);
			return child->getLine(child);
		}
		return 0;
	}
	return  token->getLine(token);
}
예제 #20
0
static	pANTLR3_BASE_TREE
getChild				(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE t, ANTLR3_UINT32 i)
{
	return t->getChild(t, i);
}
	StringLiteralValueDef::StringLiteralValueDef(const pANTLR3_BASE_TREE node)
		: LiteralValueDef(STRING_LITERAL, node)
	{
		assert(node->getType(node) == N_STRING_LITERAL);
		assert(node->getChildCount(node) == 1);

		pANTLR3_BASE_TREE n, c;

		n = (pANTLR3_BASE_TREE) node->getChild(node, 0);

		assert(n->getType(n) == STRINGL);

		wchar_t* szStr = (wchar_t*) n->getText(n)->chars;

		std::wstringbuf strBuff;

		int state = START_STATE;
		for (wchar_t* pCurr = szStr; *pCurr != L'\0'; pCurr++)
		{
			wchar_t curr = *pCurr;
			switch (state)
			{
				case START_STATE:
					assert(curr == L'"');
					state = NO_ESC_STATE;
					break;
				case NO_ESC_STATE:
					if (curr == L'\\')
					{
						state = ESC_BEGIN_STATE;
					}
					else if (curr == L'"')
					{
						state = END_STATE;
					}
					else
					{
						strBuff.sputc(curr);
					}
					break;
				case ESC_BEGIN_STATE:
					switch (curr)
					{
					case L'b':
						strBuff.sputc(L'\b');
						state = NO_ESC_STATE;
						break;
					case L't':
						strBuff.sputc(L'\t');
						state = NO_ESC_STATE;
						break;
					case L'n':
						strBuff.sputc(L'\n');
						state = NO_ESC_STATE;
						break;
					case L'f':
						strBuff.sputc(L'\f');
						state = NO_ESC_STATE;
						break;
					case L'r':
						strBuff.sputc(L'\r');
						state = NO_ESC_STATE;
						break;
					case L'"':
						strBuff.sputc(L'\"');
						state = NO_ESC_STATE;
						break;
					case L'\'':
						strBuff.sputc(L'\'');
						state = NO_ESC_STATE;
						break;
					case L'\\':
						strBuff.sputc(L'\\');
						state = NO_ESC_STATE;
						break;
					default:
						boost::wformat f(L"Unknown escape sequence \\%1% at line %2%");
						f % curr % node->getLine(node);
						ParserException e(f.str());
						throw e;
					}
					break;
				case END_STATE:
					assert(false);
					break;
				default:
					assert(false);
					break;
			}
		}

		assert(state == END_STATE);
		m_StringValue = strBuff.str();
	}
예제 #22
0
bool SCsTranslator::buildScText(pANTLR3_BASE_TREE tree)
{
    int nodesCount = tree->getChildCount(tree);
    for (int i = 0; i < nodesCount; ++i)
    {
        pANTLR3_BASE_TREE sentenceNode = (pANTLR3_BASE_TREE)tree->getChild(tree, i);
        eSentenceType sentenceType = determineSentenceType(sentenceNode);
        switch (sentenceType)
        {
        case SentenceLevel1:
            processSentenceLevel1(sentenceNode);
            break;
        case SentenceLevel2_7:
            processSentenceLevel2_7(sentenceNode);
            break;
        case SentenceAssign:
            processSentenceAssign(sentenceNode);
            break;
        case SentenceEOF:
            break;
        default:
            THROW_EXCEPT(Exception::ERR_PARSE,
                        "Unknown sentence type.",
                         mParams.fileName,
                         sentenceNode->getLine(sentenceNode));
            break;
        }
    }

    // now generate sc-text in memory
    tElementSet::iterator it, itEnd = mElementSet.end();
    for (it = mElementSet.begin(); it != itEnd; ++it)
    {
        sElement *el = *it;
        assert(el);

        if (el->type == sc_type_arc_pos_const_perm)
        {
            sc_type type = _getTypeBySetIdtf(el->arc_src->idtf);
            if (type != 0)
            {
                el->ignore = true;
                sc_type newType = el->arc_trg->type | type;
                // TODO check conflicts in sc-type
                if ((type & sc_type_constancy_mask) != 0)
                    newType = (type & sc_type_constancy_mask) | (newType & ~sc_type_constancy_mask);
                el->arc_trg->type = newType;
            }
        }

        // arcs already have types
        if (!(el->type & sc_type_arc_mask))
            determineElementType(el);
    }

    tElementSet arcs;
    for (it = mElementSet.begin(); it != itEnd; ++it)
    {
        sElement *el = *it;
        assert(el);

        // skip processed triples
        if (el->ignore) continue;

        sc_addr addr = resolveScAddr(el);

        if (SC_ADDR_IS_EMPTY(addr))
        {
            assert(el->type & sc_type_arc_mask);
            arcs.insert(el);
        }
    }

    bool created = true;
    while (!arcs.empty() && created)
    {
        created = false;

        tElementSet createdSet;
        itEnd = arcs.end();
        for (it = arcs.begin(); it != itEnd; ++it)
        {
            sElement *arc_el = *it;
            assert(arc_el->type & sc_type_arc_mask);
            sc_addr addr = resolveScAddr(arc_el);

            if (SC_ADDR_IS_EMPTY(addr)) continue;

            createdSet.insert(arc_el);
        }

        created = !createdSet.empty();
        itEnd = createdSet.end();
        for (it = createdSet.begin(); it != itEnd; ++it)
            arcs.erase(*it);
    }

    if (!arcs.empty())
    {
        StringStream ss;
        ss << "Arcs not created: " << arcs.size();
        THROW_EXCEPT(Exception::ERR_INVALID_STATE,
                     ss.str(),
                     mParams.fileName,
                     -1);
    }

    return true;
}
예제 #23
0
/** If oldRoot is a nil root, just copy or move the children to newRoot.
 *  If not a nil root, make oldRoot a child of newRoot.
 *
 * \code
 *    old=^(nil a b c), new=r yields ^(r a b c)
 *    old=^(a b c), new=r yields ^(r ^(a b c))
 * \endcode
 *
 *  If newRoot is a nil-rooted single child tree, use the single
 *  child as the new root node.
 *
 * \code
 *    old=^(nil a b c), new=^(nil r) yields ^(r a b c)
 *    old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
 * \endcode
 *
 *  If oldRoot was null, it's ok, just return newRoot (even if isNilNode).
 *
 * \code
 *    old=null, new=r yields r
 *    old=null, new=^(nil r) yields ^(nil r)
 * \endcode
 *
 *  Return newRoot.  Throw an exception if newRoot is not a
 *  simple node or nil root with a single child node--it must be a root
 *  node.  If newRoot is <code>^(nil x)</endcode> return x as newRoot.
 *
 *  Be advised that it's ok for newRoot to point at oldRoot's
 *  children; i.e., you don't have to copy the list.  We are
 *  constructing these nodes so we should have this control for
 *  efficiency.
 */
static	pANTLR3_BASE_TREE	
becomeRoot	(pANTLR3_BASE_TREE_ADAPTOR adaptor, pANTLR3_BASE_TREE newRootTree, pANTLR3_BASE_TREE oldRootTree)
{
    pANTLR3_BASE_TREE saveRoot;

	/* Protect against tree rewrites if we are in some sort of error
	 * state, but have tried to recover. In C we can end up with a null pointer
	 * for a tree that was not produced.
	 */
	if	(newRootTree == NULL)
	{
		return	oldRootTree;
	}

	/* root is just the new tree as is if there is no
	 * current root tree.
	 */
	if	(oldRootTree == NULL)
	{
		return	newRootTree;
	}

	/* Produce ^(nil real-node)
	 */
	if	(newRootTree->isNilNode(newRootTree))
	{
		if	(newRootTree->getChildCount(newRootTree) > 1)
		{
			/* TODO: Handle tree exceptions 
			 */
			ANTLR3_FPRINTF(stderr, "More than one node as root! TODO: Create tree exception handling\n");
			return newRootTree;
		}

		/* The new root is the first child, keep track of the original newRoot
         * because if it was a Nil Node, then we can reuse it now.
		 */
        saveRoot    = newRootTree;
		newRootTree = (pANTLR3_BASE_TREE)newRootTree->getChild(newRootTree, 0);

        // Reclaim the old nilNode()
        //
        saveRoot->reuse(saveRoot);
	}

	/* Add old root into new root. addChild takes care of the case where oldRoot
	 * is a flat list (nill rooted tree). All children of oldroot are added to
	 * new root.
	 */
	newRootTree->addChild(newRootTree, oldRootTree);

    // If the oldroot tree was a nil node, then we know at this point
    // it has become orphaned by the rewrite logic, so we tell it to do
    // whatever it needs to do to be reused.
    //
    if  (oldRootTree->isNilNode(oldRootTree))
    {
        // We have taken an old Root Tree and appended all its children to the new
        // root. In addition though it was a nil node, which means the generated code
        // will not reuse it again, so we will reclaim it here. First we want to zero out
        // any pointers it was carrying around. We are just the baseTree handler so we
        // don't know necessarilly know how to do this for the real node, we just ask the tree itself
        // to do it.
        //
        oldRootTree->reuse(oldRootTree);
    }
	/* Always returns new root structure
	 */
	return	newRootTree;

}
예제 #24
0
/**
* Returns the text of the given node. The result depends on the type of the node. If it represents
* a quoted text entity then two consecutive quote chars are replaced by a single one and if
* escape sequence parsing is not switched off (as per sql mode) then such sequences are handled too.
*/
std::string MySQLRecognitionBase::token_text(pANTLR3_BASE_TREE node, bool keepQuotes)
{
  pANTLR3_STRING text = node->getText(node);
  if (text == NULL)
    return "";

  std::string chars;
  pANTLR3_COMMON_TOKEN token = node->getToken(node);
  ANTLR3_UINT32 type = (token != NULL) ? token->type : ANTLR3_TOKEN_INVALID;

  if (type == STRING_TOKEN)
  {
    // STRING is the grouping subtree for multiple consecutive string literals, which
    // must be concatenated.
    for (ANTLR3_UINT32 index = 0; index < node->getChildCount(node); index++)
    {
      pANTLR3_BASE_TREE child = (pANTLR3_BASE_TREE)node->getChild(node, index);
      chars += token_text(child, keepQuotes);
    }

    return chars;
  }

  chars = (const char*)text->chars;
  std::string quote_char;
  switch (type)
  {
  case BACK_TICK_QUOTED_ID:
    quote_char = "`";
    break;
  case SINGLE_QUOTED_TEXT:
    quote_char = "'";
    break;
  case DOUBLE_QUOTED_TEXT:
    quote_char = "\"";
    break;
  default:
    return chars;
  }

  // First unquote then handle escape squences and double quotes.
  if (chars.size() < 3)
  {
    if (keepQuotes)
      return chars;
    return ""; // Also handles an invalid single quote char gracefully.
  }

  // Need to unquote even if keepQuotes is true to avoid trouble with replacing the outer quotes.
  // Add them back below.
  chars = base::unquote(chars);

  if ((d->_sql_mode & SQL_MODE_NO_BACKSLASH_ESCAPES) == 0)
    chars = base::unescape_sql_string(chars, quote_char[0]);
  else
    if (token->user1 > 0)
    {
      // The field user1 is set by the parser to the number of quote char pairs it found.
      // So we can use it to shortcut our handling here.
      base::replace(chars, quote_char + quote_char, quote_char);
    }

  if (keepQuotes)
    return quote_char + chars + quote_char;
  return chars;
}
예제 #25
0
 pANTLR3_BASE_TREE GetChild(pANTLR3_BASE_TREE node, ANTLR3_UINT32 childIndex)
 {
     return pANTLR3_BASE_TREE(node->getChild(node, childIndex));
 }