0

我试图通过直接读取 treeWalker 并动态实现编译器所需的命令来实现解析器。所以如果我有这样的命令:

 statement
            :
            ^('WRITE' expression) 
            { 
                //Here is the command that is created by my Tree Parser
                ch.emitRO("OUT",0,0,0,"write out the value of ac");
                //and then I handle it in my other classes
            }
;

我希望它写出 0,0,0;到一个文件。这就是我的语法。

虽然我的语法中的循环部分有问题,但它是:

'WHILE'^ expression 'DO' stat_seq 'ENDDO' 

在树解析器中:

doWhileStatement
:
^('WHILE' expression 'DO' stat_seq 'ENDDO')
;

我想要做的是直接将while循环中的代码解析为我需要的命令。我想出了这个解决方案,但它不起作用:

doWhileStatement
        :
        ^('WHILE' e=expression head='DO'
            {
                int loopHead =((CommonTree) head).getTokenStartIndex();

            }

            stat_seq

            {
                if ($e.result==1) {
                     input.seek(loopHead);
                     doWhileStatement();
                }
            }
         'ENDDO')
; 

这里记录一下我写的其他一些命令:(忽略括号中的代码,它用于在文本文件中生成命令。)

    stat_seq
            :
            (statement)+
            ;
statement
        :
        ^(':=' ID e=expression) { variables.put($ID.text,e); }
        | ^('WRITE' expression) 
        { 
            ch.emitRM("LDC",ac,$expression.result,0,"pass the expression value to the ac reg");
            ch.emitRO("OUT",ac,0,0,"write out the value of ac");
        }
        | ^('READ' ID)
        {
            ch.emitRO("IN",ac,0,0,"read value");
        }
        | ^('IF' expression 'THEN'
        {
            ch.emitRM("LDC",ac1,$expression.result,0,"pass the expression result to the ac reg");
            int savedLoc1 = ch.emitSkip(1);
        }
        sseq1=stat_seq  
        'ELSE'
        {
            int savedLoc2 = ch.emitSkip(1);
            ch.emitBackup(savedLoc1);
            ch.emitRM("JEQ",ac1,savedLoc2+1,0,"skip as many places as needed depending on the expression");
            ch.emitRestore();
        }
         sseq2=stat_seq
         {
            int savedLoc3 = ch.emitSkip(0);
            ch.emitBackup(savedLoc2);
            ch.emitRM("LDC",PC_REG,savedLoc3,0,"skip for the else command");
            ch.emitRestore();
         }

          'ENDIF')
        | doWhileStatement
        ;

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

4

1 回答 1

0

我为遇到同样问题的每个人都找到了它,我这样做了并且它正在工作:

^('WHILE'  

        {int c = input.index();}
        expression   

        {int s=input.index();}
        .* )// .* is a sequence of statements

        {
        int next = input.index(); // index of node following WHILE
        input.seek(c);
        match(input, Token.DOWN, null); 
        pushFollow(FOLLOW_expression_in_statement339);
        int condition = expression();

        state._fsp--;            
        //there is a problem here
        //expression() seemed to be reading from the grammar file and I couldn't
        //get it to read from the tree walker rule somehow
        //It printed something like no viable alt at input 'DOWN'
        //I googled it and found this mistake
        // So I copied the code from the normal while statement
        // And pasted it here and it works like a charm
        // Normally there should only be int condition = expression()   

        while ( condition == 1 ) {
            input.seek(s);
            stat_seq();//stat_seq is a sequence of statements: (statement ';')+
            input.seek(c);

            match(input, Token.DOWN, null); //Copied value from EvaluatorWalker.java
            //cause couldn't find another way to do it
            pushFollow(FOLLOW_expression_in_statement339);
            condition = expression();

            state._fsp--;
            System.out.println("condition:"+condition + " i:"+ variables.get("i"));
        }
        input.seek(next);
     }

我在代码的注释中写下了这个问题。如果有人可以帮助我并为我回答这个问题,我将不胜感激。太奇怪了,几乎没有关于在树语法中动态实现循环的正确方法的反馈。

问候,亚历克斯

于 2012-08-31T12:53:44.470 回答