Start of new ANTLR4 based parser.
Very simple tests pass.
This commit is contained in:
parent
03b4194193
commit
fbbe832a05
44 changed files with 860 additions and 8 deletions
83
pglablib/CaseChangingCharStream.h
Normal file
83
pglablib/CaseChangingCharStream.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include "antlr4-runtime.h"
|
||||
#include <QChar>
|
||||
|
||||
/// Helper stream for antlr, the lexer does not need to base case sensitive
|
||||
/// this is achieved by changing the case of the chars in LA how ever
|
||||
/// when the text of a recognized token is captured the getText function
|
||||
/// is used which does no case conversion so the parse will receive the original
|
||||
/// case.
|
||||
class CaseChangingCharStream: public antlr4::CharStream
|
||||
{
|
||||
public:
|
||||
CaseChangingCharStream(antlr4::CharStream *stream, bool upper)
|
||||
: stream(stream)
|
||||
, upper(upper)
|
||||
{}
|
||||
|
||||
virtual ~CaseChangingCharStream()
|
||||
{}
|
||||
|
||||
virtual void consume() override
|
||||
{
|
||||
stream->consume();
|
||||
}
|
||||
|
||||
virtual size_t LA(ssize_t i) override
|
||||
{
|
||||
int c = stream->LA(i);
|
||||
if (c <= 0)
|
||||
return c;
|
||||
|
||||
if (upper)
|
||||
return QChar::toUpper(c);
|
||||
|
||||
return QChar::toLower(c);
|
||||
}
|
||||
|
||||
virtual std::string getText(const antlr4::misc::Interval &interval) override
|
||||
{
|
||||
return stream->getText(interval);
|
||||
}
|
||||
|
||||
virtual std::string toString() const override
|
||||
{
|
||||
return stream->toString();
|
||||
}
|
||||
|
||||
virtual ssize_t mark() override
|
||||
{
|
||||
return stream->mark();
|
||||
}
|
||||
|
||||
virtual void release(ssize_t marker) override
|
||||
{
|
||||
stream->release(marker);
|
||||
}
|
||||
|
||||
virtual size_t index() override
|
||||
{
|
||||
return stream->index();
|
||||
}
|
||||
|
||||
virtual void seek(size_t index) override
|
||||
{
|
||||
stream->seek(index);
|
||||
}
|
||||
|
||||
virtual size_t size() override
|
||||
{
|
||||
return stream->size();
|
||||
}
|
||||
|
||||
virtual std::string getSourceName() const override
|
||||
{
|
||||
return stream->getSourceName();
|
||||
}
|
||||
|
||||
private:
|
||||
antlr4::CharStream *stream;
|
||||
bool upper;
|
||||
|
||||
};
|
||||
|
|
@ -36,6 +36,7 @@ class ConnectionConfig;
|
|||
class ConnectionNode {
|
||||
public:
|
||||
virtual ~ConnectionNode() = default;
|
||||
|
||||
};
|
||||
|
||||
class ConnectionGroup: public ConnectionNode {
|
||||
|
|
@ -115,7 +116,10 @@ public:
|
|||
bool dirty() const;
|
||||
void clean();
|
||||
|
||||
bool operator==(QUuid id) const { return m_uuid == id; }
|
||||
bool operator==(const ConnectionConfig &rhs) const
|
||||
{
|
||||
return m_uuid == rhs.m_uuid;
|
||||
}
|
||||
|
||||
QString makeLongDescription() const;
|
||||
QByteArray encodedPassword() const;
|
||||
|
|
|
|||
31
pglablib/PgsqlLexer.g4
Normal file
31
pglablib/PgsqlLexer.g4
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
lexer grammar PgsqlLexer;
|
||||
|
||||
@lexer::preinclude {
|
||||
#include <memory>
|
||||
}
|
||||
|
||||
|
||||
SemiColon: ';';
|
||||
Comma: ',';
|
||||
Dot: '.';
|
||||
OpenParen: '(';
|
||||
CloseParen: ')';
|
||||
|
||||
As: 'AS';
|
||||
By: 'BY';
|
||||
From: 'FROM';
|
||||
Full: 'FULL';
|
||||
Group: 'GROUP';
|
||||
Having: 'HAVING';
|
||||
Join: 'JOIN';
|
||||
Left : 'LEFT';
|
||||
Order : 'ORDER';
|
||||
Right : 'RIGHT';
|
||||
Select: 'SELECT';
|
||||
Where: 'WHERE';
|
||||
|
||||
Ident: [A-Za-z_][A-Za-z_0-9]* ; // match lower-case identifiers
|
||||
IntegerLiteral: [1-9][0-9]*;
|
||||
StringLiteral: '\'' ('\'\'' | ~ ('\''))* '\'' { setText(getText().substr(1, getText().length()-2)); };
|
||||
|
||||
Whitespace : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
|
||||
101
pglablib/PgsqlParser.g4
Normal file
101
pglablib/PgsqlParser.g4
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// Define a grammar called postgresql
|
||||
parser grammar PgsqlParser;
|
||||
|
||||
options {
|
||||
tokenVocab = PgsqlLexer;
|
||||
}
|
||||
|
||||
@parser::preinclude {
|
||||
#include "sqlast/sqlast.h"
|
||||
}
|
||||
|
||||
@parser::includes {
|
||||
}
|
||||
|
||||
@parser::members {
|
||||
}
|
||||
|
||||
main returns [std::unique_ptr<sqlast::StatementList> program]
|
||||
: statement_list { $program = std::move($statement_list.result); }
|
||||
;
|
||||
|
||||
statement_list returns [std::unique_ptr<sqlast::StatementList> result]
|
||||
: { $result = std::make_unique<sqlast::StatementList>(); }
|
||||
(statement SemiColon { $result->Add(std::move($statement.result)); } | empty_statement)*
|
||||
(statement SemiColon? { $result->Add(std::move($statement.result)); } | empty_statement )
|
||||
;
|
||||
|
||||
statement returns [std::unique_ptr<sqlast::Statement> result]
|
||||
: select_stmt { $result = std::move($select_stmt.result); }
|
||||
;
|
||||
|
||||
empty_statement
|
||||
: SemiColon
|
||||
;
|
||||
|
||||
select_stmt returns [std::unique_ptr<sqlast::SelectStatement> result]
|
||||
: Select select_list
|
||||
{
|
||||
$result = std::make_unique<sqlast::SelectStatement>();
|
||||
$result->SetSelectList(std::move($select_list.result));
|
||||
}
|
||||
(From from_item (Comma from_item)* )?
|
||||
(Where condition)?
|
||||
(Group By group_by)?
|
||||
(Order By order_by)?
|
||||
(Having having)?
|
||||
;
|
||||
|
||||
from_item
|
||||
: Ident Dot Ident from_alias?
|
||||
| Ident from_alias?
|
||||
| OpenParen select_stmt CloseParen from_alias
|
||||
;
|
||||
|
||||
from_alias
|
||||
: As? Ident (OpenParen Ident (Comma Ident)* CloseParen)?
|
||||
;
|
||||
|
||||
condition
|
||||
: expr
|
||||
;
|
||||
|
||||
group_by
|
||||
:
|
||||
;
|
||||
|
||||
order_by
|
||||
:
|
||||
;
|
||||
|
||||
having
|
||||
:
|
||||
;
|
||||
|
||||
|
||||
select_list returns [std::unique_ptr<sqlast::SelectList> result]
|
||||
: select_item
|
||||
{
|
||||
$result = std::make_unique<sqlast::SelectList>();
|
||||
$result->Add(std::move($select_item.result));
|
||||
}
|
||||
(Comma select_item)* { $result->Add(std::move($select_item.result)); }
|
||||
|
|
||||
;
|
||||
|
||||
select_item returns [std::unique_ptr<sqlast::SelectItem> result]
|
||||
: expr { $result = std::make_unique<sqlast::SelectItem>(std::move($expr.result)); }
|
||||
(As? Ident { $result->SetAlias($Ident.text); })?
|
||||
;
|
||||
|
||||
expr returns [std::unique_ptr<sqlast::Expression> result]
|
||||
: expr Dot Ident
|
||||
| Ident
|
||||
| value { $result = std::move($value.result); }
|
||||
;
|
||||
|
||||
value returns [std::unique_ptr<sqlast::Literal> result]
|
||||
: IntegerLiteral
|
||||
| StringLiteral { $result = std::make_unique<sqlast::StringLiteral>($StringLiteral.text); }
|
||||
;
|
||||
|
||||
1
pglablib/build-cpp.bat
Normal file
1
pglablib/build-cpp.bat
Normal file
|
|
@ -0,0 +1 @@
|
|||
java -Xmx500M -cp "c:\prog\antlr\antlr-4.9.2-complete.jar;%CLASSPATH%" org.antlr.v4.Tool -Dlanguage=Cpp PgsqlLexer.g4 PgsqlParser.g4 -o sqlparser/.generated -no-listener %2 %3 %4 %5 %6 %7
|
||||
|
|
@ -4,11 +4,11 @@
|
|||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += widgets core
|
||||
QT += widgets core concurrent
|
||||
|
||||
TARGET = pglablib
|
||||
TEMPLATE = lib
|
||||
CONFIG += staticlib
|
||||
CONFIG += staticlib no_keywords
|
||||
|
||||
! include( ../common.pri ) {
|
||||
error( "Couldn't find the common.pri file!" )
|
||||
|
|
@ -45,6 +45,23 @@ SOURCES += \
|
|||
catalog/PgConstraintContainer.cpp \
|
||||
ParamListJson.cpp \
|
||||
ParamListModel.cpp \
|
||||
sqlast/ColumnDefinition.cpp \
|
||||
sqlast/CreateTable.cpp \
|
||||
sqlast/Expression.cpp \
|
||||
sqlast/Literal.cpp \
|
||||
sqlast/Node.cpp \
|
||||
sqlast/SelectItem.cpp \
|
||||
sqlast/SelectList.cpp \
|
||||
sqlast/SelectStatement.cpp \
|
||||
sqlast/Statement.cpp \
|
||||
sqlast/StatementList.cpp \
|
||||
sqlast/StringLiteral.cpp \
|
||||
sqlast/TypeSpecification.cpp \
|
||||
sqlast/Visitor.cpp \
|
||||
sqlparser/.generated/PgsqlLexer.cpp \
|
||||
sqlparser/.generated/PgsqlParser.cpp \
|
||||
sqlparser/ErrorListener.cpp \
|
||||
sqlparser/Parser.cpp \
|
||||
util.cpp \
|
||||
SqlFormattingUtils.cpp \
|
||||
catalog/PgKeywordList.cpp \
|
||||
|
|
@ -87,6 +104,7 @@ SOURCES += \
|
|||
catalog/PgSequenceContainer.cpp
|
||||
|
||||
HEADERS += \
|
||||
CaseChangingCharStream.h \
|
||||
Pglablib.h \
|
||||
ASyncDBConnection.h \
|
||||
ConnectionConfig.h \
|
||||
|
|
@ -113,6 +131,24 @@ HEADERS += \
|
|||
catalog/PgConstraintContainer.h \
|
||||
ParamListJson.h \
|
||||
ParamListModel.h \
|
||||
sqlast/ColumnDefinition.h \
|
||||
sqlast/CreateTable.h \
|
||||
sqlast/Expression.h \
|
||||
sqlast/Literal.h \
|
||||
sqlast/Node.h \
|
||||
sqlast/SelectItem.h \
|
||||
sqlast/SelectList.h \
|
||||
sqlast/SelectStatement.h \
|
||||
sqlast/Statement.h \
|
||||
sqlast/StatementList.h \
|
||||
sqlast/StringLiteral.h \
|
||||
sqlast/TypeSpecification.h \
|
||||
sqlast/Visitor.h \
|
||||
sqlast/sqlast.h \
|
||||
sqlparser/.generated/PgsqlLexer.h \
|
||||
sqlparser/.generated/PgsqlParser.h \
|
||||
sqlparser/ErrorListener.h \
|
||||
sqlparser/Parser.h \
|
||||
util.h \
|
||||
SqlFormattingUtils.h \
|
||||
catalog/PgCatalogTypes.h \
|
||||
|
|
@ -170,6 +206,10 @@ else:unix:!macx: LIBS += -L$$OUT_PWD/../core/ -lcore
|
|||
INCLUDEPATH += $$PWD/../core
|
||||
DEPENDPATH += $$PWD/../core
|
||||
|
||||
INCLUDEPATH += C:\Prog\include\antlr
|
||||
win32:CONFIG(debug, debug|release): LIBS += -lantlr4-runtimed
|
||||
else:win32:CONFIG(release, debug|release): LIBS += -lantlr4-runtime
|
||||
|
||||
win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/libcore.a
|
||||
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/libcore.a
|
||||
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/core.lib
|
||||
|
|
|
|||
9
pglablib/sqlast/ColumnDefinition.cpp
Normal file
9
pglablib/sqlast/ColumnDefinition.cpp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#include "ColumnDefinition.h"
|
||||
#include "TypeSpecification.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
ColumnDefinition::ColumnDefinition()
|
||||
{
|
||||
|
||||
}
|
||||
28
pglablib/sqlast/ColumnDefinition.h
Normal file
28
pglablib/sqlast/ColumnDefinition.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include "Node.h"
|
||||
#include <QString>
|
||||
#include <memory>
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class TypeSpecification;
|
||||
|
||||
/// Defines the details of a table column
|
||||
///
|
||||
/// Constraints are not included here, as we handle constraints can apply to multiple columns
|
||||
/// and we want to put them all in one place. The UI and SQL generator is allowed to display
|
||||
/// column specific constraints with the column they belong to.
|
||||
class ColumnDefinition : public Node
|
||||
{
|
||||
public:
|
||||
ColumnDefinition();
|
||||
|
||||
private:
|
||||
QString name;
|
||||
std::unique_ptr<TypeSpecification> typeName;
|
||||
bool notNull = true;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
8
pglablib/sqlast/CreateTable.cpp
Normal file
8
pglablib/sqlast/CreateTable.cpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "CreateTable.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
CreateTable::CreateTable()
|
||||
{
|
||||
|
||||
}
|
||||
21
pglablib/sqlast/CreateTable.h
Normal file
21
pglablib/sqlast/CreateTable.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "Statement.h"
|
||||
#include <memory>
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class ColumnDefinition;
|
||||
class TableConstraint;
|
||||
|
||||
class CreateTable: public Statement
|
||||
{
|
||||
public:
|
||||
CreateTable();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
8
pglablib/sqlast/Expression.cpp
Normal file
8
pglablib/sqlast/Expression.cpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "Expression.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
Expression::Expression()
|
||||
{
|
||||
|
||||
}
|
||||
13
pglablib/sqlast/Expression.h
Normal file
13
pglablib/sqlast/Expression.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "Node.h"
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class Expression: public Node
|
||||
{
|
||||
public:
|
||||
Expression();
|
||||
};
|
||||
|
||||
}
|
||||
8
pglablib/sqlast/Literal.cpp
Normal file
8
pglablib/sqlast/Literal.cpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "Literal.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
Literal::Literal()
|
||||
{
|
||||
|
||||
}
|
||||
13
pglablib/sqlast/Literal.h
Normal file
13
pglablib/sqlast/Literal.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "Expression.h"
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class Literal: public Expression
|
||||
{
|
||||
public:
|
||||
Literal();
|
||||
};
|
||||
|
||||
}
|
||||
8
pglablib/sqlast/Node.cpp
Normal file
8
pglablib/sqlast/Node.cpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "Node.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
Node::Node()
|
||||
{
|
||||
|
||||
}
|
||||
24
pglablib/sqlast/Node.h
Normal file
24
pglablib/sqlast/Node.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class Node {
|
||||
public:
|
||||
Node();
|
||||
virtual ~Node() = default;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
/*
|
||||
|
||||
- Node
|
||||
- INSERT
|
||||
- UPDATE
|
||||
- DELETE
|
||||
- SELECT
|
||||
- WITH
|
||||
- CTE
|
||||
|
||||
|
||||
*/
|
||||
13
pglablib/sqlast/SelectItem.cpp
Normal file
13
pglablib/sqlast/SelectItem.cpp
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#include "SelectItem.h"
|
||||
#include "Expression.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
SelectItem::SelectItem(std::unique_ptr<sqlast::Expression> expr)
|
||||
: expression(std::move(expr))
|
||||
{}
|
||||
|
||||
void SelectItem::SetAlias(const std::string &alias)
|
||||
{
|
||||
this->alias = alias;
|
||||
}
|
||||
25
pglablib/sqlast/SelectItem.h
Normal file
25
pglablib/sqlast/SelectItem.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include "Node.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class Expression;
|
||||
|
||||
class SelectItem : public Node
|
||||
{
|
||||
public:
|
||||
explicit SelectItem(std::unique_ptr<sqlast::Expression> expr);
|
||||
|
||||
Expression& GetExpression() { return *expression; }
|
||||
|
||||
void SetAlias(const std::string &alias);
|
||||
std::string GetAlias() const { return alias; }
|
||||
private:
|
||||
std::unique_ptr<Expression> expression;
|
||||
std::string alias;
|
||||
};
|
||||
|
||||
}
|
||||
18
pglablib/sqlast/SelectList.cpp
Normal file
18
pglablib/sqlast/SelectList.cpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#include "SelectList.h"
|
||||
#include "SelectItem.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
SelectList::SelectList()
|
||||
{
|
||||
}
|
||||
|
||||
void SelectList::Add(std::unique_ptr<SelectItem> select_item)
|
||||
{
|
||||
list.push_back(std::move(select_item));
|
||||
}
|
||||
|
||||
int SelectList::Count() const
|
||||
{
|
||||
return static_cast<int>(list.size());
|
||||
}
|
||||
29
pglablib/sqlast/SelectList.h
Normal file
29
pglablib/sqlast/SelectList.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include "Node.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class SelectItem;
|
||||
|
||||
class SelectList : public Node
|
||||
{
|
||||
public:
|
||||
SelectList();
|
||||
|
||||
void Add(std::unique_ptr<SelectItem> select_item);
|
||||
int Count() const;
|
||||
|
||||
SelectItem& Get(int index)
|
||||
{
|
||||
return *list.at(index);
|
||||
}
|
||||
private:
|
||||
using List = std::vector<std::unique_ptr<SelectItem>>;
|
||||
|
||||
List list;
|
||||
};
|
||||
|
||||
}
|
||||
19
pglablib/sqlast/SelectStatement.cpp
Normal file
19
pglablib/sqlast/SelectStatement.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "SelectStatement.h"
|
||||
#include "SelectList.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
SelectStatement::SelectStatement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SelectList* SelectStatement::GetSelectList()
|
||||
{
|
||||
return selectList.get();
|
||||
}
|
||||
|
||||
void SelectStatement::SetSelectList(std::unique_ptr<SelectList> value)
|
||||
{
|
||||
selectList = std::move(value);
|
||||
}
|
||||
22
pglablib/sqlast/SelectStatement.h
Normal file
22
pglablib/sqlast/SelectStatement.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include "Statement.h"
|
||||
#include <memory>
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class SelectList;
|
||||
|
||||
class SelectStatement: public Statement
|
||||
{
|
||||
public:
|
||||
SelectStatement();
|
||||
|
||||
SelectList* GetSelectList();
|
||||
void SetSelectList(std::unique_ptr<SelectList> value);
|
||||
|
||||
private:
|
||||
std::unique_ptr<SelectList> selectList;
|
||||
};
|
||||
|
||||
}
|
||||
10
pglablib/sqlast/Statement.cpp
Normal file
10
pglablib/sqlast/Statement.cpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#include "Statement.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
Statement::Statement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
13
pglablib/sqlast/Statement.h
Normal file
13
pglablib/sqlast/Statement.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "Node.h"
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class Statement: public Node
|
||||
{
|
||||
public:
|
||||
Statement();
|
||||
};
|
||||
|
||||
}
|
||||
24
pglablib/sqlast/StatementList.cpp
Normal file
24
pglablib/sqlast/StatementList.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include "StatementList.h"
|
||||
#include "Statement.h"
|
||||
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
StatementList::StatementList()
|
||||
{}
|
||||
|
||||
void StatementList::Add(std::unique_ptr<Statement> &&statement)
|
||||
{
|
||||
statements.push_back(std::move(statement));
|
||||
}
|
||||
|
||||
Statement &StatementList::Get(int index)
|
||||
{
|
||||
return *statements[index];
|
||||
}
|
||||
|
||||
int StatementList::Count() const
|
||||
{
|
||||
return static_cast<int>(statements.size());
|
||||
}
|
||||
|
||||
27
pglablib/sqlast/StatementList.h
Normal file
27
pglablib/sqlast/StatementList.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "Node.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class Statement;
|
||||
|
||||
class StatementList: public Node
|
||||
{
|
||||
public:
|
||||
StatementList();
|
||||
|
||||
void Add(std::unique_ptr<Statement> &&statement);
|
||||
Statement &Get(int index);
|
||||
int Count() const;
|
||||
|
||||
private:
|
||||
using Statements = std::vector<std::unique_ptr<Statement>>;
|
||||
|
||||
Statements statements;
|
||||
};
|
||||
|
||||
}
|
||||
7
pglablib/sqlast/StringLiteral.cpp
Normal file
7
pglablib/sqlast/StringLiteral.cpp
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include "StringLiteral.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
StringLiteral::StringLiteral(const std::string s)
|
||||
: value(QString::fromStdString(s))
|
||||
{}
|
||||
19
pglablib/sqlast/StringLiteral.h
Normal file
19
pglablib/sqlast/StringLiteral.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "Literal.h"
|
||||
#include <QString>
|
||||
#include <string>
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class StringLiteral : public Literal
|
||||
{
|
||||
public:
|
||||
explicit StringLiteral(const std::string s);
|
||||
|
||||
QString GetValue() const { return value; }
|
||||
private:
|
||||
QString value;
|
||||
};
|
||||
|
||||
}
|
||||
8
pglablib/sqlast/TypeSpecification.cpp
Normal file
8
pglablib/sqlast/TypeSpecification.cpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "TypeSpecification.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
TypeSpecification::TypeSpecification()
|
||||
{
|
||||
|
||||
}
|
||||
23
pglablib/sqlast/TypeSpecification.h
Normal file
23
pglablib/sqlast/TypeSpecification.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include "Node.h"
|
||||
#include <QString>
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
/// These object define not only the base type, but also
|
||||
/// parameters used with the type
|
||||
/// Think the precision of numeric, max length of char, array
|
||||
class TypeSpecification : public Node
|
||||
{
|
||||
public:
|
||||
TypeSpecification();
|
||||
|
||||
private:
|
||||
/// We do not use the PgType from the catalog here as the type used might be defined
|
||||
/// inside the script and not present yet in the catalog.
|
||||
QString baseType;
|
||||
// is_array
|
||||
};
|
||||
|
||||
}
|
||||
8
pglablib/sqlast/Visitor.cpp
Normal file
8
pglablib/sqlast/Visitor.cpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "Visitor.h"
|
||||
|
||||
using namespace sqlast;
|
||||
|
||||
Visitor::Visitor()
|
||||
{
|
||||
|
||||
}
|
||||
13
pglablib/sqlast/Visitor.h
Normal file
13
pglablib/sqlast/Visitor.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
namespace sqlast {
|
||||
|
||||
class Visitor
|
||||
{
|
||||
public:
|
||||
Visitor();
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
12
pglablib/sqlast/sqlast.h
Normal file
12
pglablib/sqlast/sqlast.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "Node.h"
|
||||
#include "SelectStatement.h"
|
||||
#include "SelectItem.h"
|
||||
#include "SelectList.h"
|
||||
#include "Statement.h"
|
||||
#include "StatementList.h"
|
||||
#include "StringLiteral.h"
|
||||
#undef emit
|
||||
|
||||
|
||||
22
pglablib/sqlparser/ErrorListener.cpp
Normal file
22
pglablib/sqlparser/ErrorListener.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include "ErrorListener.h"
|
||||
|
||||
|
||||
void ErrorListener::syntaxError(antlr4::Recognizer *recognizer, antlr4::Token *offendingSymbol, size_t line, size_t charPositionInLine, const std::string &msg, std::exception_ptr e)
|
||||
{
|
||||
++errors;
|
||||
}
|
||||
|
||||
void ErrorListener::reportAmbiguity(antlr4::Parser *recognizer, const antlr4::dfa::DFA &dfa, size_t startIndex, size_t stopIndex, bool exact, const antlrcpp::BitSet &ambigAlts, antlr4::atn::ATNConfigSet *configs)
|
||||
{
|
||||
++errors;
|
||||
}
|
||||
|
||||
void ErrorListener::reportAttemptingFullContext(antlr4::Parser *recognizer, const antlr4::dfa::DFA &dfa, size_t startIndex, size_t stopIndex, const antlrcpp::BitSet &conflictingAlts, antlr4::atn::ATNConfigSet *configs)
|
||||
{
|
||||
++errors;
|
||||
}
|
||||
|
||||
void ErrorListener::reportContextSensitivity(antlr4::Parser *recognizer, const antlr4::dfa::DFA &dfa, size_t startIndex, size_t stopIndex, size_t prediction, antlr4::atn::ATNConfigSet *configs)
|
||||
{
|
||||
++errors;
|
||||
}
|
||||
21
pglablib/sqlparser/ErrorListener.h
Normal file
21
pglablib/sqlparser/ErrorListener.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
#include "antlr4-runtime.h"
|
||||
|
||||
class ErrorListener : public antlr4::ANTLRErrorListener
|
||||
{
|
||||
// ANTLRErrorListener interface
|
||||
public:
|
||||
virtual void syntaxError(antlr4::Recognizer *recognizer, antlr4::Token *offendingSymbol, size_t line, size_t charPositionInLine, const std::string &msg, std::exception_ptr e) override;
|
||||
virtual void reportAmbiguity(antlr4::Parser *recognizer, const antlr4::dfa::DFA &dfa, size_t startIndex, size_t stopIndex, bool exact, const antlrcpp::BitSet &ambigAlts, antlr4::atn::ATNConfigSet *configs) override;
|
||||
virtual void reportAttemptingFullContext(antlr4::Parser *recognizer, const antlr4::dfa::DFA &dfa, size_t startIndex, size_t stopIndex, const antlrcpp::BitSet &conflictingAlts, antlr4::atn::ATNConfigSet *configs) override;
|
||||
virtual void reportContextSensitivity(antlr4::Parser *recognizer, const antlr4::dfa::DFA &dfa, size_t startIndex, size_t stopIndex, size_t prediction, antlr4::atn::ATNConfigSet *configs) override;
|
||||
|
||||
public:
|
||||
int errorCount() const
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
|
||||
private:
|
||||
int errors = 0;
|
||||
};
|
||||
21
pglablib/sqlparser/Parser.cpp
Normal file
21
pglablib/sqlparser/Parser.cpp
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#include "Parser.h"
|
||||
#include "antlr4-runtime.h"
|
||||
|
||||
|
||||
Parser::Parser(const std::string &input_string)
|
||||
: InputStream(std::make_unique<antlr4::ANTLRInputStream>(input_string))
|
||||
, CaseFilter(InputStream.get(), true)
|
||||
, Lexer(&CaseFilter)
|
||||
, TokenStream(&Lexer)
|
||||
, AParser(&TokenStream)
|
||||
{
|
||||
AParser.removeErrorListeners();
|
||||
AParser.addErrorListener(&Errors);
|
||||
}
|
||||
|
||||
std::unique_ptr<sqlast::StatementList> Parser::Parse()
|
||||
{
|
||||
auto context = AParser.main();
|
||||
return std::move(context->program);
|
||||
}
|
||||
|
||||
27
pglablib/sqlparser/Parser.h
Normal file
27
pglablib/sqlparser/Parser.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include ".generated/PgsqlLexer.h"
|
||||
#include ".generated/PgsqlParser.h"
|
||||
#include "CaseChangingCharStream.h"
|
||||
#include "ErrorListener.h"
|
||||
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
Parser(const std::string &input_string);
|
||||
|
||||
std::unique_ptr<sqlast::StatementList> Parse();
|
||||
|
||||
int errorCount() const
|
||||
{
|
||||
return Errors.errorCount();
|
||||
}
|
||||
private:
|
||||
std::unique_ptr<antlr4::CharStream> InputStream;
|
||||
CaseChangingCharStream CaseFilter;
|
||||
PgsqlLexer Lexer;
|
||||
antlr4::CommonTokenStream TokenStream;
|
||||
PgsqlParser AParser;
|
||||
ErrorListener Errors;
|
||||
};
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ QString msfloatToHumanReadableString(float ms)
|
|||
if (ms < 1.0f) {
|
||||
val = ms * 1000.f;
|
||||
//result = QString::asprintf("%0.3f", ms * 1000.0f);
|
||||
unit = u8"μs";
|
||||
unit = QString::fromUtf8("μs");
|
||||
}
|
||||
else if (ms >= 1000.0) {
|
||||
val = ms / 1000.0f;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue