void cConversationManager::ParseNode( TiXmlElement *lpElem, cConversationNode *lpCurrentNode )
{	
	//Check the stop condition
	if ( lpElem == NULL )
	{
		lpCurrentNode->meType = eEndConversation;
		return;
	}
	// Get the type of the XML element
	string lacTag = lpElem->ValueStr();
	if ( lacTag == "Talk" )
	{
		// Set the type
		lpCurrentNode->meType = eNormalTalk;

		// Read the text
		const char * lacText = lpElem->GetText();
		assert(lacText);
		lpCurrentNode->macText = lacText;

		// Read the speaker Id
		lpElem->QueryIntAttribute("speakerId", &(lpCurrentNode->miCharacterId) );
		assert(lpCurrentNode->miCharacterId >= 0);
		assert(lpCurrentNode->miCharacterId < (int)mSpeakers.size() );

		// Read the time
		lpElem->QueryFloatAttribute("time", &(lpCurrentNode->mfDuration) );

		//Prepare the next node
		cConversationNode lNode;
		lpCurrentNode->mChildren.push_back( lNode ); // Asignando un puntero del Nodo a la lista 

		// Continue the recursivity
		ParseNode( lpElem->NextSiblingElement(), &(lpCurrentNode->mChildren[0]) );
	}
	else if ( lacTag == "ChooseTalk" )
	{
		// Set the type
		lpCurrentNode->meType = eChooseTalk;

		// Read all the options
		TiXmlElement *pElem2 = lpElem->FirstChildElement();
		for (pElem2; pElem2; pElem2 = pElem2->NextSiblingElement())
		{
			assert(pElem2);
			assert( pElem2->ValueStr() == "Option" );

			//Add a node to the vector
			cConversationNode lNode;
			lpCurrentNode->mChildren.push_back( lNode ); 

			// Continue the recursivity
			unsigned luiLastIndex = lpCurrentNode->mChildren.size() - 1;  // 
			ParseNode( pElem2->FirstChildElement(), &(lpCurrentNode->mChildren[ luiLastIndex ]) );
		}
	}else
		assert(0 && "Wrong tag\n");

}
NS_MUGGLE_BEGIN

void Polynomial::LoadFromString(const std::string& ref_str)
{
	// clear old data
	data_.MakeEmpty();

	// get the polynomial characters
	char *ptr_ch_begin = (char*)malloc(ref_str.size() + 1);
	memcpy(ptr_ch_begin, ref_str.c_str(), ref_str.size());
	ptr_ch_begin[ref_str.size()] = '\0';

	// parse
	char *p, *q;
	p = q = ptr_ch_begin;
	while (*p != '\0')
	{
		if (*p == ' ' || *p == '+')
		{
			*p++ = '\0';

			if (p - q > 1)
			{
				PolynomialNode node;
				bool parse_ret = ParseNode(q, &node);
				MASSERT_MSG(parse_ret, "Failed in parse string");
				if (parse_ret)
				{
					data_.Insert(node, [](const PolynomialNode& node1, const PolynomialNode& node2)->
						bool{ return node1.exponent > node2.exponent; });
				}
			}

			q = p;
		}
		else
		{
			++p;
		}
	}
	if (p - q > 1)
	{
		PolynomialNode node;
		bool parse_ret = ParseNode(q, &node);
		MASSERT_MSG(parse_ret, "Failed in parse string");
		if (parse_ret)
		{
			data_.Insert(node, Polynomial::DescendingOrder);
		}
	}

	MASSERT_MSG(data_.IsOrdered(Polynomial::DescendingOrder), "polynomial is not ordered");

	free(ptr_ch_begin);
}
void SerializedMessageList::ParseMessages(TiXmlElement *root)
{
#ifdef KNET_USE_TINYXML
	TiXmlElement *node = root->FirstChildElement("message");
	while(node)
	{
		SerializedMessageDesc desc;
		int success = node->QueryIntAttribute("id", (int*)&desc.id);
		if (success == TIXML_NO_ATTRIBUTE)
		{
			KNET_LOG(LogError, "Error parsing message attribute 'id' as int!");
			node = node->NextSiblingElement("message");
			continue; 
		}
		success = node->QueryIntAttribute("priority", (int*)&desc.priority);
		if (success == TIXML_NO_ATTRIBUTE)
			desc.priority = 0; // If priority not specified, use the default priority of zero - the lowest priority possible.
		if (node->Attribute("name"))
			desc.name = node->Attribute("name");
		desc.reliable = ParseBool(node->Attribute("reliable"));
		desc.inOrder = ParseBool(node->Attribute("inOrder"));
		desc.data = ParseNode(node, 0);

		// Work a slight convenience - if there is a single struct inside a single struct inside a single struct - jump straight through to the data.

		messages.push_back(desc);

		node = node->NextSiblingElement("message");
	}
#else
	throw NetException("kNet was built without TinyXml support! SerializedMessageList is not available!");
#endif
}
Example #4
0
ParseNode ActionParser::current() const {
    if (static_cast<size_t>(this->current_pos) == this->tokens.size())
        return TokenType::end;

    std::string arg = this->tokens[this->current_pos];
    return ParseNode(get_type(arg), arg);
}
Example #5
0
eavlMADNESSImporter::eavlMADNESSImporter(const string &fn)
{
    log = new eavlLogicalStructureQuadTree();
    log->root.xmin = -1;
    log->root.xmax = +1;
    log->root.ymin = -1;
    log->root.ymax = +1;

    ifstream in(fn.c_str());
    if (!in)
        THROW(eavlException,"Error opening given filename in MADNESS importer.");

    char buff[4096];
    in.getline(buff,4096);

    bool success = ParseNode(in, log->root);
    log->BuildLeafCellList();
    if (!success)
        THROW(eavlException,"Error parsing MADNESS file");

    //log->root.Print(cout);
    //cerr << "MADNESS TREE: "
    //     << log->root.GetNumCells(true)<<" leaf cells, "
    //     << log->root.GetNumCells(false)<<" total cell count\n";

    in.close();
}
Example #6
0
CJsonNode CExecAndParseStructuredOutput::ParseObject(bool root_object)
{
    CJsonNode result(CJsonNode::NewObjectNode());

    CJsonNode new_node;

    do {
        while (isspace(*m_Ch))
            ++m_Ch;

        if (*m_Ch != '\'' && *m_Ch != '"')
            break;

        // New attribute/value pair
        string attr_name(ParseString());

        while (isspace(*m_Ch))
            ++m_Ch;
        if (*m_Ch == ':' || *m_Ch == '=')
            while (isspace(*++m_Ch))
                ;

        if (new_node = ParseNode())
            result.SetNode(attr_name, new_node);
        else
            ThrowUnexpectedCharError();
    } while (MoreNodes());

    if (root_object ? *m_Ch != '\0' : *m_Ch != '}')
        ThrowUnexpectedCharError();

    ++m_Ch;

    return result;
}
ParseNode gen_paramtable(ParseNode & paramtable_elem) {
	ParseNode newnode = ParseNode();
	if (paramtable_elem.fs.CurrentTerm.token == TokenMeta::NT_DIMENSLICE 
		|| paramtable_elem.fs.CurrentTerm.token == TokenMeta::NT_ARGTABLE_PURE) {
		// promote dimen_slice to paramtable
		return gen_argtable(paramtable_elem);
	}
	else if(paramtable_elem.fs.CurrentTerm.token == TokenMeta::NT_KEYVALUE){
		newnode.addchild(new ParseNode(paramtable_elem)); // keyvalue
		sprintf(codegen_buf, "%s", paramtable_elem.fs.CurrentTerm.what.c_str());
		newnode.fs.CurrentTerm = Term{ TokenMeta::NT_PARAMTABLE, string(codegen_buf) };
		return newnode;
	}
	else if (paramtable_elem.fs.CurrentTerm.token == TokenMeta::NT_PARAMTABLE
		|| paramtable_elem.fs.CurrentTerm.token == TokenMeta::NT_PARAMTABLE_DIMENSLICE) {
		// get a paramtable from dimen_slice
		newnode = paramtable_elem;
		return newnode;
	}
	else {
		newnode = paramtable_elem;
		print_error("Illegal gen_paramtable arg", newnode);
		return newnode;
	}
}
ParseNode gen_empty_suite() {
	
	ParseNode * newnode = new ParseNode();
	ParseNode & stmt = ParseNode(gen_flex(Term{ TokenMeta::NT_SUITE, "\n" }), newnode);
	newnode->fs.CurrentTerm = Term{ TokenMeta::NT_SUITE, "\n" };
	newnode->addchild(new ParseNode(stmt)); // stmt
	newnode = flattern_bin(newnode);
	return *newnode;
}
ParseNode gen_vardef_simple(const ParseNode & type, std::string name) {
	ParseNode newnode = ParseNode(gen_flex(Term{ TokenMeta::NT_VARIABLEDEFINE, name }), nullptr);
	newnode.addchild(new ParseNode(type)); // type
	newnode.addchild(new ParseNode(gen_flex(Term{ TokenMeta::NT_VOID, "" }), nullptr)); // variable_desc
	ParseNode kv = gen_keyvalue(gen_token(Term{ TokenMeta::UnknownVariant, name }));
	ParseNode pt = gen_paramtable(kv);
	newnode.addchild(new ParseNode(pt)); // type
	return newnode;
}
Example #10
0
void RarcFile::ParseNode(RarcNode * Node, string & parentDirectory)
{
	u32 StringOffset = Header.stringTableOffset+0x20;
	u32 DataOffset = Header.dataStartOffset+0x20;
	u32 CurrOffset = Header.fileEntriesOffset+0x20+Node->firstFileEntryOffset*sizeof(RarcFileEntry);

	//I love recursion... :P
	string parent_dir = parentDirectory;
	string ItemName;
	GetFilename(StringOffset+Node->filenameOffset, ItemName);

	if(parent_dir.size() == 0)
	{
		parent_dir = ItemName;
	}
	else
	{
		//It's just awesome...
		parent_dir.assign(fmt("%s/%s", parentDirectory.c_str(), ItemName.c_str()));
	}

	ItemName.clear();

	AddListEntrie(parent_dir.c_str(), 0, 0, true, ItemIndex++, 0, ArcArch);
	BufferOffset.push_back(0);

	for(u16 i = 0; i < Node->numFileEntries; i++)
	{
		RarcFileEntry FileEntry;
		ReadFile(&FileEntry, sizeof(RarcFileEntry), CurrOffset);

		GetFilename(StringOffset+FileEntry.filenameOffset, ItemName);

		u32 filelength = FileEntry.dataSize;

		/* It's a dir... */
		if(FileEntry.id == 0xFFFF)
		{
			if(strcmp(ItemName.c_str(), ".") != 0 && strcmp(ItemName.c_str(), "..") != 0)
			{
				RarcNode DirNode;
				ReadFile(&DirNode, sizeof(RarcNode), sizeof(RarcHeader)+sizeof(RarcNode)*FileEntry.dataOffset);
				ParseNode(&DirNode, parent_dir);
			}
		}
		/* It's a file... */
		else
		{
			AddListEntrie(fmt("%s/%s", parent_dir.c_str(), ItemName.c_str()), filelength, filelength, false, ItemIndex++, 0, ArcArch);
			BufferOffset.push_back(DataOffset+FileEntry.dataOffset);
		}

		ItemName.clear();
		CurrOffset += sizeof(RarcFileEntry);
	}
}
ParseNode gen_argtable(ParseNode & dimen_slice) {
	ParseNode newnode = ParseNode();
	bool isdimen = false;
	int sliceid = 0; /* if the array has 2 dimensions, sliceid is 0..1 */
	dimen_slice.fs.CurrentTerm.what = "";
	for (sliceid = 0; sliceid < dimen_slice.child.size(); sliceid++)
	{
		if (sliceid != 0) {
			dimen_slice.fs.CurrentTerm.what += ", ";
		}
		if (dimen_slice.fs.CurrentTerm.token == TokenMeta::NT_DIMENSLICE) {
			// dimen_slice
			// slice or slice/exp
			isdimen = true;
			newnode.addchild(new ParseNode(*dimen_slice.child[sliceid]));
			if (dimen_slice.child[sliceid]->fs.CurrentTerm.token == TokenMeta::NT_SLICE) {
				// slice
				if (dimen_slice.child[sliceid]->child.size() == 2) {
					/* from, to */
					sprintf(codegen_buf, "%s, %s", dimen_slice.child[sliceid]->child[0]->fs.CurrentTerm.what.c_str()
						, dimen_slice.child[sliceid]->child[1]->fs.CurrentTerm.what.c_str());
				}
				else {
					// size
					sprintf(codegen_buf, "%s", dimen_slice.child[sliceid]->child[0]->fs.CurrentTerm.what.c_str());
				}
			}
			else {
				// exp
				sprintf(codegen_buf, "%s", dimen_slice.child[sliceid]->fs.CurrentTerm.what.c_str());
			}
		}
		else if(dimen_slice.fs.CurrentTerm.token == TokenMeta::NT_ARGTABLE_PURE){
			// NT_ARGTABLE_PURE
			// exp
			isdimen = false;
			newnode.addchild(new ParseNode(*dimen_slice.child[sliceid]));
			sprintf(codegen_buf, "%s", dimen_slice.child[sliceid]->fs.CurrentTerm.what.c_str());
		}
		else {
			print_error("Illegal argtable", dimen_slice);
		}
		dimen_slice.fs.CurrentTerm.what += codegen_buf;
	}
	if (isdimen) {
		// %%s.slice(%s)
		// should not set codegen_buf here
		sprintf(codegen_buf, "/* deprecated */ slice(%%s, %s)", dimen_slice.fs.CurrentTerm.what.c_str());
		newnode.fs.CurrentTerm = Term{ TokenMeta::NT_PARAMTABLE_DIMENSLICE, string(codegen_buf) };
	}
	else {
		sprintf(codegen_buf, "%s", dimen_slice.fs.CurrentTerm.what.c_str());
		newnode.fs.CurrentTerm = Term{ TokenMeta::NT_ARGTABLE_PURE, string(codegen_buf) };
	}
	return newnode;
}
ParseNode gen_case(const ParseNode & dimen_slice, ParseNode & suite) {
	// one case
	ParseNode newnode = ParseNode();
	suite.fs.CurrentTerm.what = tabber(suite.fs.CurrentTerm.what);
	newnode.fs.CurrentTerm = Term{ TokenMeta::NT_CASE, "" };
	ParseNode select;
	newnode.addchild(new ParseNode(select)); // case
	newnode.addchild(new ParseNode(dimen_slice)); // dimen_slice
	newnode.addchild(new ParseNode(suite)); // suite
	return newnode;
}
Example #13
0
bool SpaceObject::ParseNode(const TiXmlNode * node)
{
	unsigned long num = GetLong(node->FirstChild("Owner"));
	if (num < 0 || num > mGame->NumberPlayers()) {
		Message * mess = mGame->AddMessage("Error: Invalid player number");
		mess->AddLong("", num);
		mess->AddItem("Owener of", this);
		return false;
	}

	return ParseNode(node, mGame->NCGetPlayer(num));
}
ParseNode gen_keyvalue(const ParseNode & variable) {
	/* paramtable is used in function decl */
	/* this paramtable has only one value */

	sprintf(codegen_buf, "%s", variable.fs.CurrentTerm.what.c_str());
	ParseNode newnode = ParseNode(gen_flex(Term{ TokenMeta::NT_VARIABLEINITIAL, string(codegen_buf) }), nullptr);
	newnode.addchild(new ParseNode(variable)); // type
	newnode.addchild(new ParseNode(gen_flex(Term{ TokenMeta::NT_VARIABLEINITIALDUMMY, string("void") }), &newnode, nullptr)); // void is dummy initial

	// instead of return a NT_PARAMTABLE, now return NT_KEYVALUE node
	return newnode;
}
ParseNode gen_keyvalue_from_arraybuilder(const ParseNode & variable, const ParseNode & initial) {
	/* paramtable is used in function decl */
	/* this paramtable has only one value */
	/* 因为使用forarray作为数组, 故需要知道类型信息, 不在此处赋值, 在上层的var_def赋初值 */

	sprintf(codegen_buf, "%s.init(%s)", variable.fs.CurrentTerm.what.c_str(), initial.fs.CurrentTerm.what.c_str());
	ParseNode newnode = ParseNode(gen_flex(Term{ TokenMeta::NT_VARIABLEINITIAL, string(codegen_buf) }), nullptr);
	newnode.addchild(new ParseNode(variable)); // type
	newnode.addchild(new ParseNode(initial)); // void is dummy initial

	// instead of return a NT_PARAMTABLE, now return NT_KEYVALUE node
	return newnode;
}
void SerializedMessageList::ParseStructs(TiXmlElement *root)
{
#ifdef KNET_USE_TINYXML
	TiXmlElement *node = root->FirstChildElement("struct");
	while(node)
	{
		ParseNode(node, 0);

		node = node->NextSiblingElement("struct");
	}
#else
	throw NetException("kNet was built without TinyXml support! SerializedMessageList is not available!");
#endif
}
void cConversationManager::ParseConversation(TiXmlElement *pElem)
{
	cConversation lConversation;

	// Read the conversation ID
	const char * lacNameId = pElem->Attribute("nameId");
	assert(lacNameId);
	lConversation.macName = lacNameId;// guardando el nombre de la conversación

	// Read the tree
	ParseNode( pElem->FirstChildElement(), &lConversation.mRoot );// guardando la ruta de la conversación

	// Add the conversations to the list
	mConversations.push_back(lConversation);// guardando en la lista la conversación
}
ParseNode gen_promote_paramtable(const ParseNode paramtable) {
	const ParseNode * pn = &paramtable;
	ParseNode newnode = ParseNode(gen_flex(Term{ TokenMeta::NT_PARAMTABLE, "" }), nullptr);
	do {
		// for all non-flatterned paramtable
		for (int i = 0; i < pn->child.size(); i++)
		{
			newnode.addchild(new ParseNode(gen_promote_exp_to_keyvalue(*pn->child[i])));
		}
		if (pn->child.size() >= 2)
		{
			/* if pn->child.size() == 0, this is an empty paramtable(this function takes no arguments) */
			/* if the paramtable is not flatterned pn->child[1] is a right-recursive paramtable node */
			pn = pn->child[1];
		}
	} while (pn->child.size() == 2 && pn->child[1]->fs.CurrentTerm.token == TokenMeta::NT_PARAMTABLE);
	return newnode;
}
ParseNode gen_array_generate_stmt(const ParseNode & _generate_stmt) {
	/* give generate stmt */
	ParseNode newnode = ParseNode();
	ParseNode * exp = _generate_stmt.child[0];
	ParseNode * index = _generate_stmt.child[1];
	ParseNode * from = _generate_stmt.child[2];
	ParseNode * to = _generate_stmt.child[3];
	//print_error("LBound don't agree", _generate_stmt);
	sprintf(codegen_buf, "for(int %s = %s; %s < %s; %s++){\n%s(%s) = %s;\n}", index->fs.CurrentTerm.what.c_str(), from->fs.CurrentTerm.what.c_str() /* exp_from */
		, index->fs.CurrentTerm.what.c_str(), to->fs.CurrentTerm.what.c_str() /* exp_to */, index->fs.CurrentTerm.what.c_str() /* index variable inc */
		, "\t%s" /* array variable name */, index->fs.CurrentTerm.what.c_str() /* index variable */, exp->fs.CurrentTerm.what.c_str());
	newnode.fs.CurrentTerm = Term{ TokenMeta::NT_ARRAYBUILDER_EXP, string(codegen_buf) };
	newnode.addchild(new ParseNode(*exp)); // exp
	newnode.addchild(new ParseNode(*index)); // index variable
	newnode.addchild(new ParseNode(*from)); // exp_from
	newnode.addchild(new ParseNode(*to)); // exp_to
	return newnode;

}
Example #20
0
HRESULT
ParseXml
(
   IXmlReader * pReader,
   Node ** ppNode
)
{
   HRESULT hr;
   XmlNodeType nodeType;

   // ParseNode() ignores the XML declaration node, so there can be only one
   // top level node.
   if (SUCCEEDED(hr = pReader->Read(&nodeType)))
   {
      return ParseNode(pReader, ppNode);
   }

   return hr;
}
//<Library>
void LibraryParser::ParseLibrary(TiXmlNode* pParent) {
	cerr << "Parsing the Library "<< endl ;
	GetLibraryAttributes(pParent ) ;
	TiXmlNode* Child;
	string Elem;
	for (Child = pParent->FirstChild() ; Child != 0; Child
			= Child->NextSibling() ) {
		Elem = Child->ValueStr() ;
		if (Elem == "Node") {
			ParseNode(Child ) ;
		} else if (Elem == "Link") {
			ParseLink(Child ) ;
		} else if (Elem == "BiLink") {
			ParseBiLink(Child ) ;
		} else {
			cout << "Unknown XML element "<< Elem<< " in file "<< mFname<< endl ;
		}
	}
}
Example #22
0
/* read an xml file */
struct xmlNode *xmlReadFile(FILE *in)
{
    int size ;
    char *data,*p ;
    struct xmlNode *root ;

    if (!in)
        return 0 ;

    /* find len */
    fseek(in,0,SEEK_END) ;
    size = ftell(in);

    /* read the data into the buffer */
    data = calloc(size+1,1) ;
    fseek(in,0,SEEK_SET) ;
    fread(data,1,size,in) ;

    /* ignore doc tags */
    RemoveDocTags(data,"<?","?>");
    RemoveDocTags(data,"<!--","-->");

    /* make a root node */
    root = calloc(sizeof(struct xmlNode),1) ;
    if (!root) {
        free(data) ;
        return 0 ;
    }

    /* parse the data */
    p = data ;
    if (!ParseNode(root,&p)) {
        free(data) ;
        xmlFree(root) ;
        return 0 ;
    }

    /* free the data and return the root */
    free(data) ;
    return root ;

}
Example #23
0
CJsonNode CExecAndParseStructuredOutput::ParseArray()
{
    CJsonNode result(CJsonNode::NewArrayNode());

    CJsonNode new_node;

    do {
        while (isspace(*m_Ch))
            ++m_Ch;

        if (new_node = ParseNode())
            result.PushNode(new_node);
        else
            break;
    } while (MoreNodes());

    if (*m_Ch != ']')
        ThrowUnexpectedCharError();

    ++m_Ch;

    return result;
}
Example #24
0
bool RarcFile::ParseRarcHeader()
{
	ReadFile(&Header, sizeof(RarcHeader), 0);

	if(Header.magic != 'RARC')
	{
		CloseFile();
		return false;
	}

	FileSize = Header.size;

	RarcNode RootNode;

	ReadFile(&RootNode, sizeof(RarcNode), sizeof(RarcHeader));

	ItemIndex = 0;

	string ItemPath;
	ParseNode(&RootNode, ItemPath);

	return true;
}
SerializedElementDesc *SerializedMessageList::ParseNode(TiXmlElement *node, SerializedElementDesc *parentNode)
{
#ifdef KNET_USE_TINYXML
	elements.push_back(SerializedElementDesc());
	SerializedElementDesc *elem = &elements.back();
	elem->parent = parentNode;
	elem->name = node->Attribute("name") ? node->Attribute("name") : "";

	if (!strcmp(node->Value(), "message"))
	{
		elem->count = 1;
		elem->varyingCount = false;
		elem->type = SerialStruct;
	}
	else
	{
		// Cannot have both static count and dynamic count!
		if (node->Attribute("count") && node->Attribute("varyingCount"))
			KNET_LOG(LogError, "Warning: An XML node contains both 'count' and 'varyingCount' attributes! 'varyingCount' takes precedence.");

		if (node->Attribute("dynamicCount"))
		{
			node->QueryIntAttribute("dynamicCount", &elem->count);
			elem->varyingCount = true;
		}
		else if (node->Attribute("count"))
		{
			node->QueryIntAttribute("count", &elem->count);
			elem->varyingCount = false;
		}
		else
		{
			elem->count = 1;
			elem->varyingCount = false;
		}

		elem->typeString = node->Value();
		if (elem->typeString == "string")
			elem->typeString = "std::string";
		elem->type = StringToSerialType(node->Value());
		if (elem->type == SerialInvalid && !elem->typeString.empty())
			elem->type = SerialOther;
		if (elem->type == SerialStruct)
			elem->typeString = "S_" + elem->name; ///\todo Add a ClassName parameter for better control over naming here?
	}

	// If this node is a structure, parse all its members.
	if (elem->type == SerialStruct)
	{
		TiXmlElement *child = node->FirstChildElement();
		while(child)
		{
			SerializedElementDesc *childElem = ParseNode(child, elem);
			elem->elements.push_back(childElem);

			child = child->NextSiblingElement();
		}
	}

	return elem;
#else
	throw NetException("kNet was built without TinyXml support! SerializedMessageList is not available!");
#endif
}
ParseNode gen_select(const ParseNode & exp, const ParseNode & case_stmt) {

	ParseNode newnode = ParseNode();
	string codegen = "";
	for (int i = 0; i < case_stmt.child.size(); i++)
	{
		ParseNode & case_stmt_elem = *case_stmt.child[i];
		ParseNode & dimen_slice = *case_stmt_elem.child[1];
		/*
		0 -- case
		1 -- dimen_slice
		2 -- stmt(case body)
		*/
		if (dimen_slice.fs.CurrentTerm.token == TokenMeta::NT_DIMENSLICE) {
			// NT_DIMENSLICE
			string dsstr;
			for (int sliceid = 0; sliceid < dimen_slice.child.size(); sliceid++)
			{
				if (sliceid == 0) {
					sprintf(codegen_buf, "(%s >= %s && %s < %s)", exp.fs.CurrentTerm.what.c_str(), dimen_slice.child[sliceid]->child[0]->fs.CurrentTerm.what.c_str(), exp.fs.CurrentTerm.what.c_str(), dimen_slice.child[sliceid]->child[1]->fs.CurrentTerm.what.c_str());
				}
				else {
					sprintf(codegen_buf, " || (%s >= %s && %s < %s)", exp.fs.CurrentTerm.what.c_str(), dimen_slice.child[sliceid]->child[0]->fs.CurrentTerm.what.c_str(), exp.fs.CurrentTerm.what.c_str(), dimen_slice.child[sliceid]->child[1]->fs.CurrentTerm.what.c_str());
				}
				dsstr += string(codegen_buf);
			}
			if (i == 0) {
				sprintf(codegen_buf, "if(%s){\n%s}\n", dsstr.c_str(), case_stmt_elem.child[2]->fs.CurrentTerm.what.c_str());
			}
			else {
				sprintf(codegen_buf, "else if(%s){\n%s}\n", dsstr.c_str(), case_stmt_elem.child[2]->fs.CurrentTerm.what.c_str());
			}
		}
		else {
			// NT_ARGTABLE_PURE
			string choice = "";
			if (i == 0) {
				choice = "if(";
				sprintf(codegen_buf, "if(%s == %s){\n%s}\n", exp.fs.CurrentTerm.what.c_str(), dimen_slice.child[0]->fs.CurrentTerm.what.c_str(), case_stmt_elem.child[2]->fs.CurrentTerm.what.c_str());
			}
			else {
				choice = "else if(";
				sprintf(codegen_buf, "else if(%s == %s){\n%s}\n", exp.fs.CurrentTerm.what.c_str(), dimen_slice.child[0]->fs.CurrentTerm.what.c_str(), case_stmt_elem.child[2]->fs.CurrentTerm.what.c_str());
			}
			for (int j = 0; j < dimen_slice.child.size(); j++)
			{
				if (j == 0) {
					sprintf(codegen_buf, "%s == %s", exp.fs.CurrentTerm.what.c_str(), dimen_slice.child[j]->fs.CurrentTerm.what.c_str());
				}
				else {
					sprintf(codegen_buf, "|| (%s == %s)", exp.fs.CurrentTerm.what.c_str(), dimen_slice.child[j]->fs.CurrentTerm.what.c_str());
				}
				choice += codegen_buf;
			}
			sprintf(codegen_buf, "){\n%s}\n", case_stmt_elem.child[2]->fs.CurrentTerm.what.c_str());
			choice += codegen_buf;
			sprintf(codegen_buf, "%s", choice.c_str());
		}
		codegen += codegen_buf;
	}
	newnode.fs.CurrentTerm = Term{ TokenMeta::NT_SELECT, codegen };
	ParseNode select = ParseNode();
	newnode.addchild(new ParseNode(select)); // select
	newnode.addchild(new ParseNode(exp)); // exp
	newnode.addchild(new ParseNode(case_stmt)); // suite
	return newnode;
}
Example #27
0
/*
 * File ::= { Declaration }
 * Declaration ::= Node
 *               | Operation
 *               | OperationCase
 *               | Option
 *               | Enum
 *               | Literal
 *               | Header
 *               | Output
 *               | Common
 *               | Include
 * Literal ::= { LiteralFlag } ( LITERAL_DEFNS | LITERAL_END )
 * LiteralFlag ::= %both | %decls | %end
 * Header ::= %header STRING
 * Output ::= %output STRING
 * Common ::= %common
 * Include ::= %include [ %readonly ] STRING
 */
void TreeCCParse(TreeCCContext *context)
{
	/* Fetch the first token from the input stream */
	if(!TreeCCNextToken(context->input))
	{
		return;
	}

	/* Parse lines of input until the input is exhausted */
	do
	{
		switch(context->input->token)
		{
			case TREECC_TOKEN_EOF:
			{
				/* Shouldn't happen, but ignore it if it does */
			}
			break;

			case TREECC_TOKEN_IDENTIFIER:
			{
				/* Parse an operation case definition */
				ParseOperationCase(context);
			}
			continue;	/* Skip the call to TreeCCNextToken */

			case TREECC_TOKEN_LITERAL_DEFNS:
			case TREECC_TOKEN_LITERAL_END:
			case TREECC_TOKEN_BOTH:
			case TREECC_TOKEN_DECLS:
			case TREECC_TOKEN_END:
			{
				/* Parse a literal definition block for this file */
				int flags = 0;
				while(context->input->token == TREECC_TOKEN_BOTH ||
				      context->input->token == TREECC_TOKEN_DECLS ||
				      context->input->token == TREECC_TOKEN_END)
				{
					if(context->input->token == TREECC_TOKEN_BOTH)
					{
						flags |= TREECC_LITERAL_CODE |
								 TREECC_LITERAL_DECLS;
					}
					else if(context->input->token == TREECC_TOKEN_DECLS)
					{
						flags |= TREECC_LITERAL_DECLS;
					}
					else
					{
						flags |= TREECC_LITERAL_END;
					}
					TreeCCNextToken(context->input);
				}
				if((flags & TREECC_LITERAL_DECLS) == 0)
				{
					flags |= TREECC_LITERAL_CODE;
				}
				if(context->input->token == TREECC_TOKEN_LITERAL_DEFNS)
				{
					TreeCCAddLiteralDefn(context, TreeCCValue(context->input),
										 flags);
				}
				else if(context->input->token == TREECC_TOKEN_LITERAL_END)
				{
					TreeCCAddLiteralDefn(context, TreeCCValue(context->input),
										 flags | TREECC_LITERAL_END);
				}
				else
				{
					TreeCCError(context->input,
								"literal definition block expected");
					continue;
				}
			}
			break;

			case TREECC_TOKEN_NODE:
			{
				/* Parse a node definition */
				ParseNode(context);
			}
			continue;	/* Skip the call to TreeCCNextToken */

			case TREECC_TOKEN_OPERATION:
			{
				/* Parse an operation definition */
				ParseOperation(context);
			}
			continue;	/* Skip the call to TreeCCNextToken */

			case TREECC_TOKEN_OPTION:
			{
				/* Parse an option declaration */
				ParseOption(context);
			}
			continue;	/* Skip the call to TreeCCNextToken */

			case TREECC_TOKEN_HEADER:
			{
				/* Parse a header filename specification */
				TreeCCNextToken(context->input);
				if(context->input->token == TREECC_TOKEN_STRING)
				{
					TreeCCStream *stream =
						TreeCCStreamCreate(context, context->input->text,
										   context->input->text, 1);
					context->headerStream = stream;
					stream->readOnly |= context->input->readOnly;
					if(!(context->commonHeader))
					{
						context->commonHeader = stream;
					}
				}
				else
				{
					TreeCCError(context->input, "header filename expected");
					continue;
				}
			}
			break;

			case TREECC_TOKEN_OUTPUT:
			{
				/* Parse an output filename specification */
				TreeCCNextToken(context->input);
				if(context->input->token == TREECC_TOKEN_STRING)
				{
					TreeCCStream *stream =
						TreeCCStreamCreate(context, context->input->text,
										   context->input->text, 0);
					context->sourceStream = stream;
					stream->readOnly |= context->input->readOnly;
					if(!(context->commonSource))
					{
						context->commonSource = stream;
					}
				}
				else
				{
					TreeCCError(context->input, "output filename expected");
					continue;
				}
			}
			break;

			case TREECC_TOKEN_OUTDIR:
			{
				/* Parse an output directory specification */
				TreeCCNextToken(context->input);
				if(context->input->token == TREECC_TOKEN_STRING)
				{
					context->outputDirectory =
						TreeCCResolvePathname(context->input->filename,
											  context->input->text);
				}
				else
				{
					TreeCCError(context->input, "output filename expected");
					continue;
				}
			}
			break;

			case TREECC_TOKEN_ENUM:
			{
				/* Parse an enumerated type definition */
				ParseEnum(context);
			}
			continue;	/* Skip the call to TreeCCNextToken */

			case TREECC_TOKEN_COMMON:
			{
				/* Put the common housekeeping code in the
				   current header and source streams */
				context->commonHeader = context->headerStream;
				context->commonSource = context->sourceStream;
			}
			break;

			case TREECC_TOKEN_INCLUDE:
			{
				/* Include another file at this point */
				int readOnly = context->input->readOnly;
				TreeCCNextToken(context->input);
				if(context->input->token == TREECC_TOKEN_READONLY)
				{
					readOnly = 1;
					TreeCCNextToken(context->input);
				}
				if(context->input->token == TREECC_TOKEN_STRING)
				{
					char *includeFile =
						TreeCCResolvePathname(context->input->filename,
											  context->input->text);
					FILE *file = fopen(includeFile, "r");
					if(file != NULL)
					{
						/* Parse the contents of the included file */
						TreeCCInput *newInput =
							(TreeCCInput *)malloc(sizeof(TreeCCInput));
						TreeCCInput *origInput = context->input;
						if(!newInput)
						{
							TreeCCOutOfMemory(context->input);
						}
						TreeCCOpen(newInput, context->input->progname,
								   file, includeFile);
						context->input = newInput;
						TreeCCParse(context);
						context->input = origInput;
						TreeCCClose(newInput, 1);
						free(newInput);
					}
					else
					{
						TreeCCError(context->input, "cannot open \"%s\"",
									includeFile);
						free(includeFile);
					}
				}
				else
				{
					TreeCCError(context->input, "include filename expected");
				}
			}
			break;

			case TREECC_TOKEN_LITERAL_CODE:
			case TREECC_TOKEN_LPAREN:
			case TREECC_TOKEN_RPAREN:
			case TREECC_TOKEN_LBRACE:
			case TREECC_TOKEN_RBRACE:
			case TREECC_TOKEN_LSQUARE:
			case TREECC_TOKEN_RSQUARE:
			case TREECC_TOKEN_COMMA:
			case TREECC_TOKEN_EQUALS:
			case TREECC_TOKEN_STAR:
			case TREECC_TOKEN_REF:
			case TREECC_TOKEN_SEMI:
			case TREECC_TOKEN_COLON_COLON:
			case TREECC_TOKEN_STRING:
			case TREECC_TOKEN_UNKNOWN:
			case TREECC_TOKEN_ABSTRACT:
			case TREECC_TOKEN_TYPEDEF:
			case TREECC_TOKEN_NOCREATE:
			case TREECC_TOKEN_VIRTUAL:
			case TREECC_TOKEN_INLINE:
			case TREECC_TOKEN_SPLIT:
			case TREECC_TOKEN_READONLY:
			{
				/* This token is not valid here */
				TreeCCError(context->input, "declaration expected");
				do
				{
					/* Attempt to re-synchronise on the next declaration */
					TreeCCNextToken(context->input);
				}
				while(!IsStartDecl(context->input->token));
			}
			continue;	/* Skip the call to TreeCCNextToken */
		}

		/* Get the next token from the input stream */
		TreeCCNextToken(context->input);
	}
	while(context->input->token != TREECC_TOKEN_EOF);
}
Example #28
0
/* parse a tag and all its sub tags */
static int ParseNode(struct xmlNode* Node, char **s)
{
  char szText[MAX_XML_TEXT_LEN];
  char attr[MAX_XML_NAME_LEN];
  int j ;

  /* look for opening < */
  if (!skipspace(s))
    return FALSE ;

  if (**s != '<')
    return FALSE ;
  (*s)++ ;
  
  if (!skipspace(s))
    return FALSE ;

  /* get the tag name and store it */
  GetName(attr,s);
  Node->elementType = strdup(attr) ;
  if (!Node->elementType)
    return FALSE ;

  /* is it immediately followed by /? 
   * if so we are going to define it as a null tag, I don't know
   * if this is XML kosher or not
   */
  if (!skipspace(s))
    return FALSE ;

  if (**s == '/') {
    (*s)++ ;
    if (!skipspace(s))
        return FALSE ;

    /* we always have Node->textData point to something */
    Node->textData = strdup("") ;
    if (!Node->textData)
        return FALSE ;
    return *(*s)++ == '>' ;
  }

  /* are there any attributes? */
  if(**s!='>')
  {
    /* while there are attributes */
    while(**s)
    {
      char attr[MAX_XML_NAME_LEN];
      j = 0 ;

      /* get the attribute name */
      GetName(attr, s) ;
      if (!**s)
        return FALSE ;

      if (!skipspace(s))
         return FALSE ;

      /* need an equal sign */
      if (**s != '=')
        return FALSE ;
      (*s)++ ;

      if (!skipspace(s))
         return FALSE ;

      /* need an opening quote */
      if (**s != '"')
        return FALSE ;
      (*s)++ ;

      /* now read the attribute value */
      while(**s && **s!='"'&&j<MAX_XML_TEXT_LEN) {
        szText[j] = convertchar(s);
        if (szText[j++] == 0)
            return FALSE ;
      }
      szText[j] = '\0';
      if (**s)
        (*s)++;

      /* insert it into the node */
      if (!InsertAttr(Node,attr,szText))
        return FALSE ;

      if (!skipspace(s))
         return FALSE ;

      /* auto close out the tag? */
      if(**s=='/')
      {
        
        (*s)++ ;
        if (!skipspace(s))
           return FALSE ;
    
        /* we always have Node->textData point to something */

        Node->textData = strdup("") ;
        if (!Node->textData)
            return 0 ;

        /* make sure we really have the end of the tag */
        return (*(*s)++ == '>') ;
      }

      /* other wise if it is the end of a normal opening tag
       * break out of the attribute loop and go get text
       */
      if(**s=='>')  {
        (*s)++ ;
        break;
      }
    }
  } else
    (*s)++ ;

  j = 0 ;
  /* now start processing child nodes */
  while(**s)
  {
    struct xmlNode *child ;
    struct xmlNode **link  = &Node->children;
  
    /* get any text available now
     */
    while(**s && **s!='<'&&j<MAX_XML_TEXT_LEN) {
      szText[j] = convertchar(s) ;
      if (szText[j++] == 0)
        return FALSE ;
    }
    szText[j] = '\0';

    /* MUST have an opening < at this point */
    if (**s != '<')
        return FALSE ;
    (*s)++ ;

    /* is this the beginning of a closing tag? */
    if(**s=='/') 
    {
      /* if so get its name */
      (*s)++ ;
      GetName(attr,s) ;

      if (!skipspace(s))
        return FALSE ;

      /* make sure we end with > */
      if (*(*s)++ != '>')
        return FALSE ;

      /* save text, textdata always points to something even if it is null text */
      Node->textData = stripdup(szText) ;
      if (!Node->textData)
        return FALSE ;

      /* and only return TRUE if it matched the opening tag for this node */
      return !strcmp(Node->elementType,attr) ;
    }

    /* otherwise back up to < as we are going to call this routine
     * recursively to get the node data */
    while (*(--*s) != '<') ;

    /* make a new child */
    child = calloc(sizeof(struct xmlNode),1) ;
    if (!child)
        return FALSE ;

    /* find the end of the node's children and insert the new child */
    while (*link)
        link = &((*link)->next) ;
    *link = child ;

    /* now parse the child */
    if (!ParseNode(child,s))
        return FALSE ;

  }
  return FALSE ;
}
Example #29
0
HRESULT
ParseNode
(
   IXmlReader * pReader,
   Node ** ppNode
)
{
   HRESULT hr;

   XmlNodeType nodeType;
   Char * nodeName = nullptr;

   Attribute * attrList = nullptr;

   Node * childList = nullptr;
   Node * childLast = nullptr;

   const WCHAR * tmpString;

#define APPEND_CHILD(childNode) \
   if (childLast == nullptr) \
   { \
       childList = childLast = childNode; \
   } \
   else \
   { \
       childLast->Next = childNode; \
       childLast = childNode; \
   }

   // This call won't fail we make sure the reader is positioned at a valid
   // node before ParseNode() is called.
   pReader->GetNodeType(&nodeType);

   do
   {
      switch (nodeType)
      {
      case XmlNodeType_Element:
      {
         bool inOpenElement = nodeName != nullptr;
         if (inOpenElement)
         {
            Node * childNode;
            hr = ParseNode(pReader, &childNode);
            if (hr == S_OK)
            {
               APPEND_CHILD(childNode);
            }
            else
            {
               return hr;
            }
         }
         else
         {
            pReader->GetLocalName(&tmpString, nullptr);
            nodeName = ConvertWCHAR(tmpString);

            hr = ParseAttributes(pReader, &attrList);
            if (FAILED(hr))
            {
               *ppNode = nullptr;
               return hr;
            }

            *ppNode = new Node(nodeName, attrList);

            if (pReader->IsEmptyElement())
            {
               return S_OK;
            }
         }

         break;
      }

      case XmlNodeType_EndElement:
      {
         Node * node = *ppNode;

         // If we have a single child with data called "#text", then pull the data up to this node.
         if (childList != nullptr
             && childList == childLast
             && (childList->Data != nullptr)
             && (_stricmp(childList->Name, "#text") == 0))
         {
            node->Data = childList->Data;
            node->ChildList = nullptr;
         }
         else
         {
            node->ChildList = childList;
         }

         return S_OK;
      }

      case XmlNodeType_Attribute:
         // Need to manually move to attributes when at an element node.
         break;

      case XmlNodeType_CDATA:
      case XmlNodeType_Text:
      {
         pReader->GetValue(&tmpString, nullptr);
         Node * node = new Node("#text", nullptr);
         node->Data = ConvertWCHAR(tmpString);
         APPEND_CHILD(node);

         break;
      }

      case XmlNodeType_Comment:
      case XmlNodeType_DocumentType:
      case XmlNodeType_None:
      case XmlNodeType_ProcessingInstruction:
      case XmlNodeType_Whitespace:
      case XmlNodeType_XmlDeclaration:
         // Ignored.
         break;
      }
   }
   while (S_OK == (hr = pReader->Read(&nodeType)));

   return hr;

#undef APPEND_CHILD
}
ParseNode gen_vardef(const ParseNode & type_spec, const ParseNode & variable_desc, const ParseNode & paramtable) {
	ParseNode newnode = ParseNode();
	string arr_decl = ""; string var_decl = ""; bool do_arr = false;
	VariableDescAttr * vardescattr = dynamic_cast<VariableDescAttr *>(variable_desc.attr);
	ParseNode * slice = vardescattr->desc.slice;
	ParseNode * spec_typename = promote_type(type_spec, vardescattr); // reset type according to kind
	if (slice == nullptr) {
		// slice == nullptr if this is not array
		/* must assure no ParseNode * is nullptr */
		slice = new ParseNode(gen_flex(Term{ TokenMeta::NT_VOID, "" }), nullptr);
	}
	else {
		do_arr = true;
	}
	newnode.addchild(spec_typename); // type
	newnode.addchild(slice); // variable_desc
	ParseNode * pn = new ParseNode(gen_promote_paramtable(paramtable));
	newnode.addchild(pn); // paramtable
	newnode.attr = new VariableDescAttr(*dynamic_cast<VariableDescAttr *>(variable_desc.attr)); // attr
	if (do_arr)
	{
		// ARRAY
		arr_decl = gen_vardef_array(pn, spec_typename, slice, vardescattr);
		newnode.fs.CurrentTerm = Term{ TokenMeta::NT_VARIABLEDEFINE, arr_decl };
	}
	else {
		// SCALAR
		sprintf(codegen_buf, gen_vardef_typestr(vardescattr).c_str(), spec_typename->fs.CurrentTerm.what.c_str());
		string typestr = string(codegen_buf);
		var_decl += typestr;
		bool hitted = false; // 是否至少有一个变量,因为有的变量定义可能是函数的声明,这在c++规范是不允许的,所以可能出现空int,空逗号的情况。
							 /* enumerate paramtable */
		// pn is flattened
		for (int i = 0; i < pn->child.size(); i++)
		{
			ParseNode * this_variable = new ParseNode(*pn->child[i]);
			// skip if it is a function
			// TODO no module currently
			if (get_function("", this_variable->fs.CurrentTerm.what)) {
				continue;
			}
			if (hitted) {
				var_decl += ", ";
			}
			hitted = true;

			sprintf(codegen_buf, "%s", this_variable->child[0]->fs.CurrentTerm.what.c_str());

			var_decl += codegen_buf;
			/* initial value */
			if (this_variable->child[1]->fs.CurrentTerm.token != TokenMeta::NT_VARIABLEINITIALDUMMY) {
				/* if initial value is not dummy but `exp` */
				var_decl += " = ";
				var_decl += this_variable->child[1]->fs.CurrentTerm.what;
			}
			/* desc */
			this_variable->attr = vardescattr->clone();
		}
		var_decl += ";";
		if (!hitted) {
			// all function declarations
			var_decl = "";
		}

		newnode.fs.CurrentTerm = Term{ TokenMeta::NT_VARIABLEDEFINE, var_decl };
	} // end if
	// set all elements' attr in paramtable 
	for (int i = 0; i < pn->child.size(); i++)
	{
		pn->child[i]->attr = newnode.attr->clone();
	}
	return newnode;
}