2012-08-30 61 views
0

我試圖通過直接閱讀treeWalker並實現編譯器所需的命令來實現解析器。所以,如果我有一個像這樣的命令:ANTLR Tree Grammar for loops

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 
     ; 

任何幫助,將不勝感激,謝謝

回答

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

我在我的代碼的註釋中寫了這個問題。如果任何人都可以幫助我,併爲我回答這個問題,我將不勝感激。這太奇怪了,幾乎沒有任何正確的方式在樹上的語法實現循環的反饋。

問候, 亞歷

+0

沒有任何反饋,因爲它(IMO)來解決這個問題一個混亂的方式。你將語法中的所有代碼混合在一起,使語法非常難以維護。 –

+0

當然,這是一個完全混亂的方式,我同意你的看法。但是我坐了5個小時,並且找不到關於這個主題的任何好文檔,不得不自己測試它,或者嘗試從互聯網上隨機發送代碼,這通常是在很久以前提交的。我只是堅持第一個工作。 我只是爲大學制作一個項目,而且我已經在解析上花了很多時間。 –