Parsodus/include/Parsodus/grammar.h

69 lines
2.0 KiB
C++

#pragma once
#ifndef PARSODUS_GRAMMAR_H
#include "Parsodus/util/firstset.h"
#include "Parsodus/util/followset.h"
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
namespace pds {
/**
* Represents a grammar rule
* head -> tail[0] tail[1] ... tail[tail.size() - 1]
*/
struct Rule {
std::string head; ///< The replaced variable
std::vector<std::string> tail; ///< The replacement rule
bool operator<(const Rule& other) const {
if(head != other.head){
return head < other.head;
} else {
return tail < other.tail;
}
}
Rule() : head(""), tail() {}
Rule(const std::string& h, const std::vector<std::string>& t) : head(h), tail(t) {}
};
enum class PrecedenceType {
LEFT,
RIGHT,
NONASSOC
};
/**
* A context free grammar
* Keeps track of variables, terminals and replacement rules
*/
struct Grammar {
std::string start; ///< the starting variable
std::set<std::string> variables; ///< the variables
std::set<std::string> terminals; ///< the terminals
std::vector<std::shared_ptr<Rule>> rules; ///< the replacement rules
std::map<std::string, std::pair<int, PrecedenceType> > precedence; ///< lower value -> higher precedence
std::unique_ptr<util::FirstSet> first;
std::unique_ptr<util::FollowSet> follow;
Grammar() : start(""), variables(), terminals(), rules(), first(nullptr), follow(nullptr)
{}
Grammar(const Grammar& rhs)
: start(rhs.start), variables(rhs.variables), terminals(rhs.terminals)
, rules(rhs.rules), first(nullptr), follow(nullptr) {
if (rhs.first)
first = std::make_unique<util::FirstSet>(*rhs.first);
if (rhs.follow)
follow = std::make_unique<util::FollowSet>(*rhs.follow);
}
};
}
#endif //PARSODUS_GRAMMAR_H