unsigned int parseNumber(char *str) { unsigned int addr = 0; if (!sscanf(str, "0x%x", &addr)) { if (!sscanf(str, "%u", &addr)) { addr = parseBinary(str); } } return addr; }
AstNode* Parser::parseBinary(int minPrecedence) { AstNode* left = parseUnary(); int precedence = tokenPrecedence(currentToken()); while (precedence >= minPrecedence) { while (tokenPrecedence(currentToken()) == precedence) { TokenKind op = currentToken(); uint32_t op_pos = _currentTokenIndex; consumeToken(); AstNode* right = parseBinary(precedence + 1); left = new BinaryOpNode(op_pos, op, left, right); } precedence--; } return left; }
ASTExpression* ParseExpr(MemoryArena* arena, Lexer* lex) { auto parsePrimary = [](MemoryArena* arena, Lexer* lex) -> ASTExpression* { switch (lex->token.type) { case TOKEN_TRUE: { lex->nextToken(); return CreateIntegerLiteral(arena, 1); } case TOKEN_FALSE: { lex->nextToken(); return CreateIntegerLiteral(arena, 0); } case TOKEN_STRING: { auto str = CreateStringLiteral (arena, lex->token.string); lex->nextToken(); return str; } case TOKEN_NUMBER: { LOG_VERBOSE("Parsing a numberExpression!"); auto dotPos = lex->token.string.find("."); bool isFloat = dotPos == std::string::npos ? false : true; if (isFloat) { if (lex->token.string.substr(dotPos + 1).find(".") != std::string::npos) { // ReportError(worker, worker->token.site, "Floating Point value contains two decimal points!"); } auto value = std::stof(lex->token.string); auto result = CreateFloatLiteral(arena, value); lex->nextToken(); return result; } else { auto value = std::stoi(lex->token.string); auto result = CreateIntegerLiteral(arena, value); lex->nextToken(); return result; } } } return nullptr; }; std::function<ASTExpression*(MemoryArena*, Lexer*, ASTExpression*, int)> parseBinary = [&parsePrimary, &parseBinary](MemoryArena* arena, Lexer* lex, ASTExpression* lhs, int expressionPrec) -> ASTExpression* { assert(lhs != nullptr); while (true) { auto tokenPrec = GetTokenPrecedence(lex->token); if (tokenPrec < 0) return lhs; // Bail if there is no binop auto binopToken = lex->token; lex->nextToken(); // We have a binop lets see what is on the other side! ASTExpression* rhs = parsePrimary(arena, lex); if (rhs == nullptr) { //ReportError(worker, binopToken.site, "Could not parse primary expression to the right of binary opperator '" + binopToken.string + "'"); return nullptr; } auto nextPrec = GetTokenPrecedence (lex->token); if (tokenPrec < nextPrec) { rhs = parseBinary(arena, lex, rhs, tokenPrec + 1); if (rhs == nullptr) { LOG_ERROR("Could not parse recursive rhsParsing!"); return nullptr; } } lhs = (ASTExpression*)CreateBinaryOperation(arena, TokenToOperation(binopToken), lhs, rhs); } // Goes back to the while loop }; auto lhs = parsePrimary(arena, lex); if (lhs == nullptr) return nullptr; return parseBinary(arena, lex, lhs, 0); }
// virtual S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const { // map: { string:object, string:object } // array: [ object, object, object ] // undef: ! // boolean: true | false | 1 | 0 | T | F | t | f | TRUE | FALSE // integer: i#### // real: r#### // uuid: u#### // string: "g'day" | 'have a "nice" day' | s(size)"raw data" // uri: l"escaped" // date: d"YYYY-MM-DDTHH:MM:SS.FFZ" // binary: b##"ff3120ab1" | b(size)"raw data" char c; c = istr.peek(); while(isspace(c)) { // pop the whitespace. c = get(istr); c = istr.peek(); continue; } if(!istr.good()) { return 0; } S32 parse_count = 1; switch(c) { case '{': { S32 child_count = parseMap(istr, data); if((child_count == PARSE_FAILURE) || data.isUndefined()) { parse_count = PARSE_FAILURE; } else { parse_count += child_count; } if(istr.fail()) { llinfos << "STREAM FAILURE reading map." << llendl; parse_count = PARSE_FAILURE; } break; } case '[': { S32 child_count = parseArray(istr, data); if((child_count == PARSE_FAILURE) || data.isUndefined()) { parse_count = PARSE_FAILURE; } else { parse_count += child_count; } if(istr.fail()) { llinfos << "STREAM FAILURE reading array." << llendl; parse_count = PARSE_FAILURE; } break; } case '!': c = get(istr); data.clear(); break; case '0': c = get(istr); data = false; break; case 'F': case 'f': ignore(istr); c = istr.peek(); if(isalpha(c)) { int cnt = deserialize_boolean( istr, data, NOTATION_FALSE_SERIAL, false); if(PARSE_FAILURE == cnt) parse_count = cnt; else account(cnt); } else { data = false; } if(istr.fail()) { llinfos << "STREAM FAILURE reading boolean." << llendl; parse_count = PARSE_FAILURE; } break; case '1': c = get(istr); data = true; break; case 'T': case 't': ignore(istr); c = istr.peek(); if(isalpha(c)) { int cnt = deserialize_boolean(istr,data,NOTATION_TRUE_SERIAL,true); if(PARSE_FAILURE == cnt) parse_count = cnt; else account(cnt); } else { data = true; } if(istr.fail()) { llinfos << "STREAM FAILURE reading boolean." << llendl; parse_count = PARSE_FAILURE; } break; case 'i': { c = get(istr); S32 integer = 0; istr >> integer; data = integer; if(istr.fail()) { llinfos << "STREAM FAILURE reading integer." << llendl; parse_count = PARSE_FAILURE; } break; } case 'r': { c = get(istr); F64 real = 0.0; istr >> real; data = real; if(istr.fail()) { llinfos << "STREAM FAILURE reading real." << llendl; parse_count = PARSE_FAILURE; } break; } case 'u': { c = get(istr); LLUUID id; istr >> id; data = id; if(istr.fail()) { llinfos << "STREAM FAILURE reading uuid." << llendl; parse_count = PARSE_FAILURE; } break; } case '\"': case '\'': case 's': if(!parseString(istr, data)) { parse_count = PARSE_FAILURE; } if(istr.fail()) { llinfos << "STREAM FAILURE reading string." << llendl; parse_count = PARSE_FAILURE; } break; case 'l': { c = get(istr); // pop the 'l' c = get(istr); // pop the delimiter std::string str; int cnt = deserialize_string_delim(istr, str, c); if(PARSE_FAILURE == cnt) { parse_count = PARSE_FAILURE; } else { data = LLURI(str); account(cnt); } if(istr.fail()) { llinfos << "STREAM FAILURE reading link." << llendl; parse_count = PARSE_FAILURE; } break; } case 'd': { c = get(istr); // pop the 'd' c = get(istr); // pop the delimiter std::string str; int cnt = deserialize_string_delim(istr, str, c); if(PARSE_FAILURE == cnt) { parse_count = PARSE_FAILURE; } else { data = LLDate(str); account(cnt); } if(istr.fail()) { llinfos << "STREAM FAILURE reading date." << llendl; parse_count = PARSE_FAILURE; } break; } case 'b': if(!parseBinary(istr, data)) { parse_count = PARSE_FAILURE; } if(istr.fail()) { llinfos << "STREAM FAILURE reading data." << llendl; parse_count = PARSE_FAILURE; } break; default: parse_count = PARSE_FAILURE; llinfos << "Unrecognized character while parsing: int(" << (int)c << ")" << llendl; break; } if(PARSE_FAILURE == parse_count) { data.clear(); } return parse_count; }
AstNode* Parser::parseExpression() { return parseBinary(tokenPrecedence(tOR)); }
FB2Content * parseFile(char *filename) { xmlDocPtr doc; xmlNodePtr cur; FB2Content *fb; doc = xmlParseFile(filename); if (doc == NULL ) { fprintf(stderr, "Document not parsed successfully. \n"); return NULL; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { fprintf(stderr, "empty document\n"); xmlFreeDoc(doc); return NULL; } if (xmlStrcmp(cur->name, (const xmlChar *) "FictionBook")) { fprintf(stderr, "document of the wrong type, root node != FictionBook\n"); xmlFreeDoc(doc); return NULL; } fb = (FB2Content *) malloc(sizeof(FB2Content)); /* initialize buffers */ fb->text = (char *) malloc(BUF_SIZE); fb->text_buffer_size = BUF_SIZE; fb->text_current_index = 0; fb->utf8_current_index = 0; fb->description = (char *) malloc(BUF_SIZE); fb->description_buffer_size = BUF_SIZE; fb->description_current_index = 0; *fb->author = '\0'; *fb->name = '\0'; *fb->cover_href = '\0'; fb->genres[0] = NULL; fb->num_genres = 0; fb->marks[0] = NULL; fb->num_marks = 0; fb->binaries[0] = NULL; fb->num_binaries = 0; //fb->links[0] = NULL; //fb->num_links = 0; cur = cur->children; while (cur != NULL) { if (!xmlStrcmp(cur->name, (const xmlChar *)"description")) { fb->current_buffer = DESCRIPTION_BUFFER; parseDescription(doc, cur, fb); } else if (!xmlStrcmp(cur->name, (const xmlChar *)"body")) { fb->current_buffer = TEXT_BUFFER; parseBody(doc, cur, fb); } else if (!xmlStrcmp(cur->name, (const xmlChar *)"binary")) { fb->current_buffer = BINARY_BUFFER; parseBinary(doc, cur, fb); } cur = cur->next; } xmlFreeDoc(doc); fb->current_buffer = DESCRIPTION_BUFFER; bufferAppend("\0", 1, fb); fb->current_buffer = TEXT_BUFFER; bufferAppend("\0", 1, fb); return fb; }