Skip to content

Commit

Permalink
Clean up (#15)
Browse files Browse the repository at this point in the history
* Fix.

* Fix.

* Fix.

* Fix.

* Fix.

* Fix.

Co-authored-by: Bowen Fu <missing>
  • Loading branch information
BowenFu authored Jun 25, 2022
1 parent 081fb32 commit 9937a34
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 119 deletions.
1 change: 1 addition & 0 deletions include/hspp.h
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ constexpr auto toState = toGFunc<1>([](auto func)

constexpr auto runState = from;

// TODO: in param can be std::string const&
template <typename A, typename Repr>
class Parser : public DataHolder<Function<Repr, std::vector<std::tuple<A, std::string>>, std::string>>
{
Expand Down
83 changes: 2 additions & 81 deletions include/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,10 @@ constexpr auto manyImpl(Parser<A, Repr> p)

constexpr auto many1 = toGFunc<1> | [](auto p)
{
using data::cons;
return
p >>= [=](auto a) { return
manyImpl(p) >>= [=](auto as) { return
return_ | (a <cons> as);
return_ | (a <data::cons> as);
};
};
};
Expand All @@ -133,12 +132,11 @@ constexpr auto many = toGFunc<1> | [](auto p)

constexpr auto sepBy1 = toGFunc<2> | [](auto p, auto sep)
{
using data::cons;
return p
>>= [=](auto a) { return
(many | (sep >> p))
>>= [=](auto as) { return
return_ || a <cons> as;
return_ || a <data::cons> as;
};
};
};
Expand Down Expand Up @@ -207,83 +205,6 @@ constexpr auto apply = toGFunc<1> | [](auto p)
return runParser | (space >> p);
};

enum class Op
{
kADD,
kSUB,
kMUL,
kDIV
};

class OpFunc
{
Op mOp;
public:
constexpr OpFunc(Op op)
: mOp{op}
{}
template <typename T>
constexpr auto operator()(T x, T y) const
{
switch (mOp)
{
case Op::kADD: return x + y;
case Op::kSUB: return x - y;
case Op::kMUL: return x * y;
case Op::kDIV: return x / y;
}
throw std::runtime_error{"Never reach here!"};
}
};

namespace op
{
constexpr auto add = toGFunc<2> | OpFunc{Op::kADD};
constexpr auto sub = toGFunc<2> | OpFunc{Op::kSUB};
constexpr auto mul = toGFunc<2> | OpFunc{Op::kMUL};
constexpr auto div = toGFunc<2> | OpFunc{Op::kDIV};

static_assert((add | 1 | 2) == 3);
static_assert((sub | 1 | 2) == -1);
static_assert((mul | 1 | 2) == 2);
static_assert((div | 4 | 2) == 2);

inline auto const addOp = ((symb | "+") >> (return_ | add)) <triPlus> ((symb | "-") >> (return_ | sub));
inline auto const mulOp = ((symb | "*") >> (return_ | mul)) <triPlus> ((symb | "/") >> (return_ | div));
} // namespace op

using op::addOp;
using op::mulOp;

constexpr auto isDigit = toFunc<> | [](char x)
{
return isdigit(x);
};

inline TEParser<int> const& getExpr();

inline const auto digit = (token || sat | isDigit)
>>= [](char x) { return
return_ | (x - '0');
};

using namespace std::literals;
inline const auto factor =
digit <triPlus>
(((symb | "("s) >> getExpr()) >>= [](auto n){ return
(symb | ")"s) >>
(return_ | n);
});

inline const auto term = factor <chainl1> mulOp;

static inline const TEParser<int> expr = toTEParser || (term <chainl1> addOp);

inline TEParser<int> const& getExpr()
{
return expr;
}

} // namespace parser

} // namespace hspp
Expand Down
2 changes: 2 additions & 0 deletions include/range.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#ifndef HSPP_RANGE_H
#define HSPP_RANGE_H

#include <stdexcept>

namespace hspp
{
namespace data
Expand Down
1 change: 1 addition & 0 deletions sample/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
set(hspp_SAMPLES
parseExpr
)

foreach(sample ${hspp_SAMPLES})
Expand Down
128 changes: 128 additions & 0 deletions sample/parseExpr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#include "parser.h"
#include <cassert>

auto expectTrue(bool x)
{
if (!x)
{
throw std::runtime_error{"False in expectedTrue!"};
}
}

template <typename T>
auto expectEq(T const& l, T const& r)
{
if (l != r)
{
std::stringstream ss;
ss << l << " != " << r;
throw std::runtime_error{ss.str()};
}
}

using namespace hspp::parser;
using namespace hspp;

enum class Op
{
kADD,
kSUB,
kMUL,
kDIV
};

class OpFunc
{
Op mOp;
public:
constexpr OpFunc(Op op)
: mOp{op}
{}
template <typename T>
constexpr auto operator()(T x, T y) const
{
switch (mOp)
{
case Op::kADD: return x + y;
case Op::kSUB: return x - y;
case Op::kMUL: return x * y;
case Op::kDIV: return x / y;
}
throw std::runtime_error{"Never reach here!"};
}
};

namespace op
{
constexpr auto add = toGFunc<2> | OpFunc{Op::kADD};
constexpr auto sub = toGFunc<2> | OpFunc{Op::kSUB};
constexpr auto mul = toGFunc<2> | OpFunc{Op::kMUL};
constexpr auto div = toGFunc<2> | OpFunc{Op::kDIV};

static_assert((add | 1 | 2) == 3);
static_assert((sub | 1 | 2) == -1);
static_assert((mul | 1 | 2) == 2);
static_assert((div | 4 | 2) == 2);

auto const addOp = ((symb | "+") >> (return_ | add)) <triPlus> ((symb | "-") >> (return_ | sub));
auto const mulOp = ((symb | "*") >> (return_ | mul)) <triPlus> ((symb | "/") >> (return_ | div));
} // namespace op

using op::addOp;
using op::mulOp;

constexpr auto isDigit = toFunc<> | [](char x)
{
return isdigit(x);
};

extern TEParser<int> const expr;

auto const digit = (token || sat | isDigit)
>>= [](char x) { return
return_ | (x - '0');
};

using namespace std::literals;
auto const factor =
digit <triPlus>
(((symb | "("s) >> expr) >>= [](auto n){ return
(symb | ")"s) >>
(return_ | n);
});

auto const term = factor <chainl1> mulOp;

extern TEParser<int> const expr = toTEParser || (term <chainl1> addOp);

int main()
{
{
auto const rawResult = apply || many | digit || " 1 2 34";
auto const& result = std::get<0>(rawResult.at(0));
auto const expected = std::vector{1, 2, 3, 4};
expectTrue(std::equal(result.begin(), result.end(), expected.begin()));
}

{
auto const result = apply || addOp || " + * /-";
expectEq(std::get<0>(result.at(0))| 1 | 2, 3);

auto const result2 = apply || mulOp || " * /-";
expectEq(std::get<0>(result2.at(0))| 1 | 2, 2);
}

{
auto const p = digit <chainl1> addOp;
auto const result = runParser | p | "1 + 2";
auto const expected = 3;
expectEq(std::get<0>(result.at(0)), expected);
}

{
auto const result = apply | expr | "1 - 2 * 3 + 4";
auto const expected = -1;
expectEq(std::get<0>(result.at(0)), expected);
}
return 0;
}
38 changes: 0 additions & 38 deletions test/hspp/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1331,44 +1331,6 @@ TEST(Parser, apply)
EXPECT_EQ(std::get<0>(result.at(0)), expected);
}

TEST(Parser, ops)
{
auto const result = apply || addOp || " + * /-";
EXPECT_EQ(std::get<0>(result.at(0))| 1 | 2, 3);

auto const result2 = apply || mulOp || " * /-";
EXPECT_EQ(std::get<0>(result2.at(0))|1 | 2, 2);
}

TEST(Parser, digit)
{
auto const result = apply || many | digit || " 1 2 34";
auto const expected = std::vector{1, 2, 3, 4};
EXPECT_EQ(std::get<0>(result.at(0)), expected);
}

TEST(Parser, chainl1)
{
auto const p = digit <chainl1> addOp;
auto const result = runParser | p | "1 + 2";
auto const expected = 3;
EXPECT_EQ(std::get<0>(result.at(0)), expected);
(void)chainl;
}
TEST(Parser, factor)
{
auto const result = apply || many | digit || " 1 2 34";
auto const expected = std::vector{1, 2, 3, 4};
EXPECT_EQ(std::get<0>(result.at(0)), expected);
}

TEST(Parser, expr)
{
auto const result = apply | getExpr() | "1 - 2 * 3 + 4";
auto const expected = -1;
EXPECT_EQ(std::get<0>(result.at(0)), expected);
}

TEST(do_, x)
{
auto const result = doN::do_(
Expand Down

0 comments on commit 9937a34

Please sign in to comment.