📄 parser.cpp
字号:
return m_problems == 0;}bool Parser::parseDeclaration(DeclarationAST *&node){ int start = tokenStream->cursor(); switch(tokenStream->lookAhead()) { case ';': advance(); return true; case Token_extern: return parseLinkageSpecification(node); case Token_namespace: return parseNamespace(node); case Token_using: return parseUsing(node); case Token_typedef: return parseTypedef(node); case Token_asm: return parseAsmDefinition(node); case Token_template: case Token_export: return parseTemplateDeclaration(node); default: { // tokenStream->rewind(start); if (objcp && parseObjcDef(node)) return true; tokenStream->rewind(start); AST *storageSpec = 0; parseStorageClassSpecifier(storageSpec); AST *cv = 0; parseCvQualify(cv); TypeSpecifierAST *spec = 0; if (parseEnumSpecifier(spec) || parseClassSpecifier(spec)) { spec->setCvQualify(cv); AST *cv2 = 0; parseCvQualify(cv2); spec->setCv2Qualify(cv2); InitDeclaratorListAST *declarators = 0; parseInitDeclaratorList(declarators); ADVANCE(';', ";"); SimpleDeclarationAST *ast = CreateNode<SimpleDeclarationAST>(m_pool); ast->setStorageSpecifier(storageSpec); ast->setTypeSpec(spec); ast->setInitDeclaratorList(declarators); UPDATE_POS(ast, start, tokenStream->cursor()); node = ast; return true; } tokenStream->rewind(start); return parseDeclarationInternal(node); } } // end switch}bool Parser::parseLinkageSpecification(DeclarationAST *&node){ int start = tokenStream->cursor(); if (tokenStream->lookAhead() != Token_extern) { return false; } advance(); LinkageSpecificationAST *ast = CreateNode<LinkageSpecificationAST>(m_pool); int startExternType = tokenStream->cursor(); if (tokenStream->lookAhead() == Token_string_literal) { advance(); AST *externType = CreateNode<AST>(m_pool); UPDATE_POS(externType, startExternType, tokenStream->cursor()); ast->setExternType(externType); } if (tokenStream->lookAhead() == '{') { LinkageBodyAST *linkageBody = 0; parseLinkageBody(linkageBody); ast->setLinkageBody(linkageBody); } else { DeclarationAST *decl = 0; if (!parseDeclaration(decl)) { reportError(i18n("Declaration syntax error")); } ast->setDeclaration(decl); } UPDATE_POS(ast, start, tokenStream->cursor()); node = ast; return true;}bool Parser::parseLinkageBody(LinkageBodyAST *&node){ int start = tokenStream->cursor(); if (tokenStream->lookAhead() != '{') { return false; } advance(); LinkageBodyAST *lba = CreateNode<LinkageBodyAST>(m_pool); node = lba; while (tokenStream->lookAhead()) { int tk = tokenStream->lookAhead(); if (tk == '}') break; DeclarationAST *def = 0; int startDecl = tokenStream->cursor(); if (parseDeclaration(def)) { node->addDeclaration(def); } else { // error recovery if (startDecl == tokenStream->cursor()) advance(); // skip at least one token skipUntilDeclaration(); } } if (tokenStream->lookAhead() != '}') { reportError(i18n("} expected")); } else advance(); UPDATE_POS(node, start, tokenStream->cursor()); return true;}bool Parser::parseNamespace(DeclarationAST *&node){ int start = tokenStream->cursor(); if (tokenStream->lookAhead() != Token_namespace) { return false; } advance(); int startNamespaceName = tokenStream->cursor(); if (tokenStream->lookAhead() == Token_identifier) { advance(); } AST *namespaceName = CreateNode<AST>(m_pool); UPDATE_POS(namespaceName, startNamespaceName, tokenStream->cursor()); if (tokenStream->lookAhead() == '=') { // namespace alias advance(); NameAST *name = 0; if (parseName(name)) { ADVANCE(';', ";"); NamespaceAliasAST *ast = CreateNode<NamespaceAliasAST>(m_pool); ast->setNamespaceName(namespaceName); ast->setAliasName(name); UPDATE_POS(ast, start, tokenStream->cursor()); node = ast; return true; } else { reportError(i18n("namespace expected")); return false; } } else if (tokenStream->lookAhead() != '{') { reportError(i18n("{ expected")); return false; } NamespaceAST *ast = CreateNode<NamespaceAST>(m_pool); ast->setNamespaceName(namespaceName); LinkageBodyAST *linkageBody = 0; parseLinkageBody(linkageBody); ast->setLinkageBody(linkageBody); UPDATE_POS(ast, start, tokenStream->cursor()); node = ast; return true;}bool Parser::parseUsing(DeclarationAST *&node){ int start = tokenStream->cursor(); if (tokenStream->lookAhead() != Token_using) { return false; } advance(); if (tokenStream->lookAhead() == Token_namespace) { if (!parseUsingDirective(node)) { return false; } UPDATE_POS(node, start, tokenStream->cursor()); return true; } UsingAST *ast = CreateNode<UsingAST>(m_pool); int startTypeName = tokenStream->cursor(); if (tokenStream->lookAhead() == Token_typename) { advance(); AST *tn = CreateNode<AST>(m_pool); UPDATE_POS(tn, startTypeName, tokenStream->cursor()); ast->setTypeName(tn); } NameAST *name = 0; if (!parseName(name)) return false; ast->setName(name); ADVANCE(';', ";"); UPDATE_POS(ast, start, tokenStream->cursor()); node = ast; return true;}bool Parser::parseUsingDirective(DeclarationAST *&node){ int start = tokenStream->cursor(); if (tokenStream->lookAhead() != Token_namespace) { return false; } advance(); NameAST *name = 0; if (!parseName(name)) { reportError(i18n("Namespace name expected")); return false; } ADVANCE(';', ";"); UsingDirectiveAST *ast = CreateNode<UsingDirectiveAST>(m_pool); ast->setName(name); UPDATE_POS(ast, start, tokenStream->cursor()); node = ast; return true;}bool Parser::parseOperatorFunctionId(AST *&node){ int start = tokenStream->cursor(); if (tokenStream->lookAhead() != Token_operator) { return false; } advance(); AST *op = 0; if (parseOperator(op)) { AST *asn = CreateNode<AST>(m_pool); node = asn; UPDATE_POS(node, start, tokenStream->cursor()); return true; } else { // parse cast operator AST *cv = 0; parseCvQualify(cv); TypeSpecifierAST *spec = 0; if (!parseSimpleTypeSpecifier(spec)) { syntaxError(); return false; } spec->setCvQualify(cv); AST *cv2 = 0; parseCvQualify(cv2); spec->setCv2Qualify(cv2); AST *ptrOp = 0; while (parsePtrOperator(ptrOp)) ; AST *asn = CreateNode<AST>(m_pool); node = asn; UPDATE_POS(node, start, tokenStream->cursor()); return true; }}bool Parser::parseTemplateArgumentList(TemplateArgumentListAST *&node, bool reportError){ int start = tokenStream->cursor(); TemplateArgumentListAST *ast = CreateNode<TemplateArgumentListAST>(m_pool); AST *templArg = 0; if (!parseTemplateArgument(templArg)) return false; ast->addArgument(templArg); while (tokenStream->lookAhead() == ',') { advance(); if (!parseTemplateArgument(templArg)) { if (reportError) { syntaxError(); break; } else return false; } ast->addArgument(templArg); } UPDATE_POS(ast, start, tokenStream->cursor()); node = ast; return true;}bool Parser::parseTypedef(DeclarationAST *&node){ int start = tokenStream->cursor(); if (tokenStream->lookAhead() != Token_typedef) { return false; } advance(); TypeSpecifierAST *spec = 0; if (!parseTypeSpecifierOrClassSpec(spec)) { reportError(i18n("Need a type specifier to declare")); return false; } InitDeclaratorListAST *declarators = 0; if (!parseInitDeclaratorList(declarators)) { //reportError(i18n("Need an identifier to declare")); //return false; } ADVANCE(';', ";"); TypedefAST *ast = CreateNode<TypedefAST>(m_pool); ast->setTypeSpec(spec); ast->setInitDeclaratorList(declarators); UPDATE_POS(ast, start, tokenStream->cursor()); node = ast; return true;}bool Parser::parseAsmDefinition(DeclarationAST *&node){ int start = tokenStream->cursor(); ADVANCE(Token_asm, "asm"); AST *cv = 0; parseCvQualify(cv); skip('(', ')'); advance(); ADVANCE(';', ";"); DeclarationAST *ast = CreateNode<DeclarationAST>(m_pool); UPDATE_POS(ast, start, tokenStream->cursor()); node = ast; return true;}bool Parser::parseTemplateDeclaration(DeclarationAST *&node){ int start = tokenStream->cursor(); AST *exp = 0; int startExport = tokenStream->cursor(); if (tokenStream->lookAhead() == Token_export) { advance(); AST *n = CreateNode<AST>(m_pool); UPDATE_POS(n, startExport, tokenStream->cursor()); exp = n; } if (tokenStream->lookAhead() != Token_template) { return false; } advance(); TemplateParameterListAST *params = 0; if (tokenStream->lookAhead() == '<') { advance(); parseTemplateParameterList(params); ADVANCE('>', ">"); } DeclarationAST *def = 0; if (!parseDeclaration(def)) { reportError(i18n("expected a declaration")); } TemplateDeclarationAST *ast = CreateNode<TemplateDeclarationAST>(m_pool); ast->setExported(exp); ast->setTemplateParameterList(params); ast->setDeclaration(def); UPDATE_POS(ast, start, tokenStream->cursor()); node = ast; return true;}bool Parser::parseOperator(AST *&/*node*/){ QString text = tokenStream->currentTokenText(); switch(tokenStream->lookAhead()) { case Token_new: case Token_delete: advance(); if (tokenStream->lookAhead() == '[' && tokenStream->lookAhead(1) == ']') { advance(); advance(); text += "[]"; } return true; case '+': case '-': case '*': case '/': case '%': case '^': case '&': case '|': case '~': case '!': case '=': case '<': case '>': case ',': case Token_assign: case Token_shift: case Token_eq: case Token_not_eq: case Token_leq: case Token_geq: case Token_and: case Token_or: case Token_incr: case Token_decr: case Token_ptrmem: case Token_arrow: advance(); return true; default: if (tokenStream->lookAhead() == '(' && tokenStream->lookAhead(1) == ')') { advance(); advance(); return true; } else if (tokenStream->lookAhead() == '[' && tokenStream->lookAhead(1) == ']') { advance(); advance(); return true; } } return false;}bool Parser::parseCvQualify(AST *&node){ int start = tokenStream->cursor(); AST *ast = CreateNode<AST>(m_pool); int n = 0; while (tokenStream->lookAhead()) { int tk = tokenStream->lookAhead(); if (tk == Token_const || tk == Token_volatile) { ++n; int startWord = tokenStream->cursor(); advance(); AST *word = CreateNode<AST>(m_pool); UPDATE_POS(word, startWord, tokenStream->cursor()); word->setParent(ast); } else break; } if (n == 0) return false; UPDATE_POS(ast, start, tokenStream->cursor()); node = ast;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -