ひとまず仕様をfixさせ、ユーザーズガイドを作成しました。結局構文解析部分は命令毎に規則を書き下す方式にしました。状態遷移表の状態数は740状態、遷移数は3445個です。これくらいなら許容範囲かな? 規則部はこんな感じ。各命令に対応するシンボルから始まり、それぞれの命令で指定可能なアドレシングモードの規則を記述しています。文法違反の場合は、特別なエラー命令(ErrorInstruction)を生成し、パーサから抜けた後に命令リストをスキャンし、まとめてエラー表示する方式とします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
ADCA expression:val {: if (ulen(val) != 1) { warning(String.format("operand out of range: %d(0x%h)", val, val)); val = val & 0xff; } RESULT = new ADCA(Instruction.ADDRESSING_IMMEDIATE, 1, val); next_addr = addr + 2; :} | ADCA LBRACE expression:val RBRACE {: if (ulen(val) != 1) { warning(String.format("operand out of range: %d(0x%h)", val, val)); val = val & 0xff; } RESULT = new ADCA(Instruction.ADDRESSING_DIRECT, 1, val); next_addr = addr + 2; :} | ADCA LBRACKET expression:val RBRACKET {: if (ulen(val) != 1 && ulen(val) != 2) { warning(String.format("operand out of range: %d(0x%h)", val, val)); val = val & 0xffff; } RESULT = new ADCA(Instruction.ADDRESSING_EXTENDED, 2, val); next_addr = addr + 3; :} | ADCA LBRACKET REG_X PLUS expression:val RBRACKET {: if (ulen(val) != 1) { warning(String.format("operand out of range: %d(0x%h)", val, val)); val = val & 0xff; } RESULT = new ADCA(Instruction.ADDRESSING_INDEXED, 1, val); next_addr = addr + 2; :} | ADCA LBRACKET REG_X RBRACKET {: RESULT = new ADCA(Instruction.ADDRESSING_INDEXED, 1, 0); next_addr = addr + 2; :} | ADCA error {: RESULT = new ErrorInstruction(scanner.getLineNumber(), "ADCA immediate|direct|indexed|extended"); :} | 以下続く |
ちょっと悩んだのがアドレシングモードのうちDir … “6802用アセンブラを作る(5) 一応完成” の続きを読む