Merge pull request #2505 from foxever/ast-pretty-print

Feature: Add pretty print AST to CPP runtime
This commit is contained in:
Terence Parr 2019-11-11 08:28:22 -08:00 committed by GitHub
commit f7ffbdeea9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 37 additions and 25 deletions

View File

@ -231,3 +231,4 @@ YYYY/MM/DD, github id, Full name, email
2019/09/17, kaz, Kazuki Sawada, kazuki@6715.jp
2019/09/28, lmy269, Mingyang Liu, lmy040758@gmail.com
2019/10/31, a-square, Alexei Averchenko, lex.aver@gmail.com
2019/11/11, foxeverl, Liu Xinfeng, liuxf1986[at]gmail[dot]com

View File

@ -75,16 +75,16 @@ antlrcpp::Any RuleContext::accept(tree::ParseTreeVisitor *visitor) {
return visitor->visitChildren(this);
}
std::string RuleContext::toStringTree(Parser *recog) {
return tree::Trees::toStringTree(this, recog);
std::string RuleContext::toStringTree(Parser *recog, bool pretty) {
return tree::Trees::toStringTree(this, recog, pretty);
}
std::string RuleContext::toStringTree(std::vector<std::string> &ruleNames) {
return tree::Trees::toStringTree(this, ruleNames);
std::string RuleContext::toStringTree(std::vector<std::string> &ruleNames, bool pretty) {
return tree::Trees::toStringTree(this, ruleNames, pretty);
}
std::string RuleContext::toStringTree() {
return toStringTree(nullptr);
std::string RuleContext::toStringTree(bool pretty) {
return toStringTree(nullptr, pretty);
}

View File

@ -110,15 +110,15 @@ namespace antlr4 {
/// (root child1 .. childN). Print just a node if this is a leaf.
/// We have to know the recognizer so we can get rule names.
/// </summary>
virtual std::string toStringTree(Parser *recog) override;
virtual std::string toStringTree(Parser *recog, bool pretty = false) override;
/// <summary>
/// Print out a whole tree, not just a node, in LISP format
/// (root child1 .. childN). Print just a node if this is a leaf.
/// </summary>
virtual std::string toStringTree(std::vector<std::string> &ruleNames);
virtual std::string toStringTree(std::vector<std::string> &ruleNames, bool pretty = false);
virtual std::string toStringTree() override;
virtual std::string toStringTree(bool pretty = false) override;
virtual std::string toString() override;
std::string toString(Recognizer *recog);
std::string toString(const std::vector<std::string> &ruleNames);

View File

@ -39,12 +39,12 @@ namespace tree {
/// Print out a whole tree, not just a node, in LISP format
/// {@code (root child1 .. childN)}. Print just a node if this is a leaf.
virtual std::string toStringTree() = 0;
virtual std::string toStringTree(bool pretty = false) = 0;
virtual std::string toString() = 0;
/// Specialize toStringTree so that it can print out more information
/// based upon the parser.
virtual std::string toStringTree(Parser *parser) = 0;
virtual std::string toStringTree(Parser *parser, bool pretty = false) = 0;
virtual bool operator == (const ParseTree &other) const;

View File

@ -41,7 +41,7 @@ std::string TerminalNodeImpl::getText() {
return symbol->getText();
}
std::string TerminalNodeImpl::toStringTree(Parser * /*parser*/) {
std::string TerminalNodeImpl::toStringTree(Parser * /*parser*/, bool /*pretty*/) {
return toString();
}
@ -52,6 +52,6 @@ std::string TerminalNodeImpl::toString() {
return symbol->getText();
}
std::string TerminalNodeImpl::toStringTree() {
std::string TerminalNodeImpl::toStringTree(bool /*pretty*/) {
return toString();
}

View File

@ -23,9 +23,9 @@ namespace tree {
virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) override;
virtual std::string getText() override;
virtual std::string toStringTree(Parser *parser) override;
virtual std::string toStringTree(Parser *parser, bool pretty = false) override;
virtual std::string toString() override;
virtual std::string toStringTree() override;
virtual std::string toStringTree(bool pretty = false) override;
};

View File

@ -25,17 +25,17 @@ using namespace antlrcpp;
Trees::Trees() {
}
std::string Trees::toStringTree(ParseTree *t) {
return toStringTree(t, nullptr);
std::string Trees::toStringTree(ParseTree *t, bool pretty) {
return toStringTree(t, nullptr, pretty);
}
std::string Trees::toStringTree(ParseTree *t, Parser *recog) {
std::string Trees::toStringTree(ParseTree *t, Parser *recog, bool pretty) {
if (recog == nullptr)
return toStringTree(t, std::vector<std::string>());
return toStringTree(t, recog->getRuleNames());
return toStringTree(t, std::vector<std::string>(), pretty);
return toStringTree(t, recog->getRuleNames(), pretty);
}
std::string Trees::toStringTree(ParseTree *t, const std::vector<std::string> &ruleNames) {
std::string Trees::toStringTree(ParseTree *t, const std::vector<std::string> &ruleNames, bool pretty) {
std::string temp = antlrcpp::escapeWhitespace(Trees::getNodeText(t, ruleNames), false);
if (t->children.empty()) {
return temp;
@ -48,6 +48,7 @@ std::string Trees::toStringTree(ParseTree *t, const std::vector<std::string> &ru
std::stack<size_t> stack;
size_t childIndex = 0;
ParseTree *run = t;
size_t indentationLevel = 1;
while (childIndex < run->children.size()) {
if (childIndex > 0) {
ss << ' ';
@ -59,6 +60,13 @@ std::string Trees::toStringTree(ParseTree *t, const std::vector<std::string> &ru
stack.push(childIndex);
run = child;
childIndex = 0;
if (pretty) {
++indentationLevel;
ss << std::endl;
for (size_t i = 0; i < indentationLevel; ++i) {
ss << " ";
}
}
ss << "(" << temp << " ";
} else {
ss << temp;
@ -68,6 +76,9 @@ std::string Trees::toStringTree(ParseTree *t, const std::vector<std::string> &ru
childIndex = stack.top();
stack.pop();
run = run->parent;
if (pretty) {
--indentationLevel;
}
ss << ")";
} else {
break;

View File

@ -18,17 +18,17 @@ namespace tree {
/// Print out a whole tree in LISP form. getNodeText is used on the
/// node payloads to get the text for the nodes. Detect
/// parse trees and extract data appropriately.
static std::string toStringTree(ParseTree *t);
static std::string toStringTree(ParseTree *t, bool pretty = false);
/// Print out a whole tree in LISP form. getNodeText is used on the
/// node payloads to get the text for the nodes. Detect
/// parse trees and extract data appropriately.
static std::string toStringTree(ParseTree *t, Parser *recog);
static std::string toStringTree(ParseTree *t, Parser *recog, bool pretty = false);
/// Print out a whole tree in LISP form. getNodeText is used on the
/// node payloads to get the text for the nodes. Detect
/// parse trees and extract data appropriately.
static std::string toStringTree(ParseTree *t, const std::vector<std::string> &ruleNames);
static std::string toStringTree(ParseTree *t, const std::vector<std::string> &ruleNames, bool pretty = false);
static std::string getNodeText(ParseTree *t, Parser *recog);
static std::string getNodeText(ParseTree *t, const std::vector<std::string> &ruleNames);