Why is my Recursive Descent Parser not parsing an empty string?

59 views Asked by At

coding gods really wondering if someone can help with this little ol issue, this is what I've currently got it is a Recursive Descent Parser that takes Jack code and translates it into a parse-tree, I'm currently having an issue with parsing an empty string to my functions, as shown I think i have identified the issue but i cant seem to figure out the fix.

/**
 * Generates a parse tree for a single program
 * @return a ParseTree
 */
ParseTree* CompilerParser::compileProgram() {
    ParseTree* tree = new ParseTree("class", "");

    std::list<Token*> tokenListCopy = tokenList;  // Make a copy of the tokenList
print(tokenList);
    // Check for 'class' keyword
    Token* classKeyword = mustBe("keyword", "class");

    // Add 'class' keyword token to tree
    tree->addChild(classKeyword);

    std::cout << tree->tostring() << std::endl;

    // Check for identifier
    next();
    print(tokenList);

    
    Token* identifier = mustBe("identifier", "");

    // Add identifier token to tree
    tree->addChild(identifier);
    std::cout << tree->tostring() << std::endl;

    // Check for opening curly brace
    next();
    print(tokenList);
this is the parser which takes the test case     

list<Token*> tokens;
    tokens.push_back(new Token("keyword", "class"));
    tokens.push_back(new Token("identifier", "MyClass"));
    tokens.push_back(new Token("symbol", "{"));
    tokens.push_back(new Token("symbol", "}"));

my current output is

keyword class

identifier MyClass

symbol {

symbol }


class
  └ keyword class


symbol {

symbol }

as seen I've identified that the issue is occurring when i parse an empty string to my mustbe() function I think.

This is my mustbe()

/**
 * Check if the current token matches the expected type and value.
 * If so, advance to the next token, returning the current token, otherwise throw a ParseException.
 * @return the current token before advancing
 */
Token* CompilerParser::mustBe(std::string expectedType, std::string expectedValue){
     Token* currentToken = current();

    if (expectedValue.empty()) {
        if (currentToken->getType() == expectedType) {
            next();  // Advance to the next token
            return currentToken;
        }
    } else {
        if (have(expectedType, expectedValue)) {
            next();  // Advance to the next token
            return currentToken;
        }
    }

    throw ParseException(); 
}

which uses the have() function

/**
 * Check if the current token matches the expected type and value.
 * @return true if a match, false otherwise
 */
bool CompilerParser::have(std::string expectedType, std::string expectedValue){
    Token* currentToken = current();
    if (currentToken != nullptr) {
        std::string tokenType = currentToken->getType();
        std::string tokenValue = currentToken->getValue();

        if (expectedValue.empty()) {
            return (tokenType == expectedType);
        } else {
            return (tokenType == expectedType && tokenValue == expectedValue);
        }
    }
    return false;  // Return false if there is no current token
}

my biggest hate is that i know the out put should be

class
  └ keyword class
  └ identifier MyClass

help on finding the issue would be great thanks everyone.

Oops new to this i put that above :)

0

There are 0 answers