/* <mangled_name> ::= _Z <name> [<type> (if template params > 0)] <type>+ */ static int parseMangledName(LargeStaticString &src, LargeStaticString &dest, demangle_t &data) { START("MangledName"); // Does the string begin with _Z? if (src[0] != '_' || src[1] != 'Z') END_FAIL("MangledName"); src.stripFirst(2); if (parseName(src, dest, data) == FAIL) END_FAIL("MangledName"); // HACK:: Bit of a hack here - we add the entire function name (foo::bar) to the substitution index, // when it shouldn't be. Here we decrement the number of substitutions so it is wiped. if (data.nSubstitutions) data.nSubstitutions --; // HACK:: OK here we go, hack again. We manually increase the data.nNameParseLevel member so // that our template parameters don't get accidentally overwritten. data.nNameParseLevel = 5; // If we have some template params we should expect a type next (for return type). LargeStaticString tmp; // Just completely ignore the return type. if (data.nTemplateParams > 0) if (parseType(src, tmp, data) == FAIL) END_FAIL("MangledName"); data.nParams = 0; do { if (parseType(src, data.params[data.nParams], data) == FAIL) END_FAIL("MangledName"); data.nParams++; } while (src.length() > 0); END_SUCCESS("MangledName"); }
TestFunctionType parseFunctionType() { const auto returnType = parseType(); assert(stream_.peek() == '('); stream_.consume(); llvm::SmallVector<Type, 8> argumentTypes; while (stream_.peek() != ')' && stream_.peek() != '.') { argumentTypes.push_back(parseType()); assert(stream_.peek() == ',' || stream_.peek() == ')'); if (stream_.peek() == ',') { stream_.consume(); } } llvm::SmallVector<Type, 8> varArgsTypes; const bool isVarArg = (stream_.peek() == '.'); if (isVarArg) { varArgsTypes = parseVarArgsTypes(); } assert(stream_.peek() == ')'); stream_.consume(); return TestFunctionType(FunctionType(returnType, argumentTypes, isVarArg), varArgsTypes); }
/* <function_type> ::= F [Y] <type> <type>+ E */ static int parseFunctionType(LargeStaticString &src, LargeStaticString &dest, demangle_t &data) { START("FunctionType"); // Should start with an 'F'. if (src[0] != 'F') END_FAIL("FunctionType"); src.stripFirst(1); // Do we have a 'Y'? if (src[0] == 'Y') src.stripFirst(1); // Ignore it. // Return type. if (parseType(src, dest, data) == FAIL) END_FAIL("FunctionType"); dest += " ()("; bool bIsFirst = true; do { if (bIsFirst) bIsFirst = false; else dest += ", "; if (parseType(src, dest, data) == FAIL) END_FAIL("FunctionType"); } while (src[0] != 'E'); dest += ")"; src.stripFirst(1); END_SUCCESS("FunctionType"); }
// like parseFunction, but never aborts with an error bool Moc::parseMaybeFunction(FunctionDef *def) { def->type = parseType(); if (def->type.name.isEmpty()) return false; bool scopedFunctionName = false; if (test(LPAREN)) { def->name = def->type.name; scopedFunctionName = def->type.isScoped; def->type = Type("int"); } else { Type tempType = parseType();; while (!tempType.name.isEmpty() && lookup() != LPAREN) { if (def->type.name == "QT_MOC_COMPAT" || def->type.name == "QT3_SUPPORT") def->isCompat = true; else if (def->type.name == "Q_INVOKABLE") def->isInvokable = true; else if (def->type.name == "Q_SCRIPTABLE") def->isInvokable = def->isScriptable = true; else if (def->type.name == "Q_SIGNAL") def->isSignal = true; else if (def->type.name == "Q_SLOT") def->isSlot = true; else { if (!def->tag.isEmpty()) def->tag += ' '; def->tag += def->type.name; } def->type = tempType; tempType = parseType(); } if (!test(LPAREN)) return false; def->name = tempType.name; scopedFunctionName = tempType.isScoped; } // we don't support references as return types, it's too dangerous if (def->type.referenceType == Type::Reference) def->type = Type("void"); def->normalizedType = normalizeType(def->type.name); if (!test(RPAREN)) { parseFunctionArguments(def); if (!test(RPAREN)) return false; } def->isConst = test(CONST); if (scopedFunctionName && (def->isSignal || def->isSlot || def->isInvokable)) { QByteArray msg("parsemaybe: Function declaration "); msg += def->name; msg += " contains extra qualification. Ignoring as signal or slot."; warning(msg.constData()); return false; } return true; }
static PSmmAstNode parseFuncParams(PSmmParser parser, PSmmAstParamNode firstParam) { assert(firstParam != NULL); assert(parser->curToken->kind == ':'); getNextToken(parser); //skip ':' PSmmTypeInfo typeInfo = parseType(parser); if (typeInfo->kind == tiSmmUnknown && !findEitherToken(parser, ',', ')')) return &errorNode; int paramCount = 1; firstParam->kind = nkSmmParamDefinition; firstParam->type = typeInfo; firstParam->isIdent = true; firstParam->level = parser->curScope->level + 1; ibsDictPush(parser->idents, firstParam->token->repr, firstParam); PSmmAstParamNode param = firstParam; while (parser->curToken->kind == ',') { getNextToken(parser); PSmmToken paramName = expect(parser, tkSmmIdent); if (!paramName) { findEitherToken(parser, ',', ')'); continue; } if (!expect(parser, ':')) { findEitherToken(parser, ',', ')'); continue; } PSmmTypeInfo paramTypeInfo = parseType(parser); if (paramTypeInfo->kind == tiSmmUnknown) { findEitherToken(parser, ',', ')'); } PSmmAstParamNode newParam = ibsDictGet(parser->idents, paramName->repr); if (newParam) { if (newParam->level == parser->curScope->level + 1) { smmPostMessage(parser->msgs, errSmmRedefinition, paramName->filePos, paramName->repr); continue; } else if (!newParam->isIdent) { const char* tokenStr = nodeKindToString[newParam->kind]; smmPostMessage(parser->msgs, errSmmIdentTaken, paramName->filePos, paramName->repr, tokenStr); continue; } } paramCount++; newParam = smmNewAstNode(nkSmmParam, parser->a); newParam->isIdent = true; newParam->level = parser->curScope->level + 1; newParam->token = paramName; newParam->type = paramTypeInfo; ibsDictPush(parser->idents, paramName->repr, newParam); param->next = newParam; param = newParam; } firstParam->count = paramCount; return (PSmmAstNode)firstParam; }
static void parseInherit (tokenInfo *const token) { Assert (isKeyword (token, KEYWORD_inherit)); #ifdef TYPE_REFERENCE_TOOL readToken (token); while (isType (token, TOKEN_IDENTIFIER)) { parseType (token); if (isType (token, TOKEN_KEYWORD)) { switch (token->keyword) /* check for feature adaptation */ { case KEYWORD_rename: case KEYWORD_export: case KEYWORD_undefine: case KEYWORD_redefine: case KEYWORD_select: findKeyword (token, KEYWORD_end); readToken (token); default: break; } } } #else readToken (token); while (isType (token, TOKEN_IDENTIFIER)) { parseType (token); switch (token->keyword) /* check for feature adaptation */ { case KEYWORD_rename: parseRename (token); if (isKeyword (token, KEYWORD_end)) readToken (token); break; case KEYWORD_export: case KEYWORD_undefine: case KEYWORD_redefine: case KEYWORD_select: findKeyword (token, KEYWORD_end); readToken (token); break; case KEYWORD_end: readToken (token); break; default: break; } } #endif }
void esvg::Dimension::set(std::string _configX, std::string _configY) { m_data.setValue(0,0); m_type = esvg::distance_pixel; enum distance type = esvg::distance_pixel; // First Parse X enum distance typeX = parseType(_configX); float valueX = etk::string_to_float(_configX); // Second Parse Y enum distance typeY = parseType(_configY); float valueY = etk::string_to_float(_configY); // TODO : Check difference ... set(vec2(valueX, valueY), typeX); ESVG_VERBOSE(" config dimention : '" << _configX << "' '" << _configY << "' == > " << *this ); }
static void parseGeneric (tokenInfo *const token, boolean declaration __unused__) { unsigned int depth = 0; #ifdef TYPE_REFERENCE_TOOL boolean constraint = FALSE; #endif Assert (isType (token, TOKEN_OPEN_BRACKET)); do { if (isType (token, TOKEN_OPEN_BRACKET)) { ++depth; readToken (token); } else if (isType (token, TOKEN_CLOSE_BRACKET)) { --depth; readToken (token); } #ifdef TYPE_REFERENCE_TOOL else if (declaration) { boolean advanced = FALSE; if (depth == 1) { if (isType (token, TOKEN_CONSTRAINT)) constraint = TRUE; else if (isKeyword (token, KEYWORD_create)) findKeyword (token, KEYWORD_end); else if (isType (token, TOKEN_IDENTIFIER)) { if (constraint) advanced = parseType (token); else addGenericName (token); constraint = FALSE; } } else if (isType (token, TOKEN_IDENTIFIER)) advanced = parseType (token); if (! advanced) readToken (token); } #endif else parseType (token); } while (depth > 0 && ! isType (token, TOKEN_EOF)); }
PARSENODE_PTR SQLParser::parseCreate() { if (!startsCreate(nowReading)) { syntaxError(nowReading, "expect create!"); return nullptr; } //LOG_TRACE(logger, "parse create statement."); PARSENODE_PTR createNode = PARSENODE_PTR(new ParseNode(CREATE)); readToken(); if (nowReading == TABLE) { createNode->children.emplace_back(new ParseNode(TABLE)); readToken(); createNode->children.push_back(parseIdentifier()); expect(LEFT_BRACE); while (startsIdentifier(nowReading)) { PARSENODE_PTR id = parseIdentifier(); //LOG_TRACE(logger, "parse id %s.", ((IdentifierNode*)id.get())->id_.c_str()); PARSENODE_PTR type = parseType(); if (nowReading == UNIQUE) { readToken(); id->children.emplace_back(new ParseNode(UNIQUE)); } expect(SLICE); id->children.push_back(type); createNode->children.push_back(id); } expect(PRIMARY); expect(KEY); expect(LEFT_BRACE); createNode->children.push_back(parseIdentifier()); expect(RIGHT_BRACE); expect(RIGHT_BRACE); } else if (nowReading == INDEX) { createNode->children.emplace_back(new ParseNode(INDEX)); readToken(); PARSENODE_PTR indexNode = parseIdentifier(); createNode->children.push_back(indexNode); expect(ON); PARSENODE_PTR tableNode = parseIdentifier(); createNode->children.push_back(tableNode); expect(LEFT_BRACE); PARSENODE_PTR columnNode = parseIdentifier(); createNode->children.push_back(columnNode); expect(RIGHT_BRACE); } else { syntaxError(nowReading, "expect table or index!"); return nullptr; } expect(TERMINATOR); return createNode; }
/* parses a PLY element description */ void parseElementDescr(std::stringstream& cin, std::list<std::string>& header) { Element elt; std::string name; cin >> name; size_t num; cin >> num; mesh.order.push_back(name); elt.name = name; elt.size = num; /* parse all properties */ while (!header.empty()) { std::stringstream line(header.front()); std::string tag; line >> tag; if (tag != "property") break; header.pop_front(); Type ty = parseType(line); std::string name; line >> name; elt.type[name] = ty; elt.properties.push_back(name); } mesh.elements[name] = elt; }
void VertexShader::parseAttributes() { const char *hlsl = getHLSL(); if (hlsl) { const char *input = strstr(hlsl, "// Attributes") + 14; while(true) { char attributeType[256]; char attributeName[256]; int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName); if (matches != 2) { break; } mAttributes.push_back(Attribute(parseType(attributeType), attributeName)); input = strstr(input, ";") + 2; } } }
void Moc::parseFunctionArguments(FunctionDef *def) { Q_UNUSED(def); while (hasNext()) { ArgumentDef arg; arg.type = parseType(); if (arg.type.name == "void") break; if (test(IDENTIFIER)) arg.name = lexem(); while (test(LBRACK)) { arg.rightType += lexemUntil(RBRACK); } if (test(CONST) || test(VOLATILE)) { arg.rightType += ' '; arg.rightType += lexem(); } arg.normalizedType = normalizeType(arg.type.name + ' ' + arg.rightType); arg.typeNameForCast = normalizeType(noRef(arg.type.name) + "(*)" + arg.rightType); if (test(EQ)) arg.isDefault = true; def->arguments += arg; if (!until(COMMA)) break; } }
void parseGenericParameters(Generic<T> *generic, const TypeContext &typeContext) { while (stream_.consumeTokenIf(E_SPIRAL_SHELL)) { auto &variable = stream_.consumeToken(TokenType::Variable); auto constraint = parseType(typeContext, TypeDynamism::GenericTypeVariables); generic->addGenericArgument(variable.value(), constraint, variable.position()); } }
static void parseInherit (tokenInfo *const token) { Assert (isKeyword (token, KEYWORD_inherit)); readToken (token); while (isType (token, TOKEN_IDENTIFIER)) { parseType (token); if (isType (token, TOKEN_KEYWORD)) { switch (token->keyword) /* check for feature adaptation */ { case KEYWORD_rename: parseRename (token); case KEYWORD_export: case KEYWORD_undefine: case KEYWORD_redefine: case KEYWORD_select: if (findKeyword (token, KEYWORD_end)) readToken (token); break; case KEYWORD_end: readToken (token); break; default: break; } } if (isType (token, TOKEN_SEMICOLON)) readToken (token); } }
llvm::SmallVector<Type, 8> parseVarArgsTypes() { assert(stream_.peek() == '.'); stream_.consume(); assert(stream_.peek() == '.'); stream_.consume(); assert(stream_.peek() == '.'); stream_.consume(); assert(stream_.peek() == '('); stream_.consume(); llvm::SmallVector<Type, 8> varArgsTypes; while (stream_.peek() != ')') { varArgsTypes.push_back(parseType()); assert(stream_.peek() == ',' || stream_.peek() == ')'); if (stream_.peek() == ',') { stream_.consume(); } } assert(stream_.peek() == ')'); stream_.consume(); return varArgsTypes; }
DeclarationsPtr Parser::parseArgumentList() { IdentifiersPtr identifiers = parseIdentifierList(); if (m_errorCode > ErrorCodes::NoError) { return DeclarationsPtr(); } if (!match(TokenType::Colon)) { reportError(ErrorCodes::ExpectedColon); return DeclarationsPtr(); } TypePtr type = parseType(); if (m_errorCode > ErrorCodes::NoError) { return DeclarationsPtr(); } DeclarationsPtr declarations(new Declarations); for (std::vector<IdentifierPtr>::const_iterator i = identifiers->list.begin(); i != identifiers->list.end(); ++i) { DeclarationPtr declaration(new Declaration); declaration->id = *i; declaration->type = type; declarations->list.push_back(declaration); } DeclarationsPtr rest = parseArgumentList_r(); if (rest) { declarations->list.insert(declarations->list.end(), rest->list.begin(), rest->list.end()); } return declarations; }
/** * Parses the "new" keyword */ int CodeParser::parseKeyword_New( Scope* scope, TokenStack* stack ) { int errorCode = 0; // parses the object definition: new string("hello"); // get the object type TypeReference* type = parseType( scope, stack ); // parse the method parameters list<Parameter*> params; if( ( errorCode = parseMethodParameters( scope, stack, params ) ) ) { return errorCode; } // setup code to create the object on the stack // PARAMS params // NEWINST type CodeBuffer* cb = scope->getCodeBuffer(); OFFSET_T offset1 = cb->putInstruction( PARAMS << A_OP ); OFFSET_T offset2 = cb->putInstruction( NEWINST << A_OP ); // add the parameter and reference data scope->addParameterData( new ParameterData( state->nextParamId(), params, offset1 ) ); scope->addReferenceData( new ReferenceData( state->nextDataRefId(), type->getName(), offset2 ) ); return errorCode; }
/* <template_arg> ::= <type> ::= X <expression> E ::= <expr-primary> */ static int parseTemplateArg(LargeStaticString &src, LargeStaticString &dest, demangle_t &data) { START("TemplateArg"); LargeStaticString origsrc = src; LargeStaticString origdest = dest; if (parseType(src, dest, data) == SUCCESS) END_SUCCESS("TemplateArg"); src = origsrc; dest = origdest; if (src[0] == 'X') { src.stripFirst(1); if (parseExpression(src, dest, data) == FAIL) END_FAIL("TemplateArg"); if (src[0] != 'E') END_FAIL("TemplateArg"); src.stripFirst(1); END_SUCCESS("TemplateArg"); } src = origsrc; dest = origdest; if (parseExprPrimary(src, dest, data) == SUCCESS) END_SUCCESS("TemplateArg"); END_FAIL("TemplateArg"); }
void Parser::parseDeclarations(){ if(isNext(tc_VAR)){ match(tc_VAR); EntryList ids = *(new EntryList()); parseIdentifierList(ids); match(tc_COLON); if(m_parserError){ TokenCode synch[] = {tc_ARRAY, tc_INTEGER, tc_REAL, tc_NONE}; recover(synch); // if(isNext(tc_COLON)){ // match(tc_COLON); // } } parseType(); m_code->generateVariables(ids); match(tc_SEMICOL); if(m_parserError){ TokenCode synch[] = {tc_VAR, tc_FUNCTION, tc_BEGIN, tc_PROCEDURE, tc_NONE}; recover(synch); // if(isNext(tc_SEMICOL)){ // match(tc_SEMICOL); // } } parseDeclarations(); } }
StatusWithMatchExpression JSONSchemaParser::_parse(StringData path, BSONObj schema) { // Map from JSON Schema keyword to the corresponding element from 'schema', or to an empty // BSONElement if the JSON Schema keyword is not specified. StringMap<BSONElement> keywordMap{ {kSchemaTypeKeyword, {}}, {kSchemaPropertiesKeyword, {}}, {kSchemaMaximumKeyword, {}}}; for (auto&& elt : schema) { auto it = keywordMap.find(elt.fieldNameStringData()); if (it == keywordMap.end()) { return Status(ErrorCodes::FailedToParse, str::stream() << "Unknown $jsonSchema keyword: " << elt.fieldNameStringData()); } if (it->second) { return Status(ErrorCodes::FailedToParse, str::stream() << "Duplicate $jsonSchema keyword: " << elt.fieldNameStringData()); } keywordMap[elt.fieldNameStringData()] = elt; } auto typeExpr = parseType(path, keywordMap[kSchemaTypeKeyword]); if (!typeExpr.isOK()) { return typeExpr.getStatus(); } auto andExpr = stdx::make_unique<AndMatchExpression>(); if (auto propertiesElt = keywordMap[kSchemaPropertiesKeyword]) { auto propertiesExpr = _parseProperties(path, propertiesElt, typeExpr.getValue().get()); if (!propertiesExpr.isOK()) { return propertiesExpr; } andExpr->add(propertiesExpr.getValue().release()); } if (auto maximumElt = keywordMap[kSchemaMaximumKeyword]) { auto maxExpr = parseMaximum(path, maximumElt, typeExpr.getValue().get()); if (!maxExpr.isOK()) { return maxExpr; } andExpr->add(maxExpr.getValue().release()); } if (path.empty() && typeExpr.getValue() && typeExpr.getValue()->getBSONType() != BSONType::Object) { // This is a top-level schema which requires that the type is something other than // "object". Since we only know how to store objects, this schema matches nothing. return {stdx::make_unique<FalseMatchExpression>(StringData{})}; } if (!path.empty() && typeExpr.getValue()) { andExpr->add(typeExpr.getValue().release()); } return {std::move(andExpr)}; }
static void parseEntityType (tokenInfo *const token) { Assert (isType (token, TOKEN_COLON)); readToken (token); if (isType (token, TOKEN_BANG) || isType (token, TOKEN_QUESTION)) readToken (token); /* skip over '!' or '?' */ parseType (token); }
/** * Parses the class member (field or method) contained within the given token stack */ int CodeParser::parseClassMember( Scope* scope, TokenStack* stack ) { int errorCode = 0; TypeReference* type; const char* name; // the following types are parsed: // method layout: "[static] [final] type|[]| methodName(...) { ... }" // field layout: "[static] [final] type|[]| fieldName| = ....|" int step = 0; bool done = false; while( !done && stack->hasNext() ) { switch( ++step ) { // step 1: get the type of the class member (e.g. "string" or "string[]") case 1: // extract the name of the identifier if( !( type = parseType( scope, stack ) ) ) { return -1; } break; // step 2: get the class member name case 2: // get the type name if( !( name = state->getIdentifierName( stack, "class member" ) ) ) { return -2; } break; // step 3: get the class member instance (field or method) // method layout: "[static] [final] type methodName(...) { ... }" // field layout: "[static] [final] type fieldName[ = ....]" case 3: // each child should be a method (e.g. "type methodName(...)") or field (e.g. "type fieldName") // if there is a parenthesis block, it's likely to be a method errorCode = ( stack->peek()->getType() == tok::PARENTHESIS_BLOCK ) ? parseMethod( scope, name, type, stack ) : parseField( scope, name, type, stack ); // was there an error? if( errorCode ) { return errorCode; } done = true; break; } } // did it complete? if( !done ) { SYNTAX_ERROR( "unexpected end of statement", stack->last() ); return -4; } // return the error code return 0; }
void parseType() { if (t >= l) { err = true; return; } t++; if (A[t-1] == 'p') { strcpy(ab+p, "pair<"); p += 5; parseType(); strcpy(ab+p, ","); p += 1; parseType(); strcpy(ab+p, ">"); p += 1; } else { strcpy(ab+p, "int"); p += 3; } }
/* <pointer_to_member_type> ::= M <class type> <member type> */ static int parsePointerToMemberType(LargeStaticString &src, LargeStaticString &dest, demangle_t &data) { START("PointerToMemberType"); // We should start with an 'M'. if (src[0] != 'M') END_FAIL("PointerToMemberType"); src.stripFirst(1); LargeStaticString classType; if (parseType(src, classType, data) == FAIL) END_FAIL("PointerToMemberType"); // If the next thing is a function, we cheat a little to get a decent looking member // member function. /// \note This piece of code will FAIL if the member function pointer returns a function /// pointer! if (src[0] == 'F') { LargeStaticString function; if (parseFunctionType(src, function, data) == FAIL) END_FAIL("PointerToMemberType"); // find the bit before the parameter list "()". size_t nLength=0; while (function[nLength] != '(' || function[nLength+1] != ')') nLength++; // NOTE unsafe! dest += function.left(nLength+1); dest += classType; dest += "::*"; dest += function.right(function.length()-nLength-1); } else { if (parseType(src, dest, data) == FAIL) END_FAIL("PointerToMemberType"); dest += " "; dest += classType; dest += "::*"; } END_SUCCESS("PointerToMemberType"); }
static void parseBlock (tokenInfo *const token, const boolean local) { int depth = 1; while (depth > 0) { readToken (token); switch (token->keyword) { default: if (isType (token, TOKEN_IDENTIFIER)) { if (local) makeSqlTag (token, SQLTAG_LOCAL_VARIABLE); else makeSqlTag (token, SQLTAG_VARIABLE); } break; case KEYWORD_cursor: parseSimple (token, SQLTAG_CURSOR); break; case KEYWORD_function: parseSubProgram (token); break; case KEYWORD_procedure: parseSubProgram (token); break; case KEYWORD_subtype: parseSimple (token, SQLTAG_SUBTYPE); break; case KEYWORD_trigger: parseSimple (token, SQLTAG_TRIGGER); break; case KEYWORD_type: parseType (token); break; case KEYWORD_end: --depth; break; case KEYWORD_begin: { while (depth > 0) { switch (token->keyword) { case KEYWORD_if: case KEYWORD_loop: ++depth; readToken (token); break; case KEYWORD_end: --depth; findToken (token, TOKEN_SEMICOLON); break; default: readToken (token); break; } } break; } } findToken (token, TOKEN_SEMICOLON); } }
TyPtr parseTypeList (Lexer& lex, Span& sp) { Span spStart, spEnd; spStart = lex.eat(tLBrack).span; auto inner = parseType(lex, spEnd); spEnd = lex.eat(tRBrack).span; sp = spStart + spEnd; return Ty::makeConcrete("List", { inner }); }
Param* Parser::parseParam() { if ( check( IDENT_T ) ) { Token ID = match( IDENT_T ); match( COLON_T ); DataType type = parseType(); ValParam* node = new ValParam( ID.lexeme, type, ID.line, ID.column ); return node; } else { Token var = match( VAR_ID ); Token ID = match( IDENT_T ); match( COLON_T ); DataType type = parseType(); VarParam* node = new VarParam( ID.lexeme, type, var.line, var.column ); return node; } }
VarDecl* Parser::parseVarDecl() { Token var = match( VAR_ID ); Token ID = match( IDENT_T ); match( COLON_T ); DataType type = parseType(); match( SEMICOLON_T ); VarDecl* node = new VarDecl( ID.lexeme, type, var.line, var.column ); return node; }
ExternAST* Parser::handleExternFunc() { lexer->NextToken(); // eat extern directive bool isDeclspec = false; if (lexer->token == Lexer::TOK_IDENTIFIER && lexer->tokIdentifier == "__dll") { isDeclspec = true; lexer->NextToken(); } if (lexer->token != Lexer::TOK_STRING) { this->Error("Expected external function symbol"); return 0; } std::string symbol = lexer->tokValue_str; lexer->NextToken(); if (lexer->token != ',') { this->Error("Expected ,"); return 0; } lexer->NextToken(); // eat , std::string type = parseType(); if (type == "") return 0; if (lexer->token != Lexer::TOK_IDENTIFIER) { this->Error("Expected new function name"); return 0; } std::string name = lexer->tokIdentifier; lexer->NextToken(); if (lexer->token != '(') { Error("Expected '('"); return 0; } lexer->NextToken(); // eat ( std::vector<VariableDefAST*> argTypes; while (lexer->token != ')') { std::string t = parseType(); if (t == "") return 0; argTypes.push_back(new VariableDefAST("",t)); if (lexer->token != ',' && lexer->token != ')') { Error("Expected ','"); return 0; } if (lexer->token == ',') lexer->NextToken(); } lexer->NextToken(); // eat ) functionDefinitions[name] = new PrototypeAST(name, argTypes, type, true); return new ExternAST(symbol,name,isDeclspec); }
VariableDefAST* Parser::handleVarDef() { std::string type = parseType(); if (type == "") return 0; if (lexer->token != Lexer::TOK_IDENTIFIER) return ErrorD("Expected variable name, got '" + lexer->TokToStr(lexer->token) + "'"); std::string id = lexer->tokIdentifier; lexer->NextToken(); if (lexer->token == '=') lexer->PreviousToken(); // now pointing at the variable identifier if (currentFunc != 0) currentFunc->associatedVars[id] = type; return new VariableDefAST(type, id); }