diff --git a/clang-tools-extra/pseudo/tool/ClangPseudo.cpp b/clang-tools-extra/pseudo/tool/ClangPseudo.cpp --- a/clang-tools-extra/pseudo/tool/ClangPseudo.cpp +++ b/clang-tools-extra/pseudo/tool/ClangPseudo.cpp @@ -18,6 +18,7 @@ #include "clang-pseudo/grammar/LRGraph.h" #include "clang-pseudo/grammar/LRTable.h" #include "clang/Basic/LangOptions.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/Support/CommandLine.h" @@ -185,14 +186,32 @@ llvm::outs() << "GSS bytes: " << GSS.bytes() << " nodes: " << GSS.nodesCreated() << "\n"; + llvm::DenseMap AmbiguousSamples; for (auto &P : {std::make_pair("Ambiguous", ForestNode::Ambiguous), std::make_pair("Opaque", ForestNode::Opaque)}) { clang::pseudo::NodeStats Stats( - Root, [&](const auto &N) { return N.kind() == P.second; }); + Root, [&](const clang::pseudo::ForestNode &N) { + if (N.kind() == ForestNode::Ambiguous) { + if (AmbiguousSamples.count(N.symbol()) == 0) { + Token::Index Start, Last; + Start = Last = N.startTokenIndex(); + for (auto &It : N.descendants()) { + if (It.kind() == ForestNode::Terminal) + Last = std::max(Last, It.startTokenIndex()); + } + std::string TextCode; + for (const auto &T : + ParseableStream->tokens().slice(Start, Last - Start + 1)) + TextCode += T.text(); + AmbiguousSamples.insert({N.symbol(), TextCode}); + } + } + return N.kind() == P.second; + }); llvm::outs() << "\n" << Stats.Total << " " << P.first << " nodes:\n"; for (const auto &S : Stats.BySymbol) - llvm::outs() << llvm::formatv(" {0,3} {1}\n", S.second, - Lang.G.symbolName(S.first)); + llvm::outs() << llvm::formatv(" {0,3} {1}, sample code: {2}\n", S.second, + Lang.G.symbolName(S.first), AmbiguousSamples[S.first]); } // Metrics for how imprecise parsing was.