Increased dumper accuracy by genererating the dumper methods.

This commit is contained in:
Erik Verbruggen
2010-07-05 19:20:14 +02:00
parent 45e12ccb42
commit fbf2efa5f6
3 changed files with 1790 additions and 49 deletions

View File

@@ -73,13 +73,14 @@ public:
basename.append(".ast.dot");
out.open(basename.constData());
out << "digraph AST {" << std::endl;
out << "digraph AST { ordering=out;" << std::endl;
// std::cout << "rankdir = \"LR\";" << std::endl;
accept(ast);
foreach (const QByteArray &terminalShape, _terminalShapes) {
out << std::string(terminalShape) << " [shape=rect]" << std::endl;
}
typedef QPair<QByteArray, QByteArray> Pair;
foreach (const Pair &conn, _connections)
out << conn.first.constData() << " -> " << conn.second.constData() << std::endl;
alignTerminals();
@@ -88,6 +89,10 @@ public:
std::cout << basename.constData() << std::endl;
}
// the following file can be generated by using:
// generate-ast <path to cpp stuff> <path to dumpers.inc>
#include "dumpers.inc"
protected:
void alignTerminals() {
out<<"{ rank=same;" << std::endl;
@@ -97,59 +102,47 @@ protected:
out<<"}"<<std::endl;
}
QByteArray addTerminalInfo(AST *ast) const {
if (SimpleNameAST *simpleName = ast->asSimpleName()) {
return spell(simpleName->identifier_token);
} else if (BinaryExpressionAST *binExpr = ast->asBinaryExpression()) {
return spell(binExpr->binary_op_token);
} else if (SimpleSpecifierAST *simpleSpec = ast->asSimpleSpecifier()) {
return spell(simpleSpec->specifier_token);
} else if (NumericLiteralAST *numLit = ast->asNumericLiteral()) {
return spell(numLit->literal_token);
} else if (StringLiteralAST *strLit = ast->asStringLiteral()) {
return spell(strLit->literal_token);
} else if (BoolLiteralAST *boolLit = ast->asBoolLiteral()) {
return spell(boolLit->literal_token);
} else if (ObjCSelectorArgumentAST *selArg = ast->asObjCSelectorArgument()) {
QByteArray t = spell(selArg->name_token);
if (selArg->colon_token)
t.append(spell(selArg->colon_token));
return t;
} else if (AttributeAST *attr = ast->asAttribute()) {
return spell(attr->identifier_token);
} else {
return QByteArray();
}
}
std::string name(AST *ast) {
static QByteArray name(AST *ast) {
QByteArray name = abi::__cxa_demangle(typeid(*ast).name(), 0, 0, 0) + 11;
name.truncate(name.length() - 3);
name = QByteArray::number(_id.value(ast)) + ". " + name;
QByteArray info = addTerminalInfo(ast);
if (!info.isEmpty()) {
name.append("\\n");
name.append(info);
}
name.prepend('"');
name.append('"');
return name;
}
if (!info.isEmpty())
_terminalShapes.insert(name);
void terminal(unsigned token, AST *node) {
static int count = 1;
QByteArray id = 't' + QByteArray::number(count++);
_connections.append(qMakePair(_id[node], id));
return std::string(name);
QByteArray t;
t.append(id);
t.append(" [label = \"");
t.append(spell(token));
t.append("\" shape=rect]");
_terminalShapes.append(t);
}
virtual void nonterminal(AST *ast) {
accept(ast);
}
virtual void node(AST *ast) {
out << _id[ast].constData() << " [label=\"" << name(ast).constData() << "\"];" << std::endl;
}
virtual bool preVisit(AST *ast) {
static int count = 1;
_id[ast] = count++;
const QByteArray id = 'n' + QByteArray::number(count++);
_id[ast] = id;
if (! _stack.isEmpty())
out << name(_stack.last()) << " -> " << name(ast) << ";" << std::endl;
_connections.append(qMakePair(_id[_stack.last()], id));
_stack.append(ast);
node(ast);
return true;
}
@@ -158,9 +151,10 @@ protected:
}
private:
QHash<AST *, int> _id;
QHash<AST *, QByteArray> _id;
QList<QPair<QByteArray, QByteArray> > _connections;
QList<AST *> _stack;
QSet<QByteArray> _terminalShapes;
QList<QByteArray> _terminalShapes;
std::ofstream out;
};
@@ -183,7 +177,7 @@ public:
basename.append(".symbols.dot");
out.open(basename.constData());
out << "digraph Symbols {" << std::endl;
out << "digraph Symbols { ordering=out;" << std::endl;
// std::cout << "rankdir = \"LR\";" << std::endl;
accept(s);