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
;
助けていただければ幸いです、ありがとう