LR(1) Parser Initial

This commit is contained in:
IlushaShurupov 2023-08-12 11:37:41 +03:00
parent 616441e049
commit 01b6f9099c
8 changed files with 161 additions and 46 deletions

26
Parser/private/CLR.cpp Normal file
View file

@ -0,0 +1,26 @@
#include "CLR.hpp"
#include "NewPlacement.hpp"
using namespace tp;
void CLR::setGrammar(const tp::CfGrammar& grammar) {
if (grammar.isLooped()) {
mState = ParserState::FAILED;
mBuildError.description = "Cant build lalr parser from looped context free grammar";
return;
}
mState = ParserState::FAILED;
}
void CLR::setTerminal(const String& name, TerminalStream::TerminalID id) {
}
void CLR::build() {
}
void CLR::parse(TerminalStream* source, List<ASTNode>& out, ASTNode** root) {
*root = nullptr;
}

View file

@ -202,4 +202,8 @@ void CfGrammar::deinitializeCfGrammarParser(CfGrammarParserState* state) {
bool CfGrammar::parse(CfGrammarParserState* context, const String& source) {
return ::parse(source.read(), &context->automata, &context->tokenizer, this);
}
}
bool CfGrammar::isLooped() const {
return mIsLooped;
}

65
Parser/public/CLR.hpp Normal file
View file

@ -0,0 +1,65 @@
#pragma once
#include "CfGrammar.hpp"
namespace tp {
class CLR {
public:
struct ASTNode {
const CfGrammar::Rule* production = nullptr;
Map<String, String> terminals;
};
class Automation {
public:
class State {
};
};
class TerminalStream {
public:
typedef ualni TerminalID;
public:
TerminalStream() = default;
virtual TerminalID getNextTerminal() = 0;
};
public:
struct BuildError {
String description;
};
struct ParseError {
const Automation::State* state = nullptr;
String::Index location = 0;
};
private:
class SententialStack {
};
public:
CLR() = default;
void setGrammar(const CfGrammar& grammar);
void setTerminal(const String& name, TerminalStream::TerminalID id);
void build();
void parse(TerminalStream* stream, List<ASTNode>& out, ASTNode** root);
[[nodiscard]] bool isBuild() { return mState == ParserState::BUILD; }
[[nodiscard]] const BuildError& getBuildError() { return mBuildError; }
[[nodiscard]] const ParseError& getParseError() { return mParseError; }
private:
enum class ParserState { NONE, BUILD, FAILED } mState = ParserState::NONE;
ParseError mParseError;
BuildError mBuildError;
SententialStack mStack;
Automation mAutomation;
};
}

View file

@ -77,6 +77,7 @@ namespace tp {
Map<String, Terminal> mTerminals;
Map<String, NonTerminal> mNonTerminals;
bool mIsLooped = false;
public:
static struct CfGrammarParserState* initializeCfGrammarParser();
@ -89,7 +90,6 @@ namespace tp {
void generateSentences(List<Sentence>& out);
static void printSentence(Sentence& in);
private:
void optimize();
[[nodiscard]] bool isLooped() const;
};
}

View file

@ -1,6 +1,6 @@
#pragma once
#include "CfGrammar.hpp"
#include "CLR.hpp"
namespace tp {
extern ModuleManifest gModuleParser;

10
Parser/tests/CLRTests.cpp Normal file
View file

@ -0,0 +1,10 @@
#include "NewPlacement.hpp"
#include "Testing.hpp"
#include "Parser.hpp"
using namespace tp;
TEST_DEF(CLR) {
TEST(false);
}

View file

@ -0,0 +1,48 @@
#include "NewPlacement.hpp"
#include "Testing.hpp"
#include "Parser.hpp"
using namespace tp;
TEST_DEF(Grammar) {
String source = R"(
Start Body
Body : [ Function ] | List | &;
List : [ LIST ];
)";
auto state = CfGrammar::initializeCfGrammarParser();
CfGrammar grammar;
if (!grammar.parse(state, source)) {
TEST(0 && "Parsing is failed\n");
CfGrammar::deinitializeCfGrammarParser(state);
return;
}
if (!grammar.compile()) {
TEST(0 && "Compilation is failed\n");
CfGrammar::deinitializeCfGrammarParser(state);
return;
}
CfGrammar::deinitializeCfGrammarParser(state);
printf("Grammar accepted.\n");
List<CfGrammar::Sentence> sentences;
grammar.generateSentences(sentences);
TEST_ASSERT(sentences.length() == 3);
TEST_ASSERT(sentences.first()->data.terms.length() == 1);
TEST_ASSERT(sentences.last()->data.terms.length() == 1);
TEST(sentences.first()->data.terms.first()->data.id == "Function");
TEST(sentences.last()->data.terms.first()->data.id == "LIST");
printf("Example sentences formed from grammar: \n");
for (auto sentence : sentences) tp::CfGrammar::printSentence(sentence.data());
}

View file

@ -5,47 +5,8 @@
using namespace tp;
TEST_DEF(Simple) {
String source = R"(
Start Body
Body : [ Function ] | List | &;
List : [ LIST ];
)";
auto state = CfGrammar::initializeCfGrammarParser();
CfGrammar grammar;
if (!grammar.parse(state, source)) {
TEST(0 && "Parsing is failed\n");
CfGrammar::deinitializeCfGrammarParser(state);
return;
}
if (!grammar.compile()) {
TEST(0 && "Compilation is failed\n");
CfGrammar::deinitializeCfGrammarParser(state);
return;
}
CfGrammar::deinitializeCfGrammarParser(state);
printf("Grammar accepted.\n");
List<CfGrammar::Sentence> sentences;
grammar.generateSentences(sentences);
TEST_ASSERT(sentences.length() == 3);
TEST_ASSERT(sentences.first()->data.terms.length() == 1);
TEST_ASSERT(sentences.last()->data.terms.length() == 1);
TEST(sentences.first()->data.terms.first()->data.id == "Function");
TEST(sentences.last()->data.terms.first()->data.id == "LIST");
printf("Example sentences formed from grammar: \n");
for (auto sentence : sentences) tp::CfGrammar::printSentence(sentence.data());
}
void testGrammar();
void testCLR();
int main(int argc, const char* argv[]) {
tp::ModuleManifest* deps[] = { &tp::gModuleParser, nullptr };
@ -55,7 +16,8 @@ int main(int argc, const char* argv[]) {
return 1;
}
testSimple();
testGrammar();
testCLR();
testModule.deinitialize();
return 0;