This commit is contained in:
yhirose 2020-06-01 19:47:32 -04:00
parent 072cdb6d23
commit 580721aa46
5 changed files with 29 additions and 8 deletions

View File

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title>PEG Playground - v0.1.6</title> <title>PEG Playground - v0.1.7</title>
<link rel="stylesheet" href="style.css" media="all"> <link rel="stylesheet" href="style.css" media="all">
</head> </head>
<body> <body>

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -841,7 +841,7 @@ public:
std::vector<std::shared_ptr<SemanticValues>> value_stack; std::vector<std::shared_ptr<SemanticValues>> value_stack;
size_t value_stack_size = 0; size_t value_stack_size = 0;
std::vector<Definition*> rule_stack; std::vector<Definition *> rule_stack;
std::vector<std::vector<std::shared_ptr<Ope>>> args_stack; std::vector<std::vector<std::shared_ptr<Ope>>> args_stack;
bool in_token = false; bool in_token = false;
@ -1259,7 +1259,7 @@ public:
: lit_(s), ignore_case_(ignore_case), init_is_word_(false), : lit_(s), ignore_case_(ignore_case), init_is_word_(false),
is_word_(false) {} is_word_(false) {}
LiteralString(const std::string& s, bool ignore_case) LiteralString(const std::string &s, bool ignore_case)
: lit_(s), ignore_case_(ignore_case), init_is_word_(false), : lit_(s), ignore_case_(ignore_case), init_is_word_(false),
is_word_(false) {} is_word_(false) {}
@ -1934,6 +1934,9 @@ struct HasEmptyElement : public Ope::Visitor {
} }
void visit(AndPredicate & /*ope*/) override { set_error(); } void visit(AndPredicate & /*ope*/) override { set_error(); }
void visit(NotPredicate & /*ope*/) override { set_error(); } void visit(NotPredicate & /*ope*/) override { set_error(); }
void visit(LiteralString &ope) override {
if (ope.lit_.empty()) { set_error(); }
}
void visit(CaptureScope &ope) override { ope.ope_->accept(*this); } void visit(CaptureScope &ope) override { ope.ope_->accept(*this); }
void visit(Capture &ope) override { ope.ope_->accept(*this); } void visit(Capture &ope) override { ope.ope_->accept(*this); }
void visit(TokenBoundary &ope) override { ope.ope_->accept(*this); } void visit(TokenBoundary &ope) override { ope.ope_->accept(*this); }
@ -3626,15 +3629,14 @@ ast_to_s(const std::shared_ptr<T> &ptr,
} }
struct AstOptimizer { struct AstOptimizer {
AstOptimizer(bool mode, AstOptimizer(bool mode, const std::vector<std::string> &rules = {})
const std::vector<std::string> &rules = {})
: mode_(mode), rules_(rules) {} : mode_(mode), rules_(rules) {}
template <typename T> template <typename T>
std::shared_ptr<T> optimize(std::shared_ptr<T> original, std::shared_ptr<T> optimize(std::shared_ptr<T> original,
std::shared_ptr<T> parent = nullptr) { std::shared_ptr<T> parent = nullptr) {
auto found = std::find(rules_.begin(), rules_.end(), original->name) != auto found =
rules_.end(); std::find(rules_.begin(), rules_.end(), original->name) != rules_.end();
bool opt = mode_ ? !found : found; bool opt = mode_ ? !found : found;
if (opt && original->nodes.size() == 1) { if (opt && original->nodes.size() == 1) {

View File

@ -59,6 +59,25 @@ TEST_CASE("Infinite loop 5", "[infinite loop]")
REQUIRE(!pg); REQUIRE(!pg);
} }
TEST_CASE("Infinite loop 6", "[infinite loop]")
{
parser pg(R"(
S <- ''*
)");
REQUIRE(!pg);
}
TEST_CASE("Infinite loop 7", "[infinite loop]")
{
parser pg(R"(
S <- A*
A <- ''
)");
REQUIRE(!pg);
}
TEST_CASE("Not infinite 1", "[infinite loop]") TEST_CASE("Not infinite 1", "[infinite loop]")
{ {
parser pg(R"( parser pg(R"(