Skip to content

Commit c99c62d

Browse files
author
Sreeni Viswanadha
committed
Added the unparser.
1 parent df03d03 commit c99c62d

File tree

8 files changed

+239
-750
lines changed

8 files changed

+239
-750
lines changed

parser/cpp/AstNode.h

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,36 @@ class AstNode : public SimpleNode {
2020
Token* endToken;
2121
virtual ~AstNode() {}
2222
AstNode(int id) : SimpleNode(id) {}
23+
2324
AstNode(SqlParser* parser, int id) : SimpleNode(parser, id) {}
24-
int NumChildren() { return jjtGetNumChildren(); }
25-
AstNode* GetChild(int i) { return static_cast<AstNode*>(jjtGetChild(i)); }
26-
JJString toString(const JJString& prefix) const {
25+
26+
int Kind() const { return id; }
27+
28+
int NumChildren() const { return jjtGetNumChildren(); }
29+
30+
AstNode* GetChild(int i) const { return static_cast<AstNode*>(jjtGetChild(i)); }
31+
32+
std::string GetImage() const { return NumChildren() == 0 ? beginToken->image : string(""); }
33+
34+
void VisitNode(SqlParserVisitor* visitor) const { jjtAccept(visitor, nullptr); }
35+
36+
void VisitChildren(SqlParserVisitor* visitor) const { jjtChildrenAccept(visitor, nullptr); }
37+
38+
const AstNode* FirstChild() const { return NumChildren() > 0 ? GetChild(0) : nullptr; }
39+
40+
const AstNode* LastChild() const { return NumChildren() > 0 ? GetChild(NumChildren() - 1) : nullptr; }
41+
42+
const AstNode* GetFirstChildOfKind(int kind) const {
43+
for (int i = 0; i < NumChildren(); i++) {
44+
if (GetChild(i)->Kind() == kind) {
45+
return GetChild(i);
46+
}
47+
}
48+
49+
return nullptr;
50+
}
51+
52+
std::string toString(const JJString& prefix) const {
2753
return SimpleNode::toString(prefix) +
2854
string(" (") +
2955
std::to_string(beginToken->beginLine) +

parser/cpp/compile.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/bin/sh
22
SRC_DIR=./target/generated-sources/javacc
33
TARGET_DIR=./target
4-
clang++ -fbracket-depth=1024 -funsigned-char -I. -I./$SRC_DIR -o $TARGET_DIR/sqlparser -std=c++11 ParseErrorHandler.cc main.cc $SRC_DIR/*.cc
4+
clang++ -fbracket-depth=1024 -funsigned-char -I. -I./$SRC_DIR -o $TARGET_DIR/sqlparser -std=c++11 ParseErrorHandler.cc main.cc $SRC_DIR/*.cc unparser.cc

parser/cpp/main.cc

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <iostream>
44
#include <string>
55
#include <stdlib.h>
6+
#include <ctime>
67

78
#include "SqlParserConstants.h"
89
#include "CharStream.h"
@@ -11,8 +12,7 @@
1112
#include "SqlParser.h"
1213
#include "SqlParserTokenManager.h"
1314
#include "parser.h"
14-
15-
#include <ctime>
15+
#include "unparser.h"
1616

1717
using namespace commonsql::parser;
1818
using namespace std;
@@ -39,21 +39,26 @@ int main(int argc, char **argv) {
3939
double time;
4040
start = clock();
4141

42-
for (int i = 0; i < 1; i++) {
4342
CharStream *stream = new CharStream(s.c_str(), s.size() - 1, 1, 1);
4443
SqlParserTokenManager *scanner = new SqlParserTokenManager(stream);
4544
SqlParser parser(scanner);
4645
parser.setErrorHandler(new ParseErrorHandler());
46+
for (int i = 0; i < 10; i++) {
47+
stream = new CharStream(s.c_str(), s.size() - 1, 1, 1);
48+
scanner->ReInit(stream);
49+
parser.ReInit(scanner);
4750
parser.compilation_unit();
4851
SimpleNode *root = (SimpleNode*)parser.jjtree.peekNode();
4952
if (root) {
5053
JAVACC_STRING_TYPE buffer;
5154
root->dumpToBuffer(" ", "\n", &buffer);
5255
printf("%s\n", buffer.c_str());
56+
57+
printf("Unparse:\n%s\n", unparse(static_cast<AstNode*>(root)).c_str());
5358
}
5459
}
5560

5661
finish = clock();
5762
time = (double(finish)-double(start))/CLOCKS_PER_SEC;
58-
printf ("Avg parsing time: %lfms\n", (time*1000)/1);
63+
printf ("Avg parsing time: %lfms\n", (time*1000)/10);
5964
}

parser/cpp/unparser.cc

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Licensed under the Apache License, Version 2->0 (the "License");
3+
* you may not use this file except in compliance with the License->
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www->apache->org/licenses/LICENSE-2->0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied->
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License->
13+
*/
14+
15+
#include "unparser.h"
16+
17+
namespace commonsql {
18+
namespace parser {
19+
20+
void Unparser::printSpecialTokens(const Token* t)
21+
{
22+
// special tokens are chained in reverse->
23+
Token* specialToken = t->specialToken;
24+
if (specialToken != nullptr) {
25+
while (specialToken->specialToken != nullptr) {
26+
specialToken = specialToken->specialToken;
27+
}
28+
while (specialToken != nullptr) {
29+
stringBuilder << specialToken->image.c_str();
30+
specialToken = specialToken->next;
31+
}
32+
}
33+
}
34+
35+
void Unparser::printTrailingComments()
36+
{
37+
if (lastToken != nullptr && lastToken->kind == EOF) {
38+
printSpecialTokens(lastToken);
39+
}
40+
}
41+
42+
void Unparser::printToken(const std::string& s)
43+
{
44+
stringBuilder << " " << s.c_str() << " ";
45+
}
46+
47+
void Unparser::printToken(const Token* t)
48+
{
49+
while (lastToken != t) {
50+
lastToken = lastToken->next;
51+
printSpecialTokens(lastToken);
52+
stringBuilder << lastToken->image;
53+
}
54+
}
55+
56+
void Unparser::printUptoToken(const Token* t)
57+
{
58+
while (lastToken->next != t) {
59+
printToken(lastToken->next);
60+
}
61+
}
62+
63+
void Unparser::moveToEndOfNode(const AstNode* node)
64+
{
65+
lastToken = node->endToken;
66+
}
67+
68+
void Unparser::unparseUpto(const AstNode* node)
69+
{
70+
printUptoToken(node->beginToken);
71+
}
72+
73+
void Unparser::unparseRestOfTheNode(const AstNode* node)
74+
{
75+
if (lastToken != node->endToken) {
76+
printUptoToken(node->endToken);
77+
}
78+
}
79+
80+
void Unparser::defaultVisit(const SimpleNode* node, void* data)
81+
{
82+
const AstNode* astNode = static_cast<const AstNode*>(node);
83+
const AstNode* firstChild = astNode->FirstChild();
84+
const AstNode* lastChild = astNode->LastChild();
85+
86+
// Print the tokens->
87+
if (firstChild == nullptr || astNode->beginToken != firstChild->beginToken) {
88+
printToken(astNode->beginToken);
89+
}
90+
91+
astNode->VisitChildren(this);
92+
93+
if (lastChild != nullptr && astNode->endToken != lastChild->endToken) {
94+
printToken(astNode->endToken);
95+
}
96+
}
97+
98+
std::string Unparser::unparse(const AstNode* node)
99+
{
100+
stringBuilder.clear();
101+
lastToken->next = node->beginToken;
102+
node->VisitNode(this);
103+
printTrailingComments();
104+
return getUnparsedString();
105+
}
106+
107+
std::string unparse(const AstNode* node, Unparser* unparser)
108+
{
109+
return unparser->unparse(node);
110+
}
111+
112+
std::string unparse(const AstNode* node)
113+
{
114+
return unparse(node, new Unparser());
115+
}
116+
117+
}
118+
}

parser/cpp/unparser.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#ifndef __UNPARSE_H__
2+
#define __UNPARSE_H__
3+
4+
#include <sstream>
5+
#include "AstNode.h"
6+
#include "SqlParserVisitor.h"
7+
8+
namespace commonsql {
9+
namespace parser {
10+
11+
using std::string;
12+
using std::stringstream;
13+
14+
class Unparser : public SqlParserDefaultVisitor {
15+
private:
16+
Token* lastToken = new Token();
17+
18+
virtual void printSpecialTokens(const Token* t);
19+
virtual void printTrailingComments();
20+
21+
protected:
22+
std::stringstream stringBuilder;
23+
24+
virtual void printToken(const std::string& s);
25+
virtual void printToken(const Token* t);
26+
virtual void printUptoToken(const Token* t);
27+
virtual void moveToEndOfNode(const AstNode* node);
28+
virtual void unparseUpto(const AstNode* node);
29+
virtual void unparseRestOfTheNode(const AstNode* node);
30+
virtual const string getUnparsedString() const { return stringBuilder.str(); }
31+
32+
public:
33+
string unparse(const AstNode* node);
34+
void defaultVisit(const SimpleNode* node, void* data);
35+
virtual ~Unparser() {}
36+
};
37+
38+
std::string unparse(const AstNode* node, Unparser* unparser);
39+
std::string unparse(const AstNode* node);
40+
41+
}
42+
}
43+
44+
#endif

parser/grammar/javacc-options-java.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ options {
1212
VISITOR = true;
1313
VISITOR_RETURN_TYPE = "void";
1414
VISITOR_DATA_TYPE = "Void";
15+
VISITOR_METHOD_NAME_INCLUDES_TYPE_NAME = true;
1516
}
1617

1718
PARSER_BEGIN(SqlParser)

0 commit comments

Comments
 (0)