Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/Test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: TestEarley

on:
push:
branches: [ master, LR0 ]
pull_request:
branches: [ master, LR0 ]
jobs:
Build-ubuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: "Build and run tests"
run : |
git clone https://github.com/google/googletest
cd googletest
cd googletest
cmake ..
make
sudo make install
cd ../../
cmake test
make
./TestLR
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
LR(0) Parser

In: Grammar and set of words

Out: True/False
66 changes: 66 additions & 0 deletions headers/Grammar.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <stack>

using std::cin;
using std::cout;
using std::map;
using std::set;
using std::string;
using std::vector;
using std::stack;

const string rule_separator = "->";
const string mock_non_term_str = "1";
const char mock_non_term = '1';
const set<char> alp = {'a', 'b', 'c'};

class Rule {
public:
Rule() = default;
Rule(const Rule&) = default;
Rule(const string&);

Rule& operator=(const Rule&) = default;

char GetLeft() const;
string GetRight() const;

bool operator<(const Rule&) const;
bool operator==(const Rule&) const;

private:
public:
char left_;
string right_ = "";
};

class Grammar {
public:
Grammar() = default;
Grammar(const set<char>& alphabet = alp);
Grammar(const vector<Rule>& rules);
Grammar(char start_, const vector<Rule>& rules,
const set<char>& alphabet = alp);
Grammar(const Grammar&) = default;

Grammar& operator=(const Grammar&) = default;

const vector<Rule>& GetRules() const;
const set<char>& GetAlp() const;
const set<char>& GetNonTerms() const;
void AddRule(const Rule&);
void AddLetter(char c) { alp_.insert(c); }
vector<Rule> RulesWithLeftSide(char) const;
void SetStart(char);
char GetStart() const;

private:
set<char> alp_;
set<char> nonterms_;
char start_;
vector<Rule> rules_;
};
55 changes: 55 additions & 0 deletions headers/LR0.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "Parser.hpp"

class LR0 : public Parser {
public:
LR0() = delete;
LR0(const Grammar&);

bool Recognize(const string& w, Grammar grammar) override { return true; }
bool Recognize(string& w);

~LR0() {}

private:
class Situation {
public:
Situation() = delete;
Situation(const Rule&, size_t);

bool operator==(const Situation&) const;
bool operator!=(const Situation&) const;
bool operator<(const Situation&) const;

bool Completed() const;
char GetSymbol() const;
const Rule& GetRule() const;
size_t GetDotPos() const;

private:
Rule rule_;
size_t dot_pos_;
};
class NFA {
public:
NFA() = default;
set<char> alp;
vector<set<Situation>> q;
set<size_t> term_states;
size_t start;
vector<map<char, int64_t>> delta;
};
Grammar gr_;
NFA nfa_;
vector<vector<std::pair<char, int64_t>>> tb_;
const std::pair<char, int64_t> win = { 'w', 1 };
vector<char> l_;
map<char, int64_t> num_;
void BuildTable();
void BuildNFA();

void ReBuild(const Grammar&);

set<Situation> Closure(const set<Situation>&);
set<Situation> GoTo(const set<Situation>&, char);
};

9 changes: 9 additions & 0 deletions headers/Parser.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "Grammar.hpp"

class Parser {
public:
virtual bool Recognize(const string& w, Grammar grammar) = 0;
virtual ~Parser() = default;
};

class LR0;
65 changes: 65 additions & 0 deletions src/Grammar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "../headers/Grammar.hpp"

Rule::Rule(const string& s) {
size_t sep = s.find(rule_separator);
if (sep == string::npos) {
throw std::runtime_error("Incorrect rule!");
}
auto start = s.substr(0, sep);
if (start.size() > 1 || start.size() == 0) {
throw std::runtime_error("Incorrect left side for Context-free grammar!");
}
left_ = start[0];
right_ = s.substr(sep + rule_separator.size(), s.size());
}

char Rule::GetLeft() const { return left_; }

string Rule::GetRight() const { return right_; }

bool Rule::operator<(const Rule& other) const {
if (left_ == other.left_) {
return right_ < other.right_;
}
return left_ < other.left_;
}

bool Rule::operator==(const Rule& other) const {
return !(*this < other) && !(other < *this);
}

Grammar::Grammar(const set<char>& alphabet) : alp_(alphabet) {}

Grammar::Grammar(const vector<Rule>& rules) : alp_(alp), rules_(rules) {
for (const auto& rule : rules_) {
nonterms_.insert(rule.GetLeft());
}
}

Grammar::Grammar(char start, const vector<Rule>& rules,
const set<char>& alphabet)
: Grammar(rules) {
start_ = start;
}

const vector<Rule>& Grammar::GetRules() const { return rules_; }

const set<char>& Grammar::GetAlp() const { return alp_; }

const set<char>& Grammar::GetNonTerms() const { return nonterms_; }

void Grammar::AddRule(const Rule& rule) { rules_.emplace_back(rule); }

vector<Rule> Grammar::RulesWithLeftSide(char left) const {
vector<Rule> v;
for (const Rule& rule : rules_) {
if (rule.GetLeft() == left) {
v.emplace_back(rule);
}
}
return v;
}

void Grammar::SetStart(char c) { start_ = c; }

char Grammar::GetStart() const { return start_; }
Loading