2
This commit is contained in:
parent
c8fe680339
commit
70a61f31de
@ -16,6 +16,7 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextPane;
|
||||
@ -86,12 +87,18 @@ public class AnalyzerPanel extends JPanel {
|
||||
try {
|
||||
syn.analyze();
|
||||
} catch (ExceptionWithLineNumber ex) {
|
||||
System.out.println(ex.getMessage());
|
||||
showMessageBox(ex.getMessage());
|
||||
return;
|
||||
}
|
||||
showMessageBox("Source is correct!");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showMessageBox(String text) {
|
||||
JOptionPane.showMessageDialog(this, text);
|
||||
}
|
||||
|
||||
private String getTextFromResource(String res) {
|
||||
try {
|
||||
InputStream is = getClass().getResourceAsStream(res);
|
||||
|
@ -1,6 +1,11 @@
|
||||
package com.annimon.asm;
|
||||
|
||||
import com.annimon.asm.directives.ID;
|
||||
import com.annimon.asm.directives.Add;
|
||||
import com.annimon.asm.directives.Mul;
|
||||
import com.annimon.asm.directives.Pop;
|
||||
import com.annimon.asm.directives.Push;
|
||||
import com.annimon.asm.directives.SyntaxChecker;
|
||||
import com.annimon.asm.directives.Variable;
|
||||
import com.annimon.asm.exceptions.ExceptionWithLineNumber;
|
||||
|
||||
/**
|
||||
@ -9,6 +14,12 @@ import com.annimon.asm.exceptions.ExceptionWithLineNumber;
|
||||
*/
|
||||
public class SyntaxAnalyzer {
|
||||
|
||||
private static final SyntaxChecker[] DIRECTIVES = {
|
||||
new Add(), new Mul(), new Push(), new Pop(),
|
||||
new Variable()
|
||||
};
|
||||
|
||||
|
||||
private LexicTable lexicTable;
|
||||
|
||||
public SyntaxAnalyzer(LexicTable lexicTable) {
|
||||
@ -23,8 +34,10 @@ public class SyntaxAnalyzer {
|
||||
}
|
||||
|
||||
private void analyzeLine(int lineNumber, int[] lexic) throws ExceptionWithLineNumber {
|
||||
if (lexic[0] == ID.VAR) {
|
||||
|
||||
for (int i = 0; i < DIRECTIVES.length; i++) {
|
||||
if (DIRECTIVES[i].check(lineNumber, lexic)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,63 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
import com.annimon.asm.exceptions.CommaExpectedException;
|
||||
import com.annimon.asm.exceptions.ExceptionWithLineNumber;
|
||||
import com.annimon.asm.exceptions.FewArgumentsException;
|
||||
import com.annimon.asm.exceptions.TooManyArgumentsException;
|
||||
import com.annimon.asm.exceptions.WrongArgumentException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public class Add extends Directive {
|
||||
public class Add extends Directive implements SyntaxChecker {
|
||||
|
||||
public Add() {
|
||||
super("add", ID.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(int lineNumber, int[] ids) throws ExceptionWithLineNumber {
|
||||
if (ids[0] == getId()) {
|
||||
if (ids.length < 4) throw new FewArgumentsException(lineNumber);
|
||||
else if (ids.length > 4) throw new TooManyArgumentsException(lineNumber);
|
||||
|
||||
if (ids[2] != ID.COMMA) throw new CommaExpectedException(lineNumber);
|
||||
|
||||
int[] pairs = new int[] {
|
||||
// Ðåãèñòð - Ðåãèñòð
|
||||
ID.REGISTER_BYTE, ID.REGISTER_BYTE,
|
||||
ID.REGISTER_WORD, ID.REGISTER_WORD,
|
||||
ID.REGISTER_WORD, ID.REGISTER_BYTE,
|
||||
|
||||
// Ðåãèñòð - Ïàìÿòü
|
||||
ID.REGISTER_BYTE, ID.VAR,
|
||||
ID.REGISTER_WORD, ID.VAR,
|
||||
|
||||
// Ïàìÿòü - Ðåãèñòð
|
||||
ID.VAR, ID.REGISTER_BYTE,
|
||||
ID.VAR, ID.REGISTER_WORD,
|
||||
|
||||
// Ðåãèñòð - Çíà÷åíèå
|
||||
ID.REGISTER_BYTE, ID.NUMBER_BYTE,
|
||||
ID.REGISTER_WORD, ID.NUMBER_WORD,
|
||||
ID.REGISTER_WORD, ID.NUMBER_BYTE,
|
||||
|
||||
// Ïàìÿòü - Çíà÷åíèå
|
||||
ID.VAR, ID.NUMBER_BYTE,
|
||||
ID.VAR, ID.NUMBER_WORD,
|
||||
};
|
||||
|
||||
boolean correct = false;
|
||||
for(int i = 0; i < pairs.length; i += 2) {
|
||||
if ( (ids[1] == pairs[i]) && (ids[3] == pairs[i+1]) ) {
|
||||
correct = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!correct) throw new WrongArgumentException(lineNumber);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
|
@ -1,17 +1,32 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
import com.annimon.asm.exceptions.ExceptionWithLineNumber;
|
||||
import com.annimon.asm.exceptions.FewArgumentsException;
|
||||
import com.annimon.asm.exceptions.TooManyArgumentsException;
|
||||
import com.annimon.asm.exceptions.WrongArgumentException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public class Mul extends Directive {
|
||||
public class Mul extends Directive implements SyntaxChecker {
|
||||
|
||||
public Mul() {
|
||||
super("mul", ID.MUL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(int lineNumber, int[] ids) throws ExceptionWithLineNumber {
|
||||
if (ids[0] == getId()) {
|
||||
if (ids.length < 2) throw new FewArgumentsException(lineNumber, 1);
|
||||
else if (ids.length > 2) throw new TooManyArgumentsException(lineNumber, 1);
|
||||
|
||||
if ( (ids[1] != ID.REGISTER_BYTE) && (ids[1] != ID.REGISTER_WORD) &&
|
||||
(ids[1] != ID.VAR)) {
|
||||
throw new WrongArgumentException(lineNumber);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
@ -27,6 +23,12 @@ public abstract class NumericValue extends Directive {
|
||||
private Integer parse(String text) {
|
||||
int value;
|
||||
if (text.toLowerCase().endsWith("h")) {
|
||||
char first = Character.toLowerCase(text.charAt(0));
|
||||
if ( (first >= 'a') && (first <= 'f') ) {
|
||||
// Ïåðâûé ñèìâîë hex ÷èñëà íå äîëæåí áûòü îò a äî f
|
||||
return null;
|
||||
}
|
||||
|
||||
String hex = text.substring(0, text.length() - 1);
|
||||
try {
|
||||
value = Integer.parseInt(hex, 16);
|
||||
|
@ -1,17 +1,31 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
import com.annimon.asm.exceptions.ExceptionWithLineNumber;
|
||||
import com.annimon.asm.exceptions.FewArgumentsException;
|
||||
import com.annimon.asm.exceptions.WrongArgumentException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public class Pop extends Directive {
|
||||
public class Pop extends Directive implements SyntaxChecker {
|
||||
|
||||
public Pop() {
|
||||
super("pop", ID.POP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(int lineNumber, int[] ids) throws ExceptionWithLineNumber {
|
||||
if (ids[0] == getId()) {
|
||||
if (ids.length < 2) throw new FewArgumentsException(lineNumber, 1);
|
||||
for (int i = 1; i < ids.length; i++) {
|
||||
if ( (ids[i] != ID.REGISTER_WORD) &&
|
||||
(ids[i] != ID.VAR)) {
|
||||
throw new WrongArgumentException(lineNumber);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,32 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
import com.annimon.asm.exceptions.ExceptionWithLineNumber;
|
||||
import com.annimon.asm.exceptions.FewArgumentsException;
|
||||
import com.annimon.asm.exceptions.WrongArgumentException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public class Push extends Directive {
|
||||
public class Push extends Directive implements SyntaxChecker {
|
||||
|
||||
public Push() {
|
||||
super("push", ID.PUSH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(int lineNumber, int[] ids) throws ExceptionWithLineNumber {
|
||||
if (ids[0] == getId()) {
|
||||
if (ids.length < 2) throw new FewArgumentsException(lineNumber, 1);
|
||||
for (int i = 1; i < ids.length; i++) {
|
||||
if ( (ids[i] != ID.REGISTER_WORD) &&
|
||||
(ids[i] != ID.VAR)) {
|
||||
throw new WrongArgumentException(lineNumber);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
|
20
src/com/annimon/asm/directives/SyntaxChecker.java
Normal file
20
src/com/annimon/asm/directives/SyntaxChecker.java
Normal file
@ -0,0 +1,20 @@
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
import com.annimon.asm.exceptions.ExceptionWithLineNumber;
|
||||
|
||||
/**
|
||||
* Ïðîâåðêà ñèíòàêñèñà.
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public interface SyntaxChecker {
|
||||
|
||||
/**
|
||||
* Ïðîâåðèòü ñèíòàêñèñ.
|
||||
* @param lineNumber íîìåð ñòðîêè.
|
||||
* @param ids ïîñëåäîâàòåëüíîñòü èäåíòèôèêàòîðîâ â ñòðîêå.
|
||||
* @return ïðàâèëüíîñòü ïîñëåäîâàòåëüíîñòè äèðåêòèâ.
|
||||
* @throws ExceptionWithLineNumber
|
||||
*/
|
||||
public boolean check(int lineNumber, int[] ids) throws ExceptionWithLineNumber;
|
||||
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
import com.annimon.asm.exceptions.ExceptionWithLineNumber;
|
||||
import com.annimon.asm.exceptions.FewArgumentsException;
|
||||
import com.annimon.asm.exceptions.TooManyArgumentsException;
|
||||
import com.annimon.asm.exceptions.WrongArgumentException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public class Variable extends Directive {
|
||||
public class Variable extends Directive implements SyntaxChecker {
|
||||
|
||||
public Variable() {
|
||||
super("", ID.VAR);
|
||||
@ -16,7 +18,27 @@ public class Variable extends Directive {
|
||||
|
||||
@Override
|
||||
public boolean isDirective(String text) {
|
||||
if (Pattern.matches(Pattern.compile("^[^1-9]+[\\w.@_$]").pattern(), text)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(int lineNumber, int[] ids) throws ExceptionWithLineNumber {
|
||||
if (ids[0] == getId()) {
|
||||
if (ids.length < 3) throw new FewArgumentsException(lineNumber, 2);
|
||||
else if (ids.length > 3) throw new TooManyArgumentsException(lineNumber, 2);
|
||||
|
||||
boolean db = ( (ids[1] == ID.DB) &&
|
||||
((ids[2] == ID.NUMBER_BYTE) || (ids[2] == ID.NUMBER_INFINITY)) );
|
||||
boolean dw = ( (ids[1] == ID.DW) &&
|
||||
((ids[2] == ID.NUMBER_WORD) || (ids[2] == ID.NUMBER_INFINITY)) );
|
||||
if (!db && !dw) {
|
||||
throw new WrongArgumentException(lineNumber);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
@ -23,7 +19,8 @@ public class WordRegister extends Register {
|
||||
protected String[] getRegisterNames() {
|
||||
return new String[] {
|
||||
"ax", "bx", "cx", "dx",
|
||||
"cs", "ds", "ss", "es"
|
||||
"cs", "ds", "ss", "es",
|
||||
"sp", "bp", "si", "di"
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.directives;
|
||||
|
||||
/**
|
||||
|
16
src/com/annimon/asm/exceptions/CommaExpectedException.java
Normal file
16
src/com/annimon/asm/exceptions/CommaExpectedException.java
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.exceptions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public class CommaExpectedException extends ExceptionWithLineNumber {
|
||||
|
||||
public CommaExpectedException(int lineNumber) {
|
||||
super("Comma expected", lineNumber);
|
||||
}
|
||||
}
|
20
src/com/annimon/asm/exceptions/FewArgumentsException.java
Normal file
20
src/com/annimon/asm/exceptions/FewArgumentsException.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.exceptions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public class FewArgumentsException extends ExceptionWithLineNumber {
|
||||
|
||||
public FewArgumentsException(int lineNumber) {
|
||||
super("Few arguments", lineNumber);
|
||||
}
|
||||
|
||||
public FewArgumentsException(int lineNumber, int necessaryArguments) {
|
||||
super("Few arguments, need " + necessaryArguments + " args", lineNumber);
|
||||
}
|
||||
}
|
16
src/com/annimon/asm/exceptions/SyntaxException.java
Normal file
16
src/com/annimon/asm/exceptions/SyntaxException.java
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.exceptions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public class SyntaxException extends ExceptionWithLineNumber {
|
||||
|
||||
public SyntaxException(int lineNumber) {
|
||||
super("Unknown syntax", lineNumber);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.exceptions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public class TooManyArgumentsException extends ExceptionWithLineNumber {
|
||||
|
||||
public TooManyArgumentsException(int lineNumber) {
|
||||
super("Too many arguments", lineNumber);
|
||||
}
|
||||
|
||||
public TooManyArgumentsException(int lineNumber, int necessaryArguments) {
|
||||
super("Too many arguments, need " + necessaryArguments + " args", lineNumber);
|
||||
}
|
||||
}
|
16
src/com/annimon/asm/exceptions/WrongArgumentException.java
Normal file
16
src/com/annimon/asm/exceptions/WrongArgumentException.java
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.annimon.asm.exceptions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public class WrongArgumentException extends ExceptionWithLineNumber {
|
||||
|
||||
public WrongArgumentException(int lineNumber) {
|
||||
super("Wrong argument", lineNumber);
|
||||
}
|
||||
}
|
@ -2,7 +2,8 @@ num1 db 12
|
||||
num2 dw 2000
|
||||
num3 dw ?
|
||||
|
||||
add num1, num2
|
||||
add num1, 400
|
||||
add si, num2
|
||||
push num2
|
||||
mul num1
|
||||
pop ax
|
Loading…
Reference in New Issue
Block a user