std::string PropertyParser::parseType(bool SupressDiagnostics) { std::string Result; bool HasConst = Test(clang::tok::kw_const); bool HasVolatile = Test(clang::tok::kw_volatile); bool NoTemplates = true; Test(clang::tok::kw_enum) || Test(clang::tok::kw_class) || Test(clang::tok::kw_struct); if (Test(clang::tok::kw_unsigned)) { Result += parseUnsigned(); } else if (Test(clang::tok::kw_signed)) { Result += "signed"; while (true) { switch(+CurrentTok.getKind()) { case clang::tok::kw_int: case clang::tok::kw_long: case clang::tok::kw_short: case clang::tok::kw_char: Consume(); Result += " " + Spelling(); continue; } break; } } else { while(Test(clang::tok::kw_int) || Test(clang::tok::kw_long) || Test(clang::tok::kw_short) || Test(clang::tok::kw_char) || Test(clang::tok::kw_void) || Test(clang::tok::kw_bool) || Test(clang::tok::kw_double) || Test(clang::tok::kw_float)) { if (!Result.empty()) Result += " "; Result += Spelling(); } } if (Result.empty()) { clang::CXXScopeSpec SS; if (Test(clang::tok::coloncolon)) { SS.MakeGlobal(Sema.getASTContext(), OriginalLocation()); Result += Spelling(); } do { if (!Test(clang::tok::identifier)) { PP.getDiagnostics().Report(OriginalLocation(CurrentTok.getLocation()), PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, "Invalid token while parsing type")); return {}; } Result += Spelling(); if (Test(clang::tok::less)) { NoTemplates = false; Result += "<"; Result += parseTemplateType(); if (!PrevToken.is(clang::tok::greater)) { PP.getDiagnostics().Report(OriginalLocation(CurrentTok.getLocation()), PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, "parse error in type")); return {}; //error; } } clang::Token IdentTok = PrevToken; if (!Test(clang::tok::coloncolon)) break; if (NoTemplates && !SupressDiagnostics) { if (Sema.ActOnCXXNestedNameSpecifier(Sema.getScopeForContext(RD), *IdentTok.getIdentifierInfo(), OriginalLocation(IdentTok.getLocation()), OriginalLocation(CurrentTok.getLastLoc()), {}, false, SS)) SS.SetInvalid({OriginalLocation(IdentTok.getLocation()), OriginalLocation(CurrentTok.getLastLoc())}); } Result += Spelling(); } while (true); if (NoTemplates && !SupressDiagnostics) { IsEnum = true; // That's how moc does it. if (SS.isNotEmpty() && SS.isValid()) { Extra = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(Sema.computeDeclContext(SS)); clang::LookupResult Found(Sema, PrevToken.getIdentifierInfo(), OriginalLocation(), clang::Sema::LookupNestedNameSpecifierName); /*if (SS.isEmpty()) Sema.LookupQualifiedName(Found, RD); else {*/ clang::DeclContext* DC = Sema.computeDeclContext(SS); Sema.LookupQualifiedName(Found, DC ? DC : RD); //} clang::EnumDecl* R = Found.getAsSingle<clang::EnumDecl>(); /*if (!R) { if (clang::TypedefDecl *TD = Found.getAsSingle<clang::TypedefDecl>()) { const clang::TemplateSpecializationType* TDR = TD->getUnderlyingType()->getAs<clang::TemplateSpecializationType>(); if(TDR && TDR->getNumArgs() == 1 && TDR->getTemplateName().getAsTemplateDecl()->getName() == "QFlags") { if (const clang::EnumType* ET = TDR->getArg(0).getAsType()->getAs<clang::EnumType>()) R = ET->getDecl(); } }*/ /*if (!R) IsEnum = false;*/ if(Extra) { bool isQObjectOrQGadget = false; for (auto it = Extra->decls_begin(); it != Extra->decls_end(); ++it) { auto ND = llvm::dyn_cast<clang::NamedDecl>(*it); if (ND && ND->getIdentifier() && ND->getName() == "staticMetaObject") { isQObjectOrQGadget = true; break; } } if (!isQObjectOrQGadget) Extra = nullptr; } if (!R) { clang::CXXRecordDecl* D = Found.getAsSingle<clang::CXXRecordDecl>(); if (D && !D->hasDefinition()) IsPossiblyForwardDeclared = true; } } else if (SS.isEmpty()) { clang::LookupResult Found(Sema, PrevToken.getIdentifierInfo(), OriginalLocation(), clang::Sema::LookupNestedNameSpecifierName); Sema.LookupName(Found, Sema.getScopeForContext(RD)); clang::CXXRecordDecl* D = Found.getAsSingle<clang::CXXRecordDecl>(); if (D && !D->hasDefinition()) { IsPossiblyForwardDeclared = true; } Found.suppressDiagnostics(); } } } if (NoTemplates && Test(clang::tok::kw_const)) { // The official moc don't move the const if there are templates HasConst = true; } while (Test(clang::tok::kw_volatile) || Test(clang::tok::star) || Test(clang::tok::kw_const)) { Extra = nullptr; IsEnum = false; Result += Spelling(); } if (Test(clang::tok::amp)) { if (HasConst) HasConst = false; // remove const reference else Result += Spelling(); } else { Test(clang::tok::ampamp); // skip rvalue ref } if (HasVolatile) Result = "volatile " + Result; if (HasConst) Result = "const " + Result; return Result; }
std::string PropertyParser::parseTemplateType() { std::string Result; int ParensLevel = 0; bool MoveConstToFront = true; bool HasConst = false; clang::CXXScopeSpec SS; do { switch(+CurrentTok.getKind()) { case clang::tok::eof: return {}; case clang::tok::greatergreater: if (ParensLevel > 0) break; CurrentTok.setKind(clang::tok::greater); PrevToken.setKind(clang::tok::greater); if (Result[Result.size()-1] == '>') Result += " "; Result += ">"; return Result; case clang::tok::greater: if (ParensLevel > 0) break; if (Result[Result.size()-1] == '>') Result += " "; Result += ">"; Consume(); return Result; case clang::tok::less: if (ParensLevel > 0 ) break; Result += "<"; Consume(); Result += parseTemplateType(); if (!PrevToken.is(clang::tok::greater)) return {}; MoveConstToFront = false; continue; case clang::tok::l_square: case clang::tok::l_paren: case clang::tok::l_brace: ++ParensLevel; break; case clang::tok::r_square: case clang::tok::r_paren: case clang::tok::r_brace: --ParensLevel; if (ParensLevel < 0) return {}; break; case clang::tok::comma: if (ParensLevel > 0) break; Result += ","; Consume(); return Result + parseTemplateType(); case clang::tok::kw_const: if (MoveConstToFront) { HasConst = true; continue; } break; case clang::tok::kw_unsigned: if (IsIdentChar(Result[Result.size()])) Result+=" "; Result += parseUnsigned(); continue; case clang::tok::amp: case clang::tok::ampamp: case clang::tok::star: MoveConstToFront = false; break; case clang::tok::identifier: { clang::LookupResult Found(Sema, CurrentTok.getIdentifierInfo(), OriginalLocation(CurrentTok.getLocation()), clang::Sema::LookupNestedNameSpecifierName); Sema.LookupParsedName(Found, Sema.getScopeForContext(RD), &SS); clang::CXXRecordDecl* D = Found.getAsSingle<clang::CXXRecordDecl>(); if (D && !D->hasDefinition()) IsPossiblyForwardDeclared = true; Found.suppressDiagnostics(); break; } case clang::tok::coloncolon: if (PrevToken.getIdentifierInfo()) SS.Extend(Sema.getASTContext(), PrevToken.getIdentifierInfo(), OriginalLocation(), OriginalLocation(CurrentTok.getLocation())); break; } Consume(); auto Sp = Spelling(); char Last = Result[Result.size()]; if ((Last == '<' && Sp[0] == ':') || (IsIdentChar(Last) && IsIdentChar(Sp[0]))) Result += " "; Result += Sp; } while (true); if (HasConst) Result = "const " + Result; return Result; }
void main(){ scanf("%d", &n); int r; for(r = 0; r < n; r++){ scanf("%s", m[r]); } while(true){ //cin >> word; scanf("%s", word); len = strlen(word); if(len == 1 && word[0] == '0'){ break; } bool found = false; int sr, sc, dr, dc; for(sr = 0; sr < n; sr++){ for(sc = 0; sc < n; sc++){ if(Found(sr, sc, 1, 0, dr, dc)){ found = true; goto out; } if(Found(sr, sc, -1, 0, dr, dc)){ found = true; goto out; } if(Found(sr, sc, 0, 1, dr, dc)){ found = true; goto out; } if(Found(sr, sc, 0, -1, dr, dc)){ found = true; goto out; } if(Found(sr, sc, -1, -1, dr, dc)){ found = true; goto out; } if(Found(sr, sc, -1, 1, dr, dc)){ found = true; goto out; } if(Found(sr, sc, 1, -1, dr, dc)){ found = true; goto out; } if(Found(sr, sc, 1, 1, dr, dc)){ found = true; goto out; } } } out: if(found){ printf("%d,%d %d,%d\n", sr + 1, sc + 1, dr + 1, dc + 1); } else{ printf("Not found\n"); } } }