私は ANTLR のアマチュアで、単純なプロセッサ用のインタープリターを作成していますが、VALUE トークンがエラーをスローするという小さな問題に遭遇しました。私は学生なので、宿題をやってくれと頼んでいるわけではありません...私はそれをほぼ完了しました (インタープリターのすべてのクラスファイルを含む)。そして私の顔をじっと見つめます。
ANTLR が機能すると、このコンソール エラー メッセージが表示され続けます。
「エラー (208): newExpr.g:193:1: 前のトークンが同じ入力に一致するため、次のトークン定義は一致しません: 値」
明らかに VALUE の正規表現に何か問題がありますが、それが何であるかはわかりません。文法のどこにもありません。私が欠けているものを指摘できれば、それは大歓迎です...グーグルは私自身の文法のエラーを見つけるのに実際には役立たなかったからです。
grammar newExpr;
options
{
language=Java;
}
@header
{
import java.util.*;
}
@members
{
ArrayList myInitialise = new ArrayList();
ArrayList InstructionList = new ArrayList();
}
/*--------------------------------------------------------------------------------------------------------------------------------*
* PARSER RULES *
*--------------------------------------------------------------------------------------------------------------------------------*//
/*
* prog is where the interpretation beings and consists of one or more (+) 'stat' rules
*/
prog : stat+;
/*
* stat rules are the general parse rules of entire operations on the processor.
* They consist of smaller data operations rules (dataop) or memory operations (memop).
*/
stat : BASIC r1=REG c1=COMMA r2=REG c2=COMMA dataop NEWLINE
{
int reg1 = Integer.parseInt($r1.text.substring(1)); // these lines convert the token input stream and converts to an actual integer
int reg2 = Integer.parseInt($r2.text.substring(1));
int IMDT = $dataop.value; // take the immediate integer
// LOAD operation
if($BASIC.text.equals("LD"))
InstructionList.add(new ld(reg1, reg2, IMDT));
// STORE operation
else if($BASIC.text.equals("ST"))
InstructionList.add(new st(reg1, reg2, IMDT));
// SUBTRACTION operation
else if($BASIC.text.equals("SUB"))
InstructionList.add(new sub(reg1, reg2, IMDT));
// ADDITION operation
else if($BASIC.text.equals("ADD"))
InstructionList.add(new add(reg1, reg2, IMDT));
// MULTIPLICATION operation
else if($BASIC.text.equals("MUL"))
InstructionList.add(new mul(reg1, reg2, IMDT));
// DIVISION operation
else if($BASIC.text.equals("DIV"))
InstructionList.add(new div(reg1, reg2, IMDT));
}
|
i1 = INDEX '=' memop NEWLINE
{
myInitialise.add(new memInit(Integer.parseInt($i1.text), $dataop.value));
}
|
JUMP REG COMMA dataop NEWLINE
{
int R = Integer.parseInt($REG.text.substring(1));
int val = $dataop.value;
// BRANCH EQUAL operation
if($JUMP.text.equals("BEZ"))
InstructionList.add(new branchEqualZero(R,value));
// BRANCH NOT EQUAL operation
else if($JUMP.text.equals("BNEZ"))
InstructionList.add(new branchNotEqualZero(R,value));
}
|
JUMP REG NEWLINE
{
int R = Integer.parseInt($REG.text.substring(1));
InstructionList.add(new jump(R));
}
|
HALT
{
InstructionList.add(new halt());
}
;
dataop returns [int value]
: INDEX
{
$value = Integer.parseInt($INDEX.text);
}
|
VALUE
{
$value = Integer.parseInt($VALUE.text.substring(1))*-1;
};
memop returns [int value]
: INDEX
{
$value = Integer.parseInt($INDEX.text);
}
|
VALUE
{
$value = Integer.parseInt($VALUE.text.substring(1))*-1;
}
|
MEMVAL
{
if($MEMVAL.text.startsWith("-"))
{
$value = Integer.parseInt($MEMVAL.text.substring(1))*-1;
}
else
$value = Integer.parseInt($MEMVAL.text);
};
/*--------------------------------------------------------------------------------------------------------------------------------*
* LEXER RULES *
*--------------------------------------------------------------------------------------------------------------------------------*/
/*
* RegExps for BASIC instructions (load, store, add, subtract, multiply, divide
*/
BASIC : ('L' 'D') | ('S' 'T') | ('A' 'D' 'D') | ('S' 'U' 'B') | ('M' 'U' 'L') | ('D' 'I' 'V');
/*
* The comma is simply for syntactic purposes, to separate data and register references
*/
COMMA : ',';
/*
* Regular Expressions for the processor registers R0-R31
*/
REG : ('R') (('0'..'9') | ('0'..'2') ('0'..'9') | ('3') ('0'..'1') );
/*
* 'Index' is the set of regular expressions matching memory locations
*/
INDEX : ('0'..'9')
|
('0'..'9') ('0'..'9')
|
('0'..'9') ('0'..'9') ('0'..'9')
|
('0'..'9') ('0'..'9') ('0'..'9') ('0'..'9')
|
('0'..'5') ('0'..'9') ('0'..'9') ('0'..'9') ('0'..'9')
|
('6') ('0'..'4') ('0'..'9') ('0'..'9') ('0'..'9')
|
('6') ('5') ('0'..'4') ('0'..'9') ('0'..'9')
|
('6') ('5') ('5') ('0'..'2') ('0'..'9')
|
('6') ('5') ('5') ('3') ('0'..'5');
/*
* Reg Exps for memory initialisation instructions
*/
MEMVAL : ('0'..'9')+ | '-' ('0'..'9')+;
/*
* Simple integers for data values
*/
VALUE : '-' (('0'..'9') **PROBLEM IS HERE**
|
('0'..'9') ('0'..'9')
|
('0'..'9') ('0'..'9') ('0'..'9')
|
('0'..'9') ('0'..'9') ('0'..'9') ('0'..'9')
|
('0'..'5') ('0'..'9') ('0'..'9') ('0'..'9') ('0'..'9')
|
('6') ('0'..'4') ('0'..'9') ('0'..'9') ('0'..'9')
|
('6') ('5') ('0'..'4') ('0'..'9') ('0'..'9')
|
('6') ('5') ('5') ('0'..'2') ('0'..'9')
|
('6') ('5') ('5') ('3') ('0'..'6'));
/*
* Regular Expressions for return/newline characters
*/
NEWLINE : '\r'? '\n' ;
/*
* This simply makes the interpreter tolerant to whitespace
*/
WHITESPACE : (' ' | '\t' | '\u000C')+ {skip();};
/*
* RegExp for Branch on Equal to Zero/Branch on Not Equal to Zero instructions
*/
BRANCH : ('B' 'E' 'Z') | ('B' 'N' 'E' 'Z');
/*
* RegExp for jump instruction
*/
JUMP : ('J' 'R');
/*
* The HALT instruction ends the program and executes all instructions
* in the Instruction List on the data/values that have been entered
*/
HALT : ('H' 'A' 'L' 'T');