📄 parser.java
字号:
import java.math.*;
import java.util.*;
import java.io.*;
/**
* Die Klasse Parser kann ein Programm in der Programmiersprache RIES
* syntaktisch analysieren und semantisch äquivalenten Javacode
* erzeugen.
*
* @author Michael Wels, Thorsten Gutbrod
* @since 08.07.2002
* @version Release 2.03
*/
public class Parser
{
// Anzahl der Eingabeelemente
private int argsLength = 0;
// zeigt erste Funktion an
private boolean isErsteFunktion = true;
// diese Funktion im Riescode wird gerade geparst
private String aktuelleFunktion;
// Scanner
private Scanner scanner;
// aktuell zu parsender Token
private Token aktuellerToken;
// Fehlersammlung
private Vector errorVector;
// Variablen, an die im bestimmten Kontext nichts zugewiesen werden darf
private Vector forVector;
// Vector zur 躡erwachung aller bisher geparsten Funktionsnamen
private Vector funktionsNamen = new Vector();
// erzeugter Javacode
private String javaCode = new String();
// Uebersetzungstabellen fuer Variablen- und Arraynamen
private TransHash varTrans;
private TransHash arrayTrans;
private TransHash outputTrans;
private int zaehler=0;
// Tabelle aller deklarierten Funktionen/Funktionsnamen
private TransHash funktionsTabelle;
// Tabelle aller deklarierten RiesArraysnamen
private TransHash RiesArrayTabelle;
// Variable fuer das Einruecken an jedem Zeilenanfang
private int tabs = 0;
// Konstanten zur Identifikation gewisser Tokentypen
private final int REST = 0;
private final int SCHLUESSEL = 1;
private final int ARRAY = 2;
private final int ZAHL = 3;
private final int FUNKTION = 4;
private final int VEROP = 5;
private final int AROP = 6;
private final int TRENNER = 7;
private final int RIESARRAY=8;
/**
* Der Konstruktor übernimmt ein Scannerobjekt, welches im
* Verlauf der Verarbeitung den Tokenstrom realisiert.
*
* @param Scanner
*/
public Parser(Scanner newScanner) {
// Initialisierung einiger Membervariablen
scanner = newScanner;
errorVector = new Vector();
forVector = new Vector();
funktionsTabelle = scanner.getFunktionsnamen();
RiesArrayTabelle=scanner.getRiesArrayNamen();
}
/**
* Methode zum Einfügen der nötigen Leerzeichen am Anfang jeder
* Zeile des erzeugten Codes, um ihn lesbarer zu machen.
*
* @return String
*/
private String insertTabs() {
// Zwischenspeicher fuer die Ausgabe
String ergebnis = new String();
// Einfuegen hinreichend vieler Leerzeichen
for (int i = 0; i < tabs; i++) {
ergebnis += " ";
}
// Rueckgabe
return ergebnis;
}
/**
* Methode zum Parsen verschiedenartiger Anweisungen, z.B. Verbund,
* while-Schleife, etc.
*
* @return String
* @exception ParserException
*/
private String parseAnweisung() throws ParserException {
// Zwischenspeicher fuer die Javacodeausgabe
String ergebnis = new String();
/*// 'try', weil mein vorlaeufiger Scanner eine 'NullPointerException'
// erzeugt, falls der Tokenstream endet
try {*/
// Zwischenspeicher fuer das aktuelle Token
aktuellerToken = scanner.touchToken();
if(aktuellerToken.toString().equals("print"))
{
ergebnis=parseDebug();
}
/*
else if(aktuellerToken.toString().equals("get"))
{
ergebnis=parseGet();
}*/
else if (aktuellerToken.toString().equals("begin")) {
// jetzt kommt eine Verbundanweisung
ergebnis = parseVerbund();
} else if (aktuellerToken.toString().equals("if")) {
// es kommt eine if-Anweisung
ergebnis = parseIf();
} else if (aktuellerToken.toString().equals("while")) {
// es kommt eine while-Schleife
ergebnis = parseWhile();
} else if (aktuellerToken.toString().equals("for")) {
// es kommt eine for-Schleife
ergebnis = parseFor();
}
else if (aktuellerToken.toString().equals("end")) {
ergebnis += insertTabs() + "\n";
}
else {
// es kommt eine normale Zuweisung
ergebnis = parseZuweisung() + ";\n";
}
/*// Abfangen der Exception, die mein vorlaeufiger Scanner erzeugt
} catch (IndexOutOfBoundsException e) {
throw new ParserException("Fehler in \"parseAnweisung()\"\n" +
"Unerwartetes Dateiende in Zeile " +
aktuellerToken.getLineNumber(),
aktuellerToken);
}*/
// Rueckgabe des Javacodes in einem String
return ergebnis;
}
/**
* Methode zum Parsen einer print-Anweisung.
*
* @return String
* @exception ParserException
*/
private String parseDebug() throws ParserException
{
String ergebnis=insertTabs();
aktuellerToken=scanner.getNextToken();
// da es sich um eine print-Anweisung handeln soll, muss jetzt ein
// 'print' kommen
if(aktuellerToken.toString().equals("print"))
{
//ergebnis+="System.out.println(";
aktuellerToken = scanner.getNextToken(); // Token abholen
// muss jetzt '(' kommen
if (aktuellerToken.equals("(")) {}
//ergebnis += "(";
else {
/* . Es handelt sich um ein falsches Token.
*/
throw new ParserException("Start einer Parameterliste mit"
+" '(' erwartet in Zeile "
+aktuellerToken.getLineNumber(),
aktuellerToken);
}
aktuellerToken=scanner.getNextToken();
//aktuellerToken=scanner.touchToken();
//jetzt muss " kommen
if(aktuellerToken.equals("\""))
{
try{
//String wird geparst
String out=parseString();
if(outputTrans.get(out)!=null){
String zeile=outputTrans.get(out).toString();
//if(zeile.indexOf("System")!=-1)
//{
// ergebnis+=zeile+"println(";
//}
//else
//{
ergebnis+=outputTrans.get(out).toString()+".write(";
//}
}
else{
outputTrans.put(out,"_"+new Integer(zaehler).toString());
zaehler++;
ergebnis+=outputTrans.get(out).toString()+".write(";
}
}catch (Exception e){System.out.println(e.toString());}
aktuellerToken=scanner.getNextToken();
}
else if(aktuellerToken.equals("stdout"))
{
ergebnis+="System.out.print(";
aktuellerToken=scanner.getNextToken();
}
else{
throw new ParserException(
" \" erwartet in Zeile "
+aktuellerToken.getLineNumber(),
aktuellerToken);
}
//jetzt muss ',' kommen
if(aktuellerToken.equals(","))
{
aktuellerToken=scanner.getNextToken();
//jetzt muss " kommen
if(aktuellerToken.equals("\""))
{
/* ergebnis+="\"";
while(!(aktuellerToken=scanner.getNextToken()).equals("\""))
{
ergebnis+=aktuellerToken.toString();
}
ergebnis+="\"+";
*/
ergebnis+="\""+parseString()+"\"";
ergebnis+="+";
aktuellerToken=scanner.getNextToken();
//jetzt muss ',' kommen
if(aktuellerToken.equals(","))
{
//String variable=scanner.getNextToken().toString();
//ergebnis+=variable+"\" ";
//ergebnis+=parseWertvariable();
ergebnis+=parseWertausdruck();
ergebnis+=".toString());\n";
}
else {
//////Aenderung 22.03.03 ///////////
//ergebnis+=parseWertausdruck();
//ergebnis+=".toString());\n";
aktuellerToken=scanner.getNextToken();
//jetzt muss ')' kommmen
if(aktuellerToken.equals(")")){}
}
}}
else {
throw new ParserException(
" ',' erwartet in Zeile "
+aktuellerToken.getLineNumber(),
aktuellerToken);
}
aktuellerToken=scanner.getNextToken();
//System.out.println(aktuellerToken.toString());
if(aktuellerToken.equals(")")){}
else {
throw new ParserException("Ende einer Parameterliste mit"
+" ')' erwartet in Zeile "
+aktuellerToken.getLineNumber(),
aktuellerToken);
}
/*else{
ergebnis+=parseWertausdruck();
ergebnis+=".toString());\n";
aktuellerToken=scanner.getNextToken();
if(aktuellerToken.equals(")")){}
}*/
}
//ergebnis+=parseAnweisung();
return ergebnis;
}
/**
* Methode zum Parsen eines Strings
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -