69 lines
2.0 KiB
C++
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
|