Skip to content

Commit

Permalink
Added the beginnings of the new parser
Browse files Browse the repository at this point in the history
  • Loading branch information
iconmaster5326 committed Jun 22, 2019
1 parent 0ef3b94 commit a8414fb
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 4 deletions.
2 changes: 1 addition & 1 deletion include/ccl/gc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ namespace ccl {

}

template<typename U, typename = typename std::enable_if<std::is_convertible<U,T>::value>::type>
template<typename U, typename = typename std::enable_if<std::is_convertible<U&,T&>::value>::type>
Gc(const Gc<U>& other) : node{other.node} {
Lock lock{gcMutex};
node->refs++;
Expand Down
2 changes: 1 addition & 1 deletion include/ccl/lexer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ namespace ccl {
~Lexer();

Token next();
Token peek();
Token& peek();
bool done();
private:
const std::string& location;
Expand Down
25 changes: 25 additions & 0 deletions include/ccl/parser.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* parser.hpp
*
* Created on: Jun 22, 2019
* Author: iconmaster
*/

#ifndef INCLUDE_CCL_PARSER_HPP_
#define INCLUDE_CCL_PARSER_HPP_

#include "ccl/types.hpp"
#include "ccl/lexer.hpp"
#include "ccl/program.hpp"

namespace ccl {
Program parse(Context& ctx, Lexer& lexer);

template<typename... Args>
inline Program parse(Context& ctx, Args... args) {
Lexer lexer{args...};
return parse(ctx, lexer);
}
}

#endif /* INCLUDE_CCL_PARSER_HPP_ */
11 changes: 11 additions & 0 deletions include/ccl/program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,21 @@ namespace ccl {
virtual Object evaluate(Thread& thread, Scope& scope, Object& input) = 0;
};

CCL_DECL_GC_CLASS(ProgramNull) : public _Program {
public:
_ProgramNull(const Source& source = Source{}) : _Program(source) {}
Object evaluate(Thread& thread, Scope& scope, Object& input) override;
};

CCL_DECL_GC_CLASS(ProgramConstant) : public _Program {
public:
Object value;
_ProgramConstant(const Object& value, const Source& source = Source{}) : _Program(source), value{value} {}
Object evaluate(Thread& thread, Scope& scope, Object& input) override;
};

CCL_DECL_GC_CLASS(ProgramCall) : public _Program {
public:
struct Arg {
bool flag;
std::string key;
Expand All @@ -45,18 +53,21 @@ namespace ccl {
};

CCL_DECL_GC_CLASS(ProgramPipe) : public _Program {
public:
Program lhs, rhs;
_ProgramPipe(const Program& lhs, const Program& rhs, const Source& source = Source{}) : _Program(source), lhs{lhs}, rhs{rhs} {}
Object evaluate(Thread& thread, Scope& scope, Object& input) override;
};

CCL_DECL_GC_CLASS(ProgramSequence) : public _Program {
public:
Program lhs, rhs;
_ProgramSequence(const Program& lhs, const Program& rhs, const Source& source = Source{}) : _Program(source), lhs{lhs}, rhs{rhs} {}
Object evaluate(Thread& thread, Scope& scope, Object& input) override;
};

CCL_DECL_GC_CLASS(ProgramVar) : public _Program {
public:
std::string name;
_ProgramVar(const std::string& name, const Source& source = Source{}) : _Program(source), name{name} {}
Object evaluate(Thread& thread, Scope& scope, Object& input) override;
Expand Down
2 changes: 1 addition & 1 deletion src/lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ bool ccl::Lexer::done() {
return !peeked && (input->fail() || input->eof());
}

Token ccl::Lexer::peek() {
Token& ccl::Lexer::peek() {
if (!peeked) {
tokenPeeked = next();
peeked = true;
Expand Down
83 changes: 83 additions & 0 deletions src/parser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* parser.cpp
*
* Created on: Jun 22, 2019
* Author: iconmaster
*/

#include "ccl/parser.hpp"
#include "ccl/classes.hpp"

using namespace ccl;
using namespace std;

static void parsePostConst(Context& ctx, Lexer& lexer) {
Token& t = lexer.peek();
switch (t.type) {
case Token::Type::EX_STRING:
case Token::Type::FLAG:
case Token::Type::LBRACE:
case Token::Type::LBRACKET:
case Token::Type::LPAREN:
case Token::Type::STRING:
case Token::Type::VAR:
case Token::Type::WORD:
throw Error("Unexpected token after constant: " + t.value);
}
}

static optional<Program> parseExprPart(Context& ctx, Lexer& lexer) {
Token t = lexer.peek();
switch (t.type) {
case Token::Type::VAR: {
lexer.next();
auto p = (Program) ProgramVar(t.value, t.source);
parsePostConst(ctx, lexer);
return optional<Program>(p);
} break;
default:
return optional<Program>();
}
}

static Program parseExpr(Context& ctx, Lexer& lexer) {
auto p = parseExprPart(ctx, lexer);
bool done = false;
while (!done) {
Token t = lexer.peek();
switch (t.type) {
case Token::Type::PIPE: {
lexer.next();
if (!p) p = (Program) ProgramNull{t.source};
auto rhs = parseExprPart(ctx, lexer);
if (!rhs) rhs = (Program) ProgramNull{t.source};
p = (Program) ProgramPipe(*p, *rhs, t.source);
} break;
case Token::Type::SEMICOLON: {
lexer.next();
if (!p) p = (Program) ProgramNull{t.source};
auto rhs = parseExprPart(ctx, lexer);
if (!rhs) rhs = (Program) ProgramNull{t.source};
p = (Program) ProgramSequence(*p, *rhs, t.source);
} break;
case Token::Type::NONE:
case Token::Type::RPAREN:
case Token::Type::RBRACE: {
if (!p) p = (Program) ProgramNull{t.source};
done = true;
} break;
default:
done = true;
}
}

if (p) {
return *p;
}

throw Error("Unexpected token in expression: " + lexer.peek().value);
}

Program ccl::parse(Context& ctx, Lexer& lexer) {
return parseExpr(ctx, lexer);
}
5 changes: 5 additions & 0 deletions src/program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
using namespace std;
using namespace ccl;

Object ccl::_ProgramNull::evaluate(Thread& thread, Scope& scope, Object& input)
{
return input;
}

Object ccl::_ProgramConstant::evaluate(Thread& thread, Scope& scope, Object& input)
{
return value;
Expand Down
2 changes: 1 addition & 1 deletion test/test-lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ using namespace ccl;
static string location = "TEST LOCATION";

namespace std {
ostream& operator<<(ostream& os, const Token::Type t) {
static ostream& operator<<(ostream& os, const Token::Type t) {
os << (void*) t;
return os;
}
Expand Down
38 changes: 38 additions & 0 deletions test/test-parser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* test-parser.cpp
*
* Created on: Jun 22, 2019
* Author: iconmaster
*/

#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

#include <vector>

#include "ccl/parser.hpp"
#include "ccl/context.hpp"

using namespace std;
using namespace ccl;

static string location = "TEST LOCATION";

namespace std {
static ostream& operator<<(ostream& os, const Token::Type t) {
os << (void*) t;
return os;
}
}

BOOST_AUTO_TEST_SUITE(parser);

BOOST_AUTO_TEST_CASE(aParse) {
Context ctx;

BOOST_CHECK_NO_THROW({
Program p = parse(ctx, location, "$x | $y ; $z");
});
}

BOOST_AUTO_TEST_SUITE_END();

0 comments on commit a8414fb

Please sign in to comment.