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 }
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); }
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(); }
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; }
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; }
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 = ¶mtable; 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; }
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 ; } } }
/* 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 ; }
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; }
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; }
/* * 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); }
/* 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 ; }
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; }