Hallo ihr,
ich habe mir vorgenommen einen Syntax Checker zu schreiben.
Er soll ein übergebenes Skript-Dokument auf syntaktische Fehler überprüfen.
Folgenede Dinge will ich berücksichtigen.
Angefangen habe ich zunächst mit dem Part zum Einscannen von den nativen Funktionen etc., das ist aber nicht wirklich performant...
Hier mal die Methode zum Einlesen der nativen Funktionen/variabeln ...
Für jede native Funktion bzw. Variable für ein JassValue Objekt erzeugt
(JassValue)
Ich denke die nativen Funktionen und so brauche ich eventuell garnicht so einzuscannen, habe aber keine Idee, wie ich das sonst realisieren soll.
Das gleich passiert bei dem Dokument, welches vom User eingescannt wird. Alle Funktionen etc. werden als JassValue Objekte eingelesen um später zu überprüfen ob diese vorhanden sind.
Das ist ja leider aber nur der Anfang ... auf Dinge wie das Überprüfen ob der richtige Typ übergeben wurde oder Fehler in der Schreibweise habe ich noch garnicht geachtet.
Meine Fragen nun:
- Gibt es eventuell Tutorials zum schreiben von Syntax Checkern.
- Habt ihr eventuell Tips, wie ich das ganze besser angehen könnte.
- Ist mein Ansatz total falsch?
Über jegliche Hilfe wäre ich sehr glücklich
(Das ganze mache ich in meiner Freizeit , zum üben und weil es spaß macht. Also ist es auch nicht so schlimm wenn keiner weiter weiß
)
MFG
Timo
ich habe mir vorgenommen einen Syntax Checker zu schreiben.
Er soll ein übergebenes Skript-Dokument auf syntaktische Fehler überprüfen.
Folgenede Dinge will ich berücksichtigen.
- Einlesen von nativen Funktionen, welche in einer externen Datei sind
- Funktion/Variable vorhanden
- Ist der übergebene Wert korrekt (integer wirklich integer?)
- Ausgabe von Fehlern
- Anwendung via. Konsole also ohne GUI schnickschnack
Angefangen habe ich zunächst mit dem Part zum Einscannen von den nativen Funktionen etc., das ist aber nicht wirklich performant...
Hier mal die Methode zum Einlesen der nativen Funktionen/variabeln ...
Java:
private ArrayList<String> zeilen = new ArrayList<String>();
private void scanCommon(String dateiPfad) {
BufferedReader br = null;
try {
File file = new File(dateiPfad);
if (!file.exists()) {
return;
}
br = new BufferedReader(new FileReader(file));
String line = null;
try {
while ((line = br.readLine()) != null) {
if (!line.equals("") || !line.isEmpty()) {
if (line.indexOf("//") != -1) {
line = line.substring(0, line.indexOf("//"));
}
if (!line.replaceAll(" ", "").isEmpty() || !line.replaceAll(" ", "").equals("")) {
zeilen.add(line);
}
}
}
} catch (IOException ex) {
}
int lineNr = 0;
for (String t : zeilen) {
new JassValue().scan(t,lineNr++);
}
} catch (FileNotFoundException ex) {
} finally {
try {
br.close();
zeilen.clear();
} catch (IOException ex) {
}
}
}
Für jede native Funktion bzw. Variable für ein JassValue Objekt erzeugt
(JassValue)
Java:
public class JassValue{
private static HashMap<String,JassValue> valueMap = new HashMap<String,JassValue>();
private static HashMap<String,JassValue> typeMap = new HashMap<String,JassValue>();
private static ArrayList<String> typeListe = new ArrayList<String>();
private static ArrayList<String> ignoreListe = new ArrayList<String>();
private static ArrayList<String> valueNameListe = new ArrayList<String>();
private String name = "";
private ArrayList<String> parametar = new ArrayList<String>();
private String returnValue = "nothing";
private boolean firstUse = true;
public JassValue(String name,boolean standardType){
this.name = name;
}
public JassValue() {
}
public boolean scan(String headLine,int lineNr){
if(firstUse){
setupArrayList();
firstUse = false;
}
boolean takes = false, returns = false,type = false,consVar = false, first = false;
boolean globalTakes = false;
String returnString = "";
StringTokenizer st = new StringTokenizer(headLine);
while(st.hasMoreTokens()){
String s = st.nextToken();
if(globalTakes){
returnString = headLine.substring(headLine.indexOf("=")+1).trim();
globalTakes = false;
if(returnString.indexOf("(") != -1){
String temp = returnString.substring(0, returnString.indexOf("("));
}
}
if(returns){
returnValue = s;
}
if(s.equals("returns")){
takes = false;
returns = true;
}
if(s.equals("=")){
globalTakes = true;
}
if(takes){
if(!s.equals(",") && valueNameListe.indexOf(s) != -1){
parametar.add(s);
}
}
if (consVar) {
if (typeMap.containsKey(s)) {
returnValue = s;
}
consVar = false;
}
if(s.equals("takes"))takes = true;
if(s.equals("constant"))consVar = true;
if(s.equals("type"))type = true;
if(typeMap.containsKey(s) && headLine.indexOf("=") != -1 && headLine.indexOf("constant") == -1){
returnValue = s;
}
if (!takes && !returns) {
if (typeListe.indexOf(s) == -1 && ignoreListe.indexOf(s) == -1
&& valueNameListe.indexOf(s) == -1 && s.length() >= 4
&& s.indexOf("(") == -1 && s.indexOf(",") == -1 && !s.isEmpty()
&& !s.equals("") && !s.equals(" ")) {
name = s;
first = true;
valueNameListe.add(name);
if(type){
typeMap.put(name,this);
}else{
valueMap.put(name,this);
}
}
}
}
return first;
}
public ArrayList<String> getParametar(){
return parametar;
}
public String getName(){
return name;
}
public void setReturnValue(String value){
returnValue = value;
}
public String getReturnValue(){
return returnValue;
}
public boolean noParametar(){
return parametar.isEmpty();
}
private void setupArrayList() {
typeListe.add("constant");
typeListe.add("native");
typeListe.add("type");
valueNameListe.add("handle");
valueNameListe.add("integer");
valueNameListe.add("real");
valueNameListe.add("boolean");
valueNameListe.add("string");
valueNameListe.add("code");
typeMap.put("handle",new JassValue("handle",true));
typeMap.put("integer",new JassValue("integer",true));
typeMap.put("string",new JassValue("string",true));
typeMap.put("real",new JassValue("real",true));
typeMap.put("boolean",new JassValue("boolean",true));
typeMap.put("code",new JassValue("code",true));
ignoreListe.add("handle");
ignoreListe.add("extends");
ignoreListe.add("takes");
ignoreListe.add("returns");
ignoreListe.add("string");
ignoreListe.add("integer");
ignoreListe.add("boolean");
ignoreListe.add("globals");
ignoreListe.add("endglobals");
ignoreListe.add("=");
}
public static HashMap<String,JassValue> getValueMap(){
return valueMap;
}
public static HashMap<String,JassValue> getTypeMap(){
return typeMap;
}
public int compareTo(JassValue o) {
return o.getName().toLowerCase().compareTo(this.name.toLowerCase())*-1;
}
}
Ich denke die nativen Funktionen und so brauche ich eventuell garnicht so einzuscannen, habe aber keine Idee, wie ich das sonst realisieren soll.
Das gleich passiert bei dem Dokument, welches vom User eingescannt wird. Alle Funktionen etc. werden als JassValue Objekte eingelesen um später zu überprüfen ob diese vorhanden sind.
Das ist ja leider aber nur der Anfang ... auf Dinge wie das Überprüfen ob der richtige Typ übergeben wurde oder Fehler in der Schreibweise habe ich noch garnicht geachtet.
Meine Fragen nun:
- Gibt es eventuell Tutorials zum schreiben von Syntax Checkern.
- Habt ihr eventuell Tips, wie ich das ganze besser angehen könnte.
- Ist mein Ansatz total falsch?
Über jegliche Hilfe wäre ich sehr glücklich
(Das ganze mache ich in meiner Freizeit , zum üben und weil es spaß macht. Also ist es auch nicht so schlimm wenn keiner weiter weiß
MFG
Timo