[clang-tools-extra] 72864d9 - [pseudo] Use box-drawing chars to prettify debug dumps. NFC
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 25 06:17:46 PDT 2022
Author: Sam McCall
Date: 2022-03-25T14:17:38+01:00
New Revision: 72864d9bfec929b2427981d99c2ac67ff5fcfe19
URL: https://github.com/llvm/llvm-project/commit/72864d9bfec929b2427981d99c2ac67ff5fcfe19
DIFF: https://github.com/llvm/llvm-project/commit/72864d9bfec929b2427981d99c2ac67ff5fcfe19.diff
LOG: [pseudo] Use box-drawing chars to prettify debug dumps. NFC
Added:
Modified:
clang-tools-extra/pseudo/lib/Forest.cpp
clang-tools-extra/pseudo/unittests/ForestTest.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/pseudo/lib/Forest.cpp b/clang-tools-extra/pseudo/lib/Forest.cpp
index 41b9be8a8d30f..6948422a23a6e 100644
--- a/clang-tools-extra/pseudo/lib/Forest.cpp
+++ b/clang-tools-extra/pseudo/lib/Forest.cpp
@@ -46,15 +46,23 @@ std::string ForestNode::dumpRecursive(const Grammar &G,
};
CountVisits(this);
+ // The box-drawing characters that should be added as a child is rendered.
+ struct LineDecoration {
+ std::string Prefix; // Prepended to every line.
+ llvm::StringRef First; // added to the child's line.
+ llvm::StringRef Subsequent; // added to descendants' lines.
+ };
+
// We print a "#<id>" for nonterminal forest nodes that are being dumped
// multiple times.
llvm::DenseMap<const ForestNode *, size_t> ReferenceIds;
std::string Result;
constexpr Token::Index KEnd = std::numeric_limits<Token::Index>::max();
- std::function<void(const ForestNode *, unsigned, Token::Index,
- llvm::Optional<SymbolID>)>
- Dump = [&](const ForestNode *P, unsigned Level, Token::Index End,
- llvm::Optional<SymbolID> ElidedParent) {
+ std::function<void(const ForestNode *, Token::Index, llvm::Optional<SymbolID>,
+ LineDecoration &LineDec)>
+ Dump = [&](const ForestNode *P, Token::Index End,
+ llvm::Optional<SymbolID> ElidedParent,
+ LineDecoration LineDec) {
llvm::ArrayRef<const ForestNode *> Children;
auto EndOfElement = [&](size_t ChildIndex) {
return ChildIndex + 1 == Children.size()
@@ -72,18 +80,19 @@ std::string ForestNode::dumpRecursive(const Grammar &G,
if (Children[I]->startTokenIndex() == P->startTokenIndex() &&
EndOfElement(I) == End) {
return Dump(
- Children[I], Level, End,
- /*ElidedParent=*/ElidedParent.getValueOr(P->symbol()));
+ Children[I], End,
+ /*ElidedParent=*/ElidedParent.getValueOr(P->symbol()),
+ LineDec);
}
}
}
- // FIXME: pretty ascii trees
if (End == KEnd)
Result += llvm::formatv("[{0,3}, end) ", P->startTokenIndex());
else
Result += llvm::formatv("[{0,3}, {1,3}) ", P->startTokenIndex(), End);
- Result.append(2 * Level, ' ');
+ Result += LineDec.Prefix;
+ Result += LineDec.First;
if (ElidedParent.hasValue()) {
Result += G.symbolName(*ElidedParent);
Result += "~";
@@ -99,12 +108,23 @@ std::string ForestNode::dumpRecursive(const Grammar &G,
}
Result.push_back('\n');
- ++Level;
- for (size_t I = 0; I < Children.size(); ++I)
- Dump(Children[I], Level,
- P->kind() == Sequence ? EndOfElement(I) : End, llvm::None);
+ auto OldPrefixSize = LineDec.Prefix.size();
+ LineDec.Prefix += LineDec.Subsequent;
+ for (size_t I = 0; I < Children.size(); ++I) {
+ if (I == Children.size() - 1) {
+ LineDec.First = "└─";
+ LineDec.Subsequent = " ";
+ } else {
+ LineDec.First = "├─";
+ LineDec.Subsequent = "│ ";
+ }
+ Dump(Children[I], P->kind() == Sequence ? EndOfElement(I) : End,
+ llvm::None, LineDec);
+ }
+ LineDec.Prefix.resize(OldPrefixSize);
};
- Dump(this, 0, KEnd, llvm::None);
+ LineDecoration LineDec;
+ Dump(this, KEnd, llvm::None, LineDec);
return Result;
}
diff --git a/clang-tools-extra/pseudo/unittests/ForestTest.cpp b/clang-tools-extra/pseudo/unittests/ForestTest.cpp
index b9bd08d78288a..a734a8f7f8616 100644
--- a/clang-tools-extra/pseudo/unittests/ForestTest.cpp
+++ b/clang-tools-extra/pseudo/unittests/ForestTest.cpp
@@ -71,19 +71,20 @@ TEST_F(ForestTest, DumpBasic) {
ruleFor("id-expression"), {&T[2]});
const auto *Add =
- &Arena.createSequence(symbol("add-expression"), ruleFor("add-expression"), {Left, &T[1], Right});
+ &Arena.createSequence(symbol("add-expression"), ruleFor("add-expression"),
+ {Left, &T[1], Right});
EXPECT_EQ(Add->dumpRecursive(*G, true),
"[ 0, end) add-expression := id-expression + id-expression\n"
- "[ 0, 1) id-expression~IDENTIFIER := tok[0]\n"
- "[ 1, 2) + := tok[1]\n"
- "[ 2, end) id-expression~IDENTIFIER := tok[2]\n");
+ "[ 0, 1) ├─id-expression~IDENTIFIER := tok[0]\n"
+ "[ 1, 2) ├─+ := tok[1]\n"
+ "[ 2, end) └─id-expression~IDENTIFIER := tok[2]\n");
EXPECT_EQ(Add->dumpRecursive(*G, false),
"[ 0, end) add-expression := id-expression + id-expression\n"
- "[ 0, 1) id-expression := IDENTIFIER\n"
- "[ 0, 1) IDENTIFIER := tok[0]\n"
- "[ 1, 2) + := tok[1]\n"
- "[ 2, end) id-expression := IDENTIFIER\n"
- "[ 2, end) IDENTIFIER := tok[2]\n");
+ "[ 0, 1) ├─id-expression := IDENTIFIER\n"
+ "[ 0, 1) │ └─IDENTIFIER := tok[0]\n"
+ "[ 1, 2) ├─+ := tok[1]\n"
+ "[ 2, end) └─id-expression := IDENTIFIER\n"
+ "[ 2, end) └─IDENTIFIER := tok[2]\n");
}
TEST_F(ForestTest, DumpAmbiguousAndRefs) {
@@ -115,14 +116,14 @@ TEST_F(ForestTest, DumpAmbiguousAndRefs) {
&Arena.createAmbiguous(symbol("type"), {Alternative1, Alternative2});
EXPECT_EQ(Type->dumpRecursive(*G),
"[ 0, end) type := <ambiguous>\n"
- "[ 0, end) class-type := shared-type\n"
- "[ 0, end) class-type := shared-type\n"
- "[ 0, end) shared-type := IDENTIFIER #1\n"
- "[ 0, end) IDENTIFIER := tok[0]\n"
- "[ 0, end) enum-type := shared-type\n"
- "[ 0, end) enum-type := shared-type\n"
- "[ 0, end) shared-type := IDENTIFIER =#1\n"
- "[ 0, end) IDENTIFIER := tok[0]\n");
+ "[ 0, end) ├─class-type := shared-type\n"
+ "[ 0, end) │ └─class-type := shared-type\n"
+ "[ 0, end) │ └─shared-type := IDENTIFIER #1\n"
+ "[ 0, end) │ └─IDENTIFIER := tok[0]\n"
+ "[ 0, end) └─enum-type := shared-type\n"
+ "[ 0, end) └─enum-type := shared-type\n"
+ "[ 0, end) └─shared-type := IDENTIFIER =#1\n"
+ "[ 0, end) └─IDENTIFIER := tok[0]\n");
}
} // namespace
More information about the cfe-commits
mailing list