pattern_recognition / source / parser.cc
parser.cc
Raw
#include "parser.h"

#include <iostream>

// Constructor voor Parser
Parser::Parser(std::string expression) {
    index = 0;
    this->expression = expression;
    length = expression.length();
    currentToken = expression.at(0);
    error = false;
} // Parser::Parser

// Start het parsen door expr() aan te roepen
Automaton Parser::parse() {
    Automaton automaat;
    if(!(length == 1 && currentToken == '$')) {
        automaat = expr();
    } // We accepteren "$" als expressie voor de taal met alleen een lege string
    else {
        automaat.firstTransition('$');
        nextToken();
    } // Automaat die alleen lege strings accepteerd
    if(!isFinished()) {
        std::cerr << "Parse error: niet hele expressie kunnen parsen, de expressie voldoet niet" << std::endl;
        return Automaton();
    } // Nog niet de hele expressie gelezen
    automaat.setCorrectAutomaton(!error);
    return automaat;
} // Parser::parse

// Zet een nieuwe token uit expression in currentToken
void Parser::nextToken() {
    index++;
    if(length <= index) {
        currentToken = '#';
    } // Er zijn geen nieuwe tokens meer
    else {
        currentToken = expression.at(index);
    }
} // Parser::nextToken

// Geeft terug of de hele expressie geparsed is
bool Parser::isFinished() const {
    return length <= index;
} // Parser::isFinished

// Geeft terug of het karakter een letter is
bool Parser::isLetter(char const character) const {
    return character >= 'a' && character <= 'z';
} // Parser::isLetter

// Geeft terug of het karakter een openingshaakje is
bool Parser::isOpeningPar(char const character) const {
    return character == '(';
} // Parser::isOpeningPar

// Geeft terug of het karakter een sluitingshaakje is
bool Parser::isClosingPar(char const character) const {
    return character == ')';
} // Parser::isClosingPar

// Geeft terug of het karakter een ster is
bool Parser::isStar(char const character) const {
    return character == '*';
} // Parser::isStar

// Parse functie voor een expressie
Automaton Parser::expr() {
    Automaton autoTerm = term();
    Automaton newAuto;
    if(currentToken == '|') {
        nextToken();
        Automaton autoExpr;
        autoExpr = expr();
        newAuto.plus(autoTerm, autoExpr);
    }
    else {
        newAuto = autoTerm;
    }
    if(error) {
        return Automaton();
    } // Error dus return lege Automaton
    return newAuto;  
} // Parser::expr

// Parse functie voor een term
Automaton Parser::term() {
    Automaton autoFact = fact();
    if(isOpeningPar(currentToken) || isLetter(currentToken)) {
        Automaton autoTerm;
        autoTerm = term();
        autoFact.concat(autoTerm);
    }
    if(error) {
        return Automaton();
    } // Check error
    return autoFact;
} // Parser::term

// Parse functie voor een fact en een letter
Automaton Parser::fact() {
    Automaton autoFact;
    if(isOpeningPar(currentToken)) {
        nextToken();
        autoFact = expr();
        if(error) {
            return Automaton();
        } // expr() had een error
        if(isClosingPar(currentToken)) {
            nextToken();
        }
        else {
            std::cerr << "Parse error: openingshaakje heeft geen bijbehorende sluitingshaakje" << std::endl;
            error = true;
            return Automaton();
        } // Geen closing par
    } // ( <expr> )

    else if(isLetter(currentToken)) {
        autoFact.firstTransition(currentToken);
        nextToken();
    } // <lett>
    else {
        std::cerr << "Parse error: fact is leeg of bevat een onbekend karakter" << std::endl;
        error = true;
        return Automaton();
    } // Er zit niks in fact

    if(isStar(currentToken)) {
        autoFact.star();
        nextToken();
    } // [ * ]
    return autoFact;
} // Parser::fact