Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 比较解析器中的标记和哈希表上的调用方法_Java_Token_Javacc - Fatal编程技术网

Java 比较解析器中的标记和哈希表上的调用方法

Java 比较解析器中的标记和哈希表上的调用方法,java,token,javacc,Java,Token,Javacc,我正在使用javacc为一种编程语言开发解析器和扫描器。现在,我正试图确定什么是给变量赋值。创建新变量时,如下所示: hello = 5 5的值保存在哈希表中,这非常好。使用函数,我获取变量及其值并将其放入表中 但是,当我尝试为一个变量分配另一个现有变量时: hello = 5 bye = hello 我将使用另一种方法首先检查hashtable中是否已经存在hello。如果它这样做,bye将被分配值5,如果它不这样做,它将打印一条错误消息 在我的.jj文件中 对于第一个案例,我有以下代码:

我正在使用javacc为一种编程语言开发解析器和扫描器。现在,我正试图确定什么是给变量赋值。创建新变量时,如下所示:

hello = 5
5的值保存在哈希表中,这非常好。使用函数,我获取变量及其值并将其放入表中

但是,当我尝试为一个变量分配另一个现有变量时:

hello = 5
bye = hello
我将使用另一种方法首先检查hashtable中是否已经存在hello。如果它这样做,bye将被分配值5,如果它不这样做,它将打印一条错误消息

在我的.jj文件中 对于第一个案例,我有以下代码:

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

    {
        TableVariables.assignValue(var,value);
    }
}  
这就是assignValue的外观:

public static void assignValue(Token id, int value) {   
        table.put(id.image, value);
    }
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");
        }
    }
以及assignID的外观:

public static void assignValue(Token id, int value) {   
        table.put(id.image, value);
    }
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");
        }
    }
我试图这样做,但没有成功:

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);
    }
}
void Assign():{Token-var;Token-var2;int-value;}
{
var=
value=Exp()
{
TableVariables.assignValue(var,value);
}
|
var=
var2=
{
TableVariables.assignID(var,var2);
}
}

任何帮助都将不胜感激,谢谢

我不认为真的有两种情况。如果您的语言与大多数语言一样,那么有一种表达式是变量。也就是说,您的
Exp
非终结符看起来像:

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) ; }
|
   ...
}
int Exp():{
令牌t;
int值;}
{
t=
{ 
整数v=TableVariables.getValue(t.image);
如果(v==null){
reportError(“未初始化变量”+t.image);
返回0;
否则{
返回v.intValue();}
}
|
t=
{返回整数.parseInt(t.image,10);}
|
...
}
然后您的赋值语句可以将这两种情况作为一种情况处理,就像您之前所做的那样

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

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

如果您打算在将来的任何时候支持循环,您会发现在同一个过程中解析和求值都不是一个好主意。原因是您希望解析循环一次,但要执行它多次。如果您打算支持子例程,则类似的推理。最好有一个创建子例程的解析过程中间代码是一种中间代码,然后是解释(即执行)该中间代码的解释过程。中间代码的典型选择包括:抽象语法树和虚拟机的机器代码。