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
            }
;

OUT 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 に答える