From b80d7cb8d52e1975058302edbe968987c1b8574f Mon Sep 17 00:00:00 2001 From: Martin Zak <zakmart1@fit.cvut.cz> Date: Sun, 17 Nov 2013 17:07:04 +0100 Subject: [PATCH] Adds LeftRegularGrammar --- alib/src/grammar/LeftRegularGrammar.cpp | 62 +++++++++++++++++++++++++ alib/src/grammar/LeftRegularGrammar.h | 24 ++++++++++ examples/grammar/leftRegular.xml | 46 ++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 alib/src/grammar/LeftRegularGrammar.cpp create mode 100644 alib/src/grammar/LeftRegularGrammar.h create mode 100644 examples/grammar/leftRegular.xml diff --git a/alib/src/grammar/LeftRegularGrammar.cpp b/alib/src/grammar/LeftRegularGrammar.cpp new file mode 100644 index 0000000000..d5e93ee179 --- /dev/null +++ b/alib/src/grammar/LeftRegularGrammar.cpp @@ -0,0 +1,62 @@ +/* + * LeftRegularGrammar.cpp + * + * Created on: Nov 17, 2013 + * Author: martin + */ + +#include "LeftRegularGrammar.h" + +namespace grammar { + +bool LeftRegularGrammar::isValidRule(const Rule& rule) const { + return checkLeftSide(rule.getLeftSide()) && checkRightSide(rule.getRightSide()); +} + +bool LeftRegularGrammar::checkLeftSide(const list<Symbol>& leftSide) const { + if (leftSide.size() != 1) { + return false; + } + + if (nonTerminalSymbols.find(leftSide.front()) == nonTerminalSymbols.end()) { + return false; + } + + return true; +} + +bool LeftRegularGrammar::checkRightSide(const list<Symbol>& rightSide) const { + if (rightSide.size() == 0) { + return true; + } else if (rightSide.size() == 1) { + const Symbol& symbol = rightSide.front(); + + //check epsilon + if (symbol.getSymbol() == "") { + return true; + } + + //check that symbol exists + return ((terminalSymbols.find(symbol) != terminalSymbols.end()) + || (nonTerminalSymbols.find(symbol) != nonTerminalSymbols.end())); + } else { + //check if first symbol is nonterminal + list<Symbol>::const_iterator symbol = rightSide.begin(); + if (nonTerminalSymbols.find(*symbol) == nonTerminalSymbols.end()) { + return false; + } + + symbol++; + + //check if following symbols are terminal + for (; symbol != rightSide.end(); symbol++) { + if (terminalSymbols.find(*symbol) == terminalSymbols.end()) { + return false; + } + } + + return true; + } +} + +} /* namespace grammar */ diff --git a/alib/src/grammar/LeftRegularGrammar.h b/alib/src/grammar/LeftRegularGrammar.h new file mode 100644 index 0000000000..37d71be653 --- /dev/null +++ b/alib/src/grammar/LeftRegularGrammar.h @@ -0,0 +1,24 @@ +/* + * LeftRegularGrammar.h + * + * Created on: Nov 17, 2013 + * Author: martin + */ + +#ifndef LEFTREGULARGRAMMAR_H_ +#define LEFTREGULARGRAMMAR_H_ + +#include "Grammar.h" + +namespace grammar { + +class LeftRegularGrammar : public Grammar { +private: + bool checkLeftSide(const list<Symbol>& leftSide) const; + bool checkRightSide(const list<Symbol>& rightSide) const; +protected: + bool isValidRule(const Rule& rule) const; +}; + +} /* namespace grammar */ +#endif /* LEFTREGULARGRAMMAR_H_ */ diff --git a/examples/grammar/leftRegular.xml b/examples/grammar/leftRegular.xml new file mode 100644 index 0000000000..f1ab4aa2e9 --- /dev/null +++ b/examples/grammar/leftRegular.xml @@ -0,0 +1,46 @@ +<grammar> + <nonTerminalSymbols> + <symbol>S</symbol> + <symbol>A</symbol> + </nonTerminalSymbols> + + <terminalSymbols> + <symbol>a</symbol> + <symbol>b</symbol> + </terminalSymbols> + + <rules> + <rule> + <leftSide> + <symbol>S</symbol> + </leftSide> + + <rightSide> + <symbol>A</symbol> + </rightSide> + </rule> + <rule> + <leftSide> + <symbol>A</symbol> + </leftSide> + + <rightSide> + <symbol>a</symbol> + </rightSide> + </rule> + <rule> + <leftSide> + <symbol>A</symbol> + </leftSide> + <rightSide> + <symbol>A</symbol> + <symbol>b</symbol> + <symbol>b</symbol> + <symbol>b</symbol> + </rightSide> + </rule> + </rules> + + <startSymbol>S</startSymbol> + +</grammar> -- GitLab