Search code examples
javatokenjavacc

comparing tokens in parser to call method on a hashtable


I'm working on a parser and scanner with javacc for a programming language. Right now I'm trying to establish what would be assigning values to variables. When creating a new variable, like so:

hello = 5

the value of 5 is saved on a hashtable, and that works perfectly fine. With a function I take the variable and its value and put it in the table.

However when I try to assign a variable another existing variable:

hello = 5
bye = hello

I'd use another method to first check if hello already exists in the hashtable. If it does bye gets assigned the value of 5, and if it doesn't it prints an error message.

on my .jj file I have the following code for the first case:

void Assign() : { Token var; int value;}
{
    var = <TK_ID>
    <TK_EQ> 
    value = Exp()

    {
        TableVariables.assignValue(var,value);
    }
}  

TK_ID is the token for whatever name the variable is given

TK_EQ is the token for =

Exp() is a method that allows any kind of numerical expression to be a value

what I want to do and don't know how is the following:

    if (var = value)
        TableVariables.assignValue(var,value);
    else if (var = var2)
        TableVariables.assignID(var,var2);

this is what assignValue looks like:

public static void assignValue(Token id, int value) {   
        table.put(id.image, value);
    }

and what assignID looks like:

public static void assignID(Token id, Token id2) {

        if(table.containsKey(id2.image)) {
            table.put(id.image, (Integer)table.get(id2.image)); 
        }
        else {
            System.out.println("Error " + id2.image + " does not exist");
        }
    }

I tried to do this but it didn't work:

void Assign() : { Token var; Token var2; int value;}
{
    var = <TK_ID>
    <TK_EQ> 
    value = Exp()

    {
        TableVariables.assignValue(var,value);
    }
    |
    var = <TK_ID>
    <TK_EQ> 
    var2 = <TK_ID>

    {
        TableVariables.assignID(var,var2);
    }
}

Any help will be appreciated, thanks!


Solution

  • I don't think there are really two cases. If your language is like most languages, one kind of expression is a variable. I.e. your Exp nonterminal would look something like:

    int Exp() :{
        Token t;
        int value;}
    {
        t = <TK_ID> 
        { 
            Integer v = TableVariables.getValue(t.image) ;
            if( v == null ) {
                reportError( "Uninitialized variable "+ t.image ) ;
                return 0 ;
            else {
                return v.intValue() ; }
        }
    |
        t = <TK_INT_LITERAL> 
        { return Integer.parseInt( t.image, 10) ; }
    |
       ...
    }
    

    Then your assignment statement can handle both cases as one case, just as you had

    void Assign() : { Token var; int value;}
    {
        var = <TK_ID>
        <TK_EQ> 
        value = Exp()
    
        {
            TableVariables.assignValue(var,value);
        }
    }