LR(1) Parser Initial
This commit is contained in:
parent
616441e049
commit
01b6f9099c
8 changed files with 161 additions and 46 deletions
26
Parser/private/CLR.cpp
Normal file
26
Parser/private/CLR.cpp
Normal 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;
|
||||
}
|
||||
|
|
@ -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
65
Parser/public/CLR.hpp
Normal 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;
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "CfGrammar.hpp"
|
||||
#include "CLR.hpp"
|
||||
|
||||
namespace tp {
|
||||
extern ModuleManifest gModuleParser;
|
||||
|
|
|
|||
10
Parser/tests/CLRTests.cpp
Normal file
10
Parser/tests/CLRTests.cpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
#include "NewPlacement.hpp"
|
||||
#include "Testing.hpp"
|
||||
#include "Parser.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
TEST_DEF(CLR) {
|
||||
TEST(false);
|
||||
}
|
||||
48
Parser/tests/GrammarTests.cpp
Normal file
48
Parser/tests/GrammarTests.cpp
Normal 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());
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue