TODO : Make RE Grammar template independent. Difine Unified grammar format.
This commit is contained in:
parent
53b690dad9
commit
419ebb43d1
4 changed files with 115 additions and 11 deletions
|
|
@ -1,4 +1,53 @@
|
||||||
|
|
||||||
#include "Grammar.hpp"
|
#include "Grammar.hpp"
|
||||||
|
#include "NewPlacement.hpp"
|
||||||
|
|
||||||
using namespace tp;
|
using namespace tp;
|
||||||
|
|
||||||
|
ContextFreeGrammar::Arg::Arg(const String& id, bool terminal, bool epsilon) {
|
||||||
|
mId = id;
|
||||||
|
mIsTerminal = terminal;
|
||||||
|
mIsEpsilon = epsilon;
|
||||||
|
}
|
||||||
|
|
||||||
|
const String& ContextFreeGrammar::Arg::getId() const { return mId; }
|
||||||
|
|
||||||
|
bool ContextFreeGrammar::Arg::operator==(const Arg& in) const { return (mId == in.mId) && (mIsEpsilon == in.mIsEpsilon) && (mIsTerminal == in.mIsTerminal); }
|
||||||
|
|
||||||
|
ContextFreeGrammar::Rule::Rule(const String& id, const InitialierList<Arg>& args) {
|
||||||
|
mId = id;
|
||||||
|
mArgs = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContextFreeGrammar::Rule::operator==(const Rule& in) const { return (mId == in.mId) && (mArgs == in.mArgs); }
|
||||||
|
|
||||||
|
bool ContextFreeGrammar::Rule::isProductive() const {
|
||||||
|
for (auto arg : mArgs) {
|
||||||
|
if (arg->getId() == mId) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContextFreeGrammar::NonTerminal::isProductive() const {
|
||||||
|
for (auto rule : rules) {
|
||||||
|
if (rule->isProductive()) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContextFreeGrammar::NonTerminal::isLooped(Map<String, ualni>& processed, const String& id) const {
|
||||||
|
for (auto ref : referencing) {
|
||||||
|
if (processed.presents(ref->key)) return true;
|
||||||
|
}
|
||||||
|
processed.put(id, {});
|
||||||
|
for (auto ref : referencing) {
|
||||||
|
if (ref->val->isLooped(processed, ref->key)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContextFreeGrammar::addRule(const Rule& rule) { mRules.append(rule); }
|
||||||
|
|
||||||
|
void ContextFreeGrammar::addRule(const String& id, const InitialierList<Arg>& args) { addRule(Rule(id, args)); }
|
||||||
|
|
||||||
|
void ContextFreeGrammar::setStart(const String& startRule) { mStartTerminal = startRule; }
|
||||||
|
|
@ -12,15 +12,8 @@ SimpleParser::SimpleParser() {
|
||||||
ContextFreeGrammar contextFreeGrammar;
|
ContextFreeGrammar contextFreeGrammar;
|
||||||
{
|
{
|
||||||
// use existing CF grammar interface
|
// use existing CF grammar interface
|
||||||
auto term = contextFreeGrammar.createTerminal();
|
contextFreeGrammar.addRule("a", { ContextFreeGrammar::Arg("") });
|
||||||
|
contextFreeGrammar.setStart("a");
|
||||||
auto nonTerm = contextFreeGrammar.createNonTerminal();
|
|
||||||
auto nonTerm2 = contextFreeGrammar.createNonTerminal();
|
|
||||||
|
|
||||||
contextFreeGrammar.addRule(nonTerm, { term, nonTerm2 });
|
|
||||||
contextFreeGrammar.addRule();
|
|
||||||
|
|
||||||
contextFreeGrammar.setStart(nonTerm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define Regular grammar
|
// Define Regular grammar
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,70 @@
|
||||||
|
|
||||||
#include "Buffer.hpp"
|
#include "Buffer.hpp"
|
||||||
#include "LanguageCommon.hpp"
|
#include "LanguageCommon.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Map.hpp"
|
||||||
|
#include "Strings.hpp"
|
||||||
|
|
||||||
namespace tp {
|
namespace tp {
|
||||||
|
|
||||||
class ContextFreeGrammar {};
|
class ContextFreeGrammar {
|
||||||
|
public:
|
||||||
|
struct Arg {
|
||||||
|
friend class Rule;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Arg() = default;
|
||||||
|
explicit Arg(const String& id, bool terminal = true, bool epsilon = false);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool operator==(const Arg& in) const;
|
||||||
|
[[nodiscard]] const String& getId() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
String mId;
|
||||||
|
bool mIsTerminal = false;
|
||||||
|
bool mIsEpsilon = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Rule {
|
||||||
|
public:
|
||||||
|
Rule() = default;
|
||||||
|
Rule(const String& id, const InitialierList<Arg>& args);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool operator==(const Rule& in) const;
|
||||||
|
[[nodiscard]] bool isProductive() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
String mId;
|
||||||
|
Buffer<Arg> mArgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
// cache data
|
||||||
|
struct NonTerminal {
|
||||||
|
Buffer<Rule*> rules;
|
||||||
|
Map<String, NonTerminal*> references;
|
||||||
|
Map<String, NonTerminal*> referencing;
|
||||||
|
|
||||||
|
public:
|
||||||
|
[[nodiscard]] bool isProductive() const;
|
||||||
|
[[nodiscard]] bool isLooped(Map<String, ualni>& processed, const String& id) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ContextFreeGrammar() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void addRule(const Rule& rule);
|
||||||
|
void addRule(const String& id, const InitialierList<Arg>& args);
|
||||||
|
void setStart(const String& startRule);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Map<String, NonTerminal> mNonTerminals;
|
||||||
|
Buffer<Rule> mRules;
|
||||||
|
String mStartTerminal;
|
||||||
|
bool mIsLooped = false;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename tAlphabetType, typename tTokType>
|
template <typename tAlphabetType, typename tTokType>
|
||||||
class RegularGrammar {
|
class RegularGrammar {
|
||||||
|
|
|
||||||
3
TODO
3
TODO
|
|
@ -3,6 +3,9 @@ All:
|
||||||
make more general structure for feature renders
|
make more general structure for feature renders
|
||||||
|
|
||||||
Language:
|
Language:
|
||||||
|
Grammar:
|
||||||
|
Store all RE Grammar API nodes in one buffer
|
||||||
|
|
||||||
rename Language module to FormalLanguage
|
rename Language module to FormalLanguage
|
||||||
Merge parser and tokenizer module into grammar module
|
Merge parser and tokenizer module into grammar module
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue