mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Make the tree structure more explicit in parse dumps (#7591)
It's hard to track 2-space indent levels across large vertical gaps, and it can be hard to suppress the instinct to read the dump as if it were preorder. This change introduces a new dump mode that addresses both problems by using box-drawing characters to explicitly represent the parent-child edges of the tree. This new mode is the default, but the old behavior remains available with `--parse-dump-format=yaml-postorder`.
This commit is contained in:
@@ -140,8 +140,8 @@ auto TreeAndSubtrees::roots() const -> llvm::iterator_range<SiblingIterator> {
|
||||
SiblingIterator(*this, NodeId(-1)));
|
||||
}
|
||||
|
||||
auto TreeAndSubtrees::PrintNode(llvm::raw_ostream& output, NodeId n, int depth,
|
||||
bool preorder) const -> bool {
|
||||
auto TreeAndSubtrees::YamlPrintNode(llvm::raw_ostream& output, NodeId n,
|
||||
int depth, bool preorder) const -> bool {
|
||||
output.indent(2 * (depth + 2));
|
||||
output << "{";
|
||||
// If children are being added, include node_index in order to disambiguate
|
||||
@@ -167,9 +167,56 @@ auto TreeAndSubtrees::PrintNode(llvm::raw_ostream& output, NodeId n, int depth,
|
||||
return false;
|
||||
}
|
||||
|
||||
auto TreeAndSubtrees::Print(llvm::raw_ostream& output) const -> void {
|
||||
output << "- filename: " << tokens_->source().filename() << "\n"
|
||||
<< " parse_tree: [\n";
|
||||
auto TreeAndSubtrees::PrettyPrintNode(llvm::raw_ostream& output, NodeId n,
|
||||
int depth,
|
||||
llvm::BitVector& pending_parents) const
|
||||
-> void {
|
||||
output.indent(2);
|
||||
// In this mode we treat all nodes as nested under the parse tree root.
|
||||
++depth;
|
||||
CARBON_CHECK(pending_parents.find_last() <= depth,
|
||||
"Node interleaved between a non-ancestor and its child");
|
||||
pending_parents.resize(depth);
|
||||
|
||||
for (int i = 0; i < depth; ++i) {
|
||||
if (i == depth - 1) {
|
||||
if (pending_parents.test(i)) {
|
||||
output << "├─";
|
||||
} else {
|
||||
output << "╭─";
|
||||
pending_parents.set(i);
|
||||
}
|
||||
} else {
|
||||
if (pending_parents.test(i)) {
|
||||
output << "│ ";
|
||||
} else {
|
||||
output << " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
output << tree_->node_kind(n) << " '"
|
||||
<< tokens_->GetTokenText(tree_->node_token(n)) << "'";
|
||||
|
||||
if (tree_->node_has_error(n)) {
|
||||
output << " has_error";
|
||||
}
|
||||
}
|
||||
|
||||
auto TreeAndSubtrees::PrintYamlPostorder(llvm::raw_ostream& output) const
|
||||
-> void {
|
||||
PrintPostorder(output, /*yaml=*/true);
|
||||
}
|
||||
|
||||
auto TreeAndSubtrees::PrettyPrint(llvm::raw_ostream& output) const -> void {
|
||||
PrintPostorder(output, /*yaml=*/false);
|
||||
}
|
||||
|
||||
auto TreeAndSubtrees::PrintPostorder(llvm::raw_ostream& output, bool yaml) const
|
||||
-> void {
|
||||
output << "- filename: " << tokens_->source().filename() << "\n";
|
||||
if (yaml) {
|
||||
output << " parse_tree: [\n";
|
||||
}
|
||||
|
||||
// Walk the tree in reverse, just to calculate depths for each node.
|
||||
llvm::SmallVector<int> depths(tree_->size(), 0);
|
||||
@@ -180,14 +227,25 @@ auto TreeAndSubtrees::Print(llvm::raw_ostream& output) const -> void {
|
||||
}
|
||||
}
|
||||
|
||||
llvm::BitVector pending_parents;
|
||||
for (auto [n, depth] : llvm::zip_equal(tree_->postorder(), depths)) {
|
||||
PrintNode(output, n, depth, /*preorder=*/false);
|
||||
output << ",\n";
|
||||
if (yaml) {
|
||||
YamlPrintNode(output, n, depth, /*preorder=*/false);
|
||||
output << ",\n";
|
||||
} else {
|
||||
PrettyPrintNode(output, n, depth, pending_parents);
|
||||
output << "\n";
|
||||
}
|
||||
}
|
||||
if (yaml) {
|
||||
output << " ]\n";
|
||||
} else {
|
||||
output << " (root)\n";
|
||||
}
|
||||
output << " ]\n";
|
||||
}
|
||||
|
||||
auto TreeAndSubtrees::PrintPreorder(llvm::raw_ostream& output) const -> void {
|
||||
auto TreeAndSubtrees::PrintYamlPreorder(llvm::raw_ostream& output) const
|
||||
-> void {
|
||||
output << "- filename: " << tokens_->source().filename() << "\n"
|
||||
<< " parse_tree: [\n";
|
||||
|
||||
@@ -208,7 +266,7 @@ auto TreeAndSubtrees::PrintPreorder(llvm::raw_ostream& output) const -> void {
|
||||
int depth;
|
||||
std::tie(n, depth) = node_stack.pop_back_val();
|
||||
|
||||
if (PrintNode(output, n, depth, /*preorder=*/true)) {
|
||||
if (YamlPrintNode(output, n, depth, /*preorder=*/true)) {
|
||||
// Has children, so we descend. We append the children in order here as
|
||||
// well because they will get reversed when popped off the stack.
|
||||
for (NodeId sibling_n : children(n)) {
|
||||
|
||||
Reference in New Issue
Block a user