Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
GraphParser.cpp 6.44 KiB
#include "aidge/graphRegex/GraphParser.hpp"

using namespace Aidge; 

GraphParser::GraphParser(const std::string gRegexExpressions):
mLexer(gRegexExpressions)
{
    mCurrentToken = mLexer.getNextToken();
}


const std::string GraphParser::getQuery(){
    return mLexer.getQuery();
}

std::shared_ptr<AstNode<gRegexTokenTypes>> GraphParser::parse(void){

    std::shared_ptr<AstNode<gRegexTokenTypes>> astTree = constructAstAllExpr();
    rstParser();
    return astTree;
}


void GraphParser::rstParser(void){
    mLexer.rstPosition();
    mCurrentToken = mLexer.getNextToken();
}


void GraphParser::ackToken(gRegexTokenTypes  tokenType){
    
    if(mCurrentToken->getType() == tokenType ){
        try {
            mCurrentToken = mLexer.getNextToken();
        } catch (const std::runtime_error& e) {
            std::ostringstream errorMessage;
            errorMessage << "Graph Lexer error in Parser :\n"<< e.what() << std::endl;
            throw std::runtime_error(errorMessage.str());
        }
    }else{
        std::ostringstream errorMessage;
        errorMessage << "Bad syntax GraphParser " << static_cast<int>(mCurrentToken->getType())  <<"!="<< static_cast<int>(tokenType) << "\n";
        errorMessage << mLexer.rep();
        throw std::runtime_error(errorMessage.str());
    }
}

/*
exp : KEY(QOM | QZM)?  | CKEY | domain
*/
std::shared_ptr<AstNode<gRegexTokenTypes>> GraphParser::constructAstExp(void)
{

    try{
        std::shared_ptr<ParsingToken<gRegexTokenTypes>> token = mCurrentToken->copy();
        std::shared_ptr<AstNode<gRegexTokenTypes>> node = std::make_shared<AstNode<gRegexTokenTypes>>(token);

        if (mCurrentToken->getType() == gRegexTokenTypes::KEY  ){
            ackToken(gRegexTokenTypes::KEY );
            if (mCurrentToken->getType() == gRegexTokenTypes::QOM  ){
                token = mCurrentToken->copy();
                ackToken(gRegexTokenTypes::QOM );
                std::shared_ptr<AstNode<gRegexTokenTypes>> newNode = std::make_shared<AstNode<gRegexTokenTypes>>(token,
                std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{node});
                return newNode;
            }else if (mCurrentToken->getType() == gRegexTokenTypes::QZM  ){
                token = mCurrentToken->copy();
                ackToken(gRegexTokenTypes::QZM );
                std::shared_ptr<AstNode<gRegexTokenTypes>> newNode = std::make_shared<AstNode<gRegexTokenTypes>>(token,
                std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{node});
                return newNode;
            }
            return node;
        }else if (mCurrentToken->getType() == gRegexTokenTypes::CKEY){
            ackToken(gRegexTokenTypes::CKEY );
            return node;
        }else{
            return constructAstDomain();
        }

    } catch (const std::runtime_error& e) {
        std::ostringstream errorMessage;
        errorMessage << "GraphParser constructAstExp :\n"<< e.what() << std::endl;
        throw std::runtime_error(errorMessage.str());
    }
}

/*
seq :exp (NEXT seq)* 
*/
std::shared_ptr<AstNode<gRegexTokenTypes>> GraphParser::constructAstSeq(void)
{

   try{
   
        std::shared_ptr<AstNode<gRegexTokenTypes>> left = constructAstExp();
        if(mCurrentToken->getType() == gRegexTokenTypes::NEXT ) 
        {
            std::shared_ptr<ParsingToken<gRegexTokenTypes>> token = mCurrentToken->copy();
            ackToken(gRegexTokenTypes::NEXT);
            std::shared_ptr<AstNode<gRegexTokenTypes>> newNode = std::make_shared<AstNode<gRegexTokenTypes>>(token,
            std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{left,constructAstSeq()});
            left = newNode;
        }
        return left;

    } catch (const std::runtime_error& e) {
        std::ostringstream errorMessage;
        errorMessage << "GraphParser constructAstSeq :\n"<< e.what() << std::endl;
        throw std::runtime_error(errorMessage.str());
    }

}


/*
LPAREN seq RPAREN (QOM | QZM) 
*/
std::shared_ptr<AstNode<gRegexTokenTypes>> GraphParser::constructAstDomain(void)
{

   try{
        std::shared_ptr<ParsingToken<gRegexTokenTypes>> token ;
        std::shared_ptr<AstNode<gRegexTokenTypes>> node ;
 
        token = mCurrentToken->copy();
        ackToken(gRegexTokenTypes::LPAREN);
        node = std::make_shared<AstNode<gRegexTokenTypes>>(token,
        std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{constructAstSeq()});
        ackToken(gRegexTokenTypes::RPAREN);
        //(QOM | QZM)

        token = mCurrentToken->copy();
        if (mCurrentToken->getType() == gRegexTokenTypes::QOM){
            ackToken(gRegexTokenTypes::QOM);
            node = std::make_shared<AstNode<gRegexTokenTypes>>(token,
            std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{node});
        }else if (mCurrentToken->getType() == gRegexTokenTypes::QZM){
            ackToken(gRegexTokenTypes::QZM);
            node = std::make_shared<AstNode<gRegexTokenTypes>>(token,
            std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{node});
        }else{
            std::ostringstream errorMessage;
            errorMessage << "Bad syntax constructAstDomain must have quantifier \n";
            throw std::runtime_error(errorMessage.str());
        }
   
        return node;

    } catch (const std::runtime_error& e) {
        std::ostringstream errorMessage;
        errorMessage << "GraphParser constructAstDomain :\n"<< e.what() << std::endl;
        throw std::runtime_error(errorMessage.str());
    }
}

/*
        allExpr: seq (SEP allExpr)* | STOP
*/
std::shared_ptr<AstNode<gRegexTokenTypes>> GraphParser::constructAstAllExpr(void)
{

    try{
        std::shared_ptr<AstNode<gRegexTokenTypes>> left = constructAstSeq();
        if(mCurrentToken->getType() == gRegexTokenTypes::SEP ) 
        {
            std::shared_ptr<ParsingToken<gRegexTokenTypes>> token = mCurrentToken->copy();
            ackToken(gRegexTokenTypes::SEP);

            if(mCurrentToken->getType() == gRegexTokenTypes::STOP )
            {
                 return left;
            } 
            std::shared_ptr<AstNode<gRegexTokenTypes>> newNode = std::make_shared<AstNode<gRegexTokenTypes>>(token,
            std::vector<std::shared_ptr<AstNode<gRegexTokenTypes>>>{left,constructAstAllExpr()});
            left = newNode;
        }
        return left;

    } catch (const std::runtime_error& e) {
        std::ostringstream errorMessage;
        errorMessage << "GraphParser constructAstDomain :\n"<< e.what() << std::endl;
        throw std::runtime_error(errorMessage.str());
    }
}