diff --git a/.gitignore b/.gitignore index 9bea433..5b08b20 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,19 @@ +# IntelliJ folders +**/.idea/ +# IntelliJ files +**/*.iml + +# Java Compiler output +**/bin/ + +# Eclipse files +**/.classpath +**/.project + +# Eclipse folders +**/.externalToolBuilders/ +**/.settings/ + +# macOS files .DS_Store diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/lib/jflex-1.6.1.jar b/ÜB-Praxis-LL1-Parser für X-Leer/lib/jflex-1.6.1.jar new file mode 100644 index 0000000..001e0e5 Binary files /dev/null and b/ÜB-Praxis-LL1-Parser für X-Leer/lib/jflex-1.6.1.jar differ diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/lib/jflexant.xml b/ÜB-Praxis-LL1-Parser für X-Leer/lib/jflexant.xml new file mode 100644 index 0000000..a5dc0cf --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/lib/jflexant.xml @@ -0,0 +1,13 @@ + + + + Generate Scanner from lex-files + + + + + + + + + \ No newline at end of file diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/FloatConstToken.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/FloatConstToken.java new file mode 100644 index 0000000..583cf19 --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/FloatConstToken.java @@ -0,0 +1,28 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * - Token-Definition floatConst + * + * ********************************************** + */ + +package de.dhbw.compiler.xparser; + +public class FloatConstToken extends Token { + + private double value=0.0; + + public FloatConstToken(int type, String text, int line, int column, double value) { + super(type,text,line,column); + this.value = value; + } + + public double getValue() { + return value; + } + + +} diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/IntConstToken.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/IntConstToken.java new file mode 100644 index 0000000..b6d6b79 --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/IntConstToken.java @@ -0,0 +1,28 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * - Token-Definition intConst + * + * ********************************************** + */ + +package de.dhbw.compiler.xparser; + +public class IntConstToken extends Token { + + private int value=0; + + public IntConstToken(int type, String text, int line, int column, int value) { + super(type,text,line,column); + this.value = value; + } + + public int getValue() { + return value; + } + + +} diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/JFlexXScanner.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/JFlexXScanner.java new file mode 100644 index 0000000..6eab8a5 --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/JFlexXScanner.java @@ -0,0 +1,991 @@ +/* The following code was generated by JFlex 1.6.1 */ + +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis X Abstiegsparser + * - Scanner-Definition + * + * ********************************************** + */ + + +package de.dhbw.compiler.xparser; + + +/** + * This class is a scanner generated by + * JFlex 1.6.1 + * from the specification file C:/Users/eisenbiegler/Dropbox/workspace_�b/�B-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/XParser/JFlexXScanner.lex + */ +public final class JFlexXScanner { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int YYINITIAL = 0; + public static final int INT = 2; + public static final int FRACTION = 4; + public static final int EXPVZ = 6; + public static final int EXP = 8; + public static final int STRING = 10; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 + }; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\10\0\3\42\1\0\2\42\22\0\1\43\1\0\1\41\5\0\1\24"+ + "\1\25\1\20\1\16\1\0\1\17\1\35\1\21\1\40\11\37\1\22"+ + "\1\32\1\26\1\23\1\27\2\0\4\36\1\45\25\36\1\0\1\44"+ + "\4\0\1\3\1\33\1\36\1\4\1\2\1\11\1\15\1\30\1\6"+ + "\2\36\1\12\1\34\1\7\1\13\1\5\1\36\1\1\1\14\1\10"+ + "\2\36\1\31\3\36\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uff95\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\6\0\1\1\10\2\1\3\1\4\1\5\1\6\1\7"+ + "\1\10\1\11\1\12\1\13\1\14\1\2\1\15\1\2"+ + "\1\16\1\17\1\20\1\21\1\22\2\23\1\24\1\25"+ + "\2\26\1\27\2\30\1\31\1\32\1\33\1\34\1\35"+ + "\1\36\1\37\1\35\5\2\1\40\4\2\1\0\1\41"+ + "\2\2\1\42\1\0\1\43\1\0\1\44\1\45\1\46"+ + "\1\2\1\47\3\2\1\50\2\2\1\51\1\2\1\0"+ + "\2\2\1\52\1\53\2\2\1\54\2\2\1\55\2\2"+ + "\1\56\1\2\1\57\1\2\1\60\1\61\1\2\1\62"+ + "\1\63"; + + private static int [] zzUnpackAction() { + int [] result = new int[103]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\46\0\114\0\162\0\230\0\276\0\344\0\u010a"+ + "\0\u0130\0\u0156\0\u017c\0\u01a2\0\u01c8\0\u01ee\0\u0214\0\344"+ + "\0\344\0\344\0\u023a\0\u0260\0\344\0\344\0\344\0\344"+ + "\0\344\0\u0286\0\344\0\u02ac\0\344\0\344\0\u02d2\0\344"+ + "\0\u02f8\0\344\0\u031e\0\344\0\344\0\344\0\u0344\0\344"+ + "\0\344\0\u036a\0\344\0\344\0\344\0\344\0\344\0\344"+ + "\0\344\0\u0390\0\u03b6\0\u03dc\0\u0402\0\u0428\0\u044e\0\u0156"+ + "\0\u0474\0\u049a\0\u04c0\0\u04e6\0\u050c\0\344\0\u0532\0\u0558"+ + "\0\344\0\u057e\0\344\0\u05a4\0\344\0\344\0\344\0\u05ca"+ + "\0\u0156\0\u05f0\0\u0616\0\u063c\0\u0156\0\u0662\0\u0688\0\u0156"+ + "\0\u06ae\0\u06d4\0\u06fa\0\u0720\0\u0156\0\u0156\0\u0746\0\u076c"+ + "\0\u0156\0\u0792\0\u07b8\0\344\0\u07de\0\u0804\0\u0156\0\u082a"+ + "\0\u0156\0\u0850\0\u0156\0\u0156\0\u0876\0\u0156\0\u0156"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[103]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\1\7\1\10\1\11\2\12\1\13\1\14\1\12\1\15"+ + "\1\16\2\12\1\17\1\12\1\20\1\21\1\22\1\23"+ + "\1\24\1\25\1\26\1\27\1\30\1\31\1\12\1\32"+ + "\1\33\1\34\1\12\1\35\1\12\1\36\1\37\1\40"+ + "\2\41\1\7\1\12\2\42\1\43\32\42\1\44\1\42"+ + "\2\45\4\42\1\43\2\46\1\47\34\46\2\50\4\46"+ + "\1\47\17\51\1\52\17\51\1\53\1\54\5\51\37\55"+ + "\2\56\5\55\1\57\15\60\4\57\1\60\5\57\2\60"+ + "\1\57\4\60\2\57\1\61\1\57\1\60\1\62\1\60"+ + "\47\0\1\12\1\63\13\12\12\0\2\12\1\0\2\12"+ + "\1\0\3\12\4\0\1\12\1\0\6\12\1\64\2\12"+ + "\1\65\3\12\12\0\2\12\1\0\2\12\1\0\3\12"+ + "\4\0\1\12\1\0\15\12\12\0\2\12\1\0\2\12"+ + "\1\0\3\12\4\0\1\12\1\0\1\66\14\12\12\0"+ + "\2\12\1\0\2\12\1\0\3\12\4\0\1\12\1\0"+ + "\6\12\1\67\1\12\1\70\4\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\15\12\12\0"+ + "\1\71\1\12\1\0\2\12\1\0\3\12\4\0\1\12"+ + "\1\0\11\12\1\72\1\73\2\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\7\12\1\74"+ + "\5\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\20\0\1\75\50\0\1\76\23\0\15\12\12\0"+ + "\1\77\1\12\1\0\2\12\1\0\3\12\4\0\1\12"+ + "\1\0\1\12\1\100\13\12\12\0\2\12\1\0\2\12"+ + "\1\0\3\12\4\0\1\12\35\0\1\101\52\0\2\41"+ + "\21\0\1\102\17\0\2\103\24\0\1\104\17\0\2\105"+ + "\44\0\1\106\1\54\46\0\1\107\5\0\2\12\1\110"+ + "\12\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\1\0\3\12\1\111\11\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\13\12\1\112"+ + "\1\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\1\0\5\12\1\113\4\12\1\114\2\12\12\0"+ + "\2\12\1\0\2\12\1\0\3\12\4\0\1\12\1\0"+ + "\7\12\1\115\5\12\12\0\2\12\1\0\2\12\1\0"+ + "\3\12\4\0\1\12\1\0\1\12\1\116\13\12\12\0"+ + "\2\12\1\0\2\12\1\0\3\12\4\0\1\12\1\0"+ + "\12\12\1\117\2\12\12\0\2\12\1\0\2\12\1\0"+ + "\3\12\4\0\1\12\1\0\1\120\14\12\12\0\2\12"+ + "\1\0\2\12\1\0\3\12\4\0\1\12\1\0\1\121"+ + "\14\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\20\75\1\122\25\75\1\0\5\12\1\123\7\12"+ + "\12\0\2\12\1\0\2\12\1\0\3\12\4\0\1\12"+ + "\1\0\14\12\1\124\12\0\2\12\1\0\2\12\1\0"+ + "\3\12\4\0\1\12\37\0\2\103\44\0\2\105\6\0"+ + "\3\12\1\125\11\12\12\0\2\12\1\0\2\12\1\0"+ + "\3\12\4\0\1\12\1\0\1\12\1\126\13\12\12\0"+ + "\2\12\1\0\2\12\1\0\3\12\4\0\1\12\1\0"+ + "\6\12\1\127\6\12\12\0\2\12\1\0\2\12\1\0"+ + "\3\12\4\0\1\12\1\0\14\12\1\130\12\0\2\12"+ + "\1\0\2\12\1\0\3\12\4\0\1\12\1\0\6\12"+ + "\1\131\6\12\12\0\2\12\1\0\2\12\1\0\3\12"+ + "\4\0\1\12\1\0\2\12\1\132\12\12\12\0\2\12"+ + "\1\0\2\12\1\0\3\12\4\0\1\12\1\0\5\12"+ + "\1\133\7\12\12\0\2\12\1\0\2\12\1\0\3\12"+ + "\4\0\1\12\20\75\1\122\1\134\24\75\1\0\11\12"+ + "\1\135\3\12\12\0\2\12\1\0\2\12\1\0\3\12"+ + "\4\0\1\12\1\0\5\12\1\136\7\12\12\0\2\12"+ + "\1\0\2\12\1\0\3\12\4\0\1\12\1\0\7\12"+ + "\1\137\5\12\12\0\2\12\1\0\2\12\1\0\3\12"+ + "\4\0\1\12\1\0\1\140\14\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\7\12\1\141"+ + "\5\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\1\0\6\12\1\142\6\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\1\12\1\143"+ + "\13\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\1\0\6\12\1\144\6\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\2\12\1\145"+ + "\12\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\1\0\14\12\1\146\12\0\2\12\1\0\2\12"+ + "\1\0\3\12\4\0\1\12\1\0\15\12\12\0\2\12"+ + "\1\0\1\12\1\147\1\0\3\12\4\0\1\12"; + + private static int [] zzUnpackTrans() { + int [] result = new int[2204]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unknown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\6\0\1\11\10\1\3\11\2\1\5\11\1\1\1\11"+ + "\1\1\2\11\1\1\1\11\1\1\1\11\1\1\3\11"+ + "\1\1\2\11\1\1\7\11\13\1\1\0\1\11\2\1"+ + "\1\11\1\0\1\11\1\0\3\11\12\1\1\0\11\1"+ + "\1\11\13\1"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[103]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /** + * The number of occupied positions in zzBuffer beyond zzEndRead. + * When a lead/high surrogate has been read from the input stream + * into the final zzBuffer position, this will have a value of 1; + * otherwise, it will have a value of 0. + */ + private int zzFinalHighSurrogate = 0; + + /* user code: */ + private int intvalue=0; + private String textvalue =""; + private int fracvalue=0; + private int fraclength=0; + private int expvalue=0; + private int expsign=1; + private int startline =0; + private int startcolumn =0; + private String stringvalue=""; + + + /** + * Creates a new scanner + * + * @param in the java.io.Reader to read input from. + */ + public JFlexXScanner(java.io.Reader in) { + this.zzReader = in; + } + + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x110000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 140) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length - zzFinalHighSurrogate) { + /* if not: blow it up */ + char newBuffer[] = new char[zzBuffer.length*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + } + + /* fill the buffer with new input */ + int requested = zzBuffer.length - zzEndRead; + int numRead = zzReader.read(zzBuffer, zzEndRead, requested); + + /* not supposed to occur according to specification of java.io.Reader */ + if (numRead == 0) { + throw new java.io.IOException("Reader returned 0 characters. See JFlex examples for workaround."); + } + if (numRead > 0) { + zzEndRead += numRead; + /* If numRead == requested, we might have requested to few chars to + encode a full Unicode character. We assume that a Reader would + otherwise never return half characters. */ + if (numRead == requested) { + if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) { + --zzEndRead; + zzFinalHighSurrogate = 1; + } + } + /* potentially more input available */ + return false; + } + + /* numRead < 0 ==> end of stream */ + return true; + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * Internal scan buffer is resized down to its initial length, if it has grown. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEOFDone = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = 0; + zzFinalHighSurrogate = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + if (zzBuffer.length > ZZ_BUFFERSIZE) + zzBuffer = new char[ZZ_BUFFERSIZE]; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public Token nextToken() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + boolean zzR = false; + int zzCh; + int zzCharCount; + for (zzCurrentPosL = zzStartRead ; + zzCurrentPosL < zzMarkedPosL ; + zzCurrentPosL += zzCharCount ) { + zzCh = Character.codePointAt(zzBufferL, zzCurrentPosL, zzMarkedPosL); + zzCharCount = Character.charCount(zzCh); + switch (zzCh) { + case '\u000B': + case '\u000C': + case '\u0085': + case '\u2028': + case '\u2029': + yyline++; + yycolumn = 0; + zzR = false; + break; + case '\r': + yyline++; + yycolumn = 0; + zzR = true; + break; + case '\n': + if (zzR) + zzR = false; + else { + yyline++; + yycolumn = 0; + } + break; + default: + zzR = false; + yycolumn += zzCharCount; + } + } + + if (zzR) { + // peek one character ahead if it is \n (if we have counted one line too much) + boolean zzPeek; + if (zzMarkedPosL < zzEndReadL) + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + else if (zzAtEOF) + zzPeek = false; + else { + boolean eof = zzRefill(); + zzEndReadL = zzEndRead; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + if (eof) + zzPeek = false; + else + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + } + if (zzPeek) yyline--; + } + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; + + // set up zzAction for empty match case: + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + } + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + switch (zzLexicalState) { + case INT: { + yybegin(YYINITIAL); + yypushback(1); + return new IntConstToken(Token.INTCONST, textvalue, startline, startcolumn, intvalue); + } + case 104: break; + case FRACTION: { + yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn,intvalue+fracvalue/Math.pow(10,fraclength)); + } + case 105: break; + case EXPVZ: { + yybegin(YYINITIAL); + yypushback(1); + return new Token(Token.INVALID, textvalue, startline, startcolumn); + } + case 106: break; + case EXP: { + yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn, (intvalue+fracvalue/Math.pow(10,fraclength))*Math.pow(10,expvalue*expsign)); + } + case 107: break; + case STRING: { + yybegin(YYINITIAL); return new Token(Token.INVALID, textvalue, startline, startcolumn); + } + case 108: break; + default: + { + return new Token(Token.EOF, yytext(), yyline+1, yycolumn+1); + } + } + } + else { + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 1: + { return new Token(Token.INVALID, yytext(), yyline+1, yycolumn+1); + } + case 52: break; + case 2: + { return new Token(Token.ID, yytext(), yyline+1, yycolumn+1); + } + case 53: break; + case 3: + { return new Token(Token.PLUS, yytext(), yyline+1, yycolumn+1); + } + case 54: break; + case 4: + { return new Token(Token.MINUS, yytext(), yyline+1, yycolumn+1); + } + case 55: break; + case 5: + { return new Token(Token.MULT, yytext(), yyline+1, yycolumn+1); + } + case 56: break; + case 6: + { return new Token(Token.DIV, yytext(), yyline+1, yycolumn+1); + } + case 57: break; + case 7: + { return new Token(Token.COLON, yytext(), yyline+1, yycolumn+1); + } + case 58: break; + case 8: + { return new Token(Token.EQUALS, yytext(), yyline+1, yycolumn+1); + } + case 59: break; + case 9: + { return new Token(Token.LBR, yytext(), yyline+1, yycolumn+1); + } + case 60: break; + case 10: + { return new Token(Token.RBR, yytext(), yyline+1, yycolumn+1); + } + case 61: break; + case 11: + { return new Token(Token.LESS, yytext(), yyline+1, yycolumn+1); + } + case 62: break; + case 12: + { return new Token(Token.MORE, yytext(), yyline+1, yycolumn+1); + } + case 63: break; + case 13: + { return new Token(Token.SEMICOLON, yytext(), yyline+1, yycolumn+1); + } + case 64: break; + case 14: + { return new Token(Token.DOT, yytext(), yyline+1, yycolumn+1); + } + case 65: break; + case 15: + { yybegin(INT); textvalue=yytext(); startline=yyline+1; startcolumn=yycolumn+1; + intvalue=yytext().charAt(0)-'0'; fracvalue=0; fraclength=0; expvalue=0; + } + case 66: break; + case 16: + { return new IntConstToken(Token.INTCONST, yytext(), yyline+1, yycolumn+1, 0); + } + case 67: break; + case 17: + { yybegin(STRING); textvalue="\""; stringvalue=""; startline=yyline+1; startcolumn=yycolumn+1; + } + case 68: break; + case 18: + { /* eat whitespace */ + } + case 69: break; + case 19: + { yybegin(YYINITIAL); + yypushback(1); + return new IntConstToken(Token.INTCONST, textvalue, startline, startcolumn, intvalue); + } + case 70: break; + case 20: + { yybegin(FRACTION); + textvalue+=yytext(); + } + case 71: break; + case 21: + { intvalue = 10*intvalue + yytext().charAt(0)-'0'; + textvalue+=yytext(); + } + case 72: break; + case 22: + { yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn,intvalue+fracvalue/Math.pow(10,fraclength)); + } + case 73: break; + case 23: + { fracvalue= 10*fracvalue+ yytext().charAt(0)-'0'; + fraclength++; + textvalue+=yytext(); + } + case 74: break; + case 24: + { yybegin(YYINITIAL); + yypushback(1); + return new Token(Token.INVALID, textvalue, startline, startcolumn); + } + case 75: break; + case 25: + { yybegin(EXP); expvalue=yytext().charAt(0)-'0'; expsign=1; textvalue+=yytext(); + } + case 76: break; + case 26: + { yybegin(YYINITIAL); + return new FloatConstToken(Token.FLOATCONST, textvalue+yytext(), startline, startcolumn,intvalue+fracvalue/Math.pow(10,fraclength)); + } + case 77: break; + case 27: + { yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn, (intvalue+fracvalue/Math.pow(10,fraclength))*Math.pow(10,expvalue*expsign)); + } + case 78: break; + case 28: + { expvalue = 10* expvalue + yytext().charAt(0)-'0'; textvalue+=yytext(); + } + case 79: break; + case 29: + { yybegin(YYINITIAL); return new Token(Token.INVALID, textvalue+yytext(), startline, startcolumn); + } + case 80: break; + case 30: + { textvalue+=yytext(); stringvalue+=yytext(); + } + case 81: break; + case 31: + { yybegin(YYINITIAL); return new StringConstToken(Token.STRINGCONST, textvalue+"\"", startline, startcolumn, stringvalue); + } + case 82: break; + case 32: + { return new Token(Token.IF, yytext(), yyline+1, yycolumn+1); + } + case 83: break; + case 33: + { return new Token(Token.ASSIGN, yytext(), yyline+1, yycolumn+1); + } + case 84: break; + case 34: + // lookahead expression with fixed base length + zzMarkedPos = Character.offsetByCodePoints + (zzBufferL, zzStartRead, zzEndRead - zzStartRead, zzStartRead, 1); + { yybegin(INT); textvalue=yytext(); startline=yyline+1; startcolumn=yycolumn+1; + intvalue=yytext().charAt(0)-'0'; fracvalue=0; fraclength=0; expvalue=0; + } + case 85: break; + case 35: + // lookahead expression with fixed base length + zzMarkedPos = Character.offsetByCodePoints + (zzBufferL, zzStartRead, zzEndRead - zzStartRead, zzStartRead, 1); + { yybegin(EXPVZ); textvalue += yytext(); + } + case 86: break; + case 36: + // lookahead expression with fixed base length + zzMarkedPos = Character.offsetByCodePoints + (zzBufferL, zzStartRead, zzEndRead - zzStartRead, zzStartRead, 1); + { yybegin(EXPVZ); + textvalue+=yytext(); + } + case 87: break; + case 37: + { yybegin(EXP); expvalue=yytext().charAt(1)-'0'; expsign=-1; textvalue+=yytext(); + } + case 88: break; + case 38: + { textvalue+="\\\""; stringvalue+="\""; + } + case 89: break; + case 39: + { return new Token(Token.END, yytext(), yyline+1, yycolumn+1); + } + case 90: break; + case 40: + { return new Token(Token.INT, yytext(), yyline+1, yycolumn+1); + } + case 91: break; + case 41: + { return new Token(Token.FOR, yytext(), yyline+1, yycolumn+1); + } + case 92: break; + case 42: + { return new Token(Token.READ, yytext(), yyline+1, yycolumn+1); + } + case 93: break; + case 43: + { return new Token(Token.ELSE, yytext(), yyline+1, yycolumn+1); + } + case 94: break; + case 44: + { return new Token(Token.THEN, yytext(), yyline+1, yycolumn+1); + } + case 95: break; + case 45: + { /* eat comments */ + } + case 96: break; + case 46: + { return new Token(Token.PRINT, yytext(), yyline+1, yycolumn+1); + } + case 97: break; + case 47: + { return new Token(Token.FLOAT, yytext(), yyline+1, yycolumn+1); + } + case 98: break; + case 48: + { return new Token(Token.WHILE, yytext(), yyline+1, yycolumn+1); + } + case 99: break; + case 49: + { return new Token(Token.BEGIN, yytext(), yyline+1, yycolumn+1); + } + case 100: break; + case 50: + { return new Token(Token.STRING, yytext(), yyline+1, yycolumn+1); + } + case 101: break; + case 51: + { return new Token(Token.PROGRAM, yytext(), yyline+1, yycolumn+1); + } + case 102: break; + default: + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/JFlexXScanner.java~ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/JFlexXScanner.java~ new file mode 100644 index 0000000..7978d79 --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/JFlexXScanner.java~ @@ -0,0 +1,985 @@ +/* The following code was generated by JFlex 1.6.1 */ + +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * - Scanner-Definition + * + * ********************************************** + */ + + +package de.dhbw.compiler.xparser; + + +/** + * This class is a scanner generated by + * JFlex 1.6.1 + * from the specification file C:/Users/eisenbiegler/Dropbox/workspace_üb/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/XParser/JFlexXScanner.lex + */ +public final class JFlexXScanner { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int YYINITIAL = 0; + public static final int INT = 2; + public static final int FRACTION = 4; + public static final int EXPVZ = 6; + public static final int EXP = 8; + public static final int STRING = 10; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 + }; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\10\0\3\42\1\0\2\42\22\0\1\43\1\0\1\41\5\0\1\24"+ + "\1\25\1\20\1\16\1\0\1\17\1\35\1\21\1\40\11\37\1\22"+ + "\1\32\1\26\1\23\1\27\2\0\4\36\1\45\25\36\1\0\1\44"+ + "\4\0\1\3\1\33\1\36\1\4\1\2\1\11\1\15\1\30\1\6"+ + "\2\36\1\12\1\34\1\7\1\13\1\5\1\36\1\1\1\14\1\10"+ + "\2\36\1\31\3\36\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uff95\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\6\0\1\1\10\2\1\3\1\4\1\5\1\6\1\7"+ + "\1\10\1\11\1\12\1\13\1\14\1\2\1\15\1\2"+ + "\1\16\1\17\1\20\1\21\1\22\2\23\1\24\1\25"+ + "\1\26\1\27\1\30\2\31\1\32\1\33\1\34\1\35"+ + "\1\36\1\37\1\40\1\36\5\2\1\41\4\2\1\0"+ + "\1\42\2\2\1\43\1\44\1\45\1\46\1\2\1\47"+ + "\3\2\1\50\2\2\1\51\1\2\1\0\2\2\1\52"+ + "\1\53\2\2\1\54\2\2\1\55\2\2\1\56\1\2"+ + "\1\57\1\2\1\60\1\61\1\2\1\62\1\63"; + + private static int [] zzUnpackAction() { + int [] result = new int[100]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\46\0\114\0\162\0\230\0\276\0\344\0\u010a"+ + "\0\u0130\0\u0156\0\u017c\0\u01a2\0\u01c8\0\u01ee\0\u0214\0\344"+ + "\0\344\0\344\0\u023a\0\u0260\0\344\0\344\0\344\0\344"+ + "\0\344\0\u0286\0\344\0\u02ac\0\344\0\344\0\u02d2\0\344"+ + "\0\u02f8\0\344\0\u031e\0\344\0\344\0\344\0\344\0\344"+ + "\0\344\0\u0344\0\344\0\344\0\344\0\344\0\344\0\344"+ + "\0\344\0\u036a\0\u0390\0\u03b6\0\u03dc\0\u0402\0\u0428\0\u0156"+ + "\0\u044e\0\u0474\0\u049a\0\u04c0\0\u04e6\0\344\0\u050c\0\u0532"+ + "\0\344\0\344\0\344\0\344\0\u0558\0\u0156\0\u057e\0\u05a4"+ + "\0\u05ca\0\u0156\0\u05f0\0\u0616\0\u0156\0\u063c\0\u0662\0\u0688"+ + "\0\u06ae\0\u0156\0\u0156\0\u06d4\0\u06fa\0\u0156\0\u0720\0\u0746"+ + "\0\344\0\u076c\0\u0792\0\u0156\0\u07b8\0\u0156\0\u07de\0\u0156"+ + "\0\u0156\0\u0804\0\u0156\0\u0156"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[100]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\1\7\1\10\1\11\2\12\1\13\1\14\1\12\1\15"+ + "\1\16\2\12\1\17\1\12\1\20\1\21\1\22\1\23"+ + "\1\24\1\25\1\26\1\27\1\30\1\31\1\12\1\32"+ + "\1\33\1\34\1\12\1\35\1\12\1\36\1\37\1\40"+ + "\2\41\1\7\1\12\2\42\1\43\32\42\1\44\1\42"+ + "\2\45\4\42\1\43\2\46\1\47\34\46\2\50\4\46"+ + "\1\47\17\51\1\52\17\51\1\53\1\54\5\51\37\55"+ + "\2\56\5\55\1\57\15\60\4\57\1\60\5\57\2\60"+ + "\1\57\4\60\2\57\1\61\1\57\1\60\1\62\1\60"+ + "\47\0\1\12\1\63\13\12\12\0\2\12\1\0\2\12"+ + "\1\0\3\12\4\0\1\12\1\0\6\12\1\64\2\12"+ + "\1\65\3\12\12\0\2\12\1\0\2\12\1\0\3\12"+ + "\4\0\1\12\1\0\15\12\12\0\2\12\1\0\2\12"+ + "\1\0\3\12\4\0\1\12\1\0\1\66\14\12\12\0"+ + "\2\12\1\0\2\12\1\0\3\12\4\0\1\12\1\0"+ + "\6\12\1\67\1\12\1\70\4\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\15\12\12\0"+ + "\1\71\1\12\1\0\2\12\1\0\3\12\4\0\1\12"+ + "\1\0\11\12\1\72\1\73\2\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\7\12\1\74"+ + "\5\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\20\0\1\75\50\0\1\76\23\0\15\12\12\0"+ + "\1\77\1\12\1\0\2\12\1\0\3\12\4\0\1\12"+ + "\1\0\1\12\1\100\13\12\12\0\2\12\1\0\2\12"+ + "\1\0\3\12\4\0\1\12\35\0\1\101\52\0\2\41"+ + "\21\0\1\102\17\0\2\102\44\0\1\103\1\54\46\0"+ + "\1\104\5\0\2\12\1\105\12\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\3\12\1\106"+ + "\11\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\1\0\13\12\1\107\1\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\5\12\1\110"+ + "\4\12\1\111\2\12\12\0\2\12\1\0\2\12\1\0"+ + "\3\12\4\0\1\12\1\0\7\12\1\112\5\12\12\0"+ + "\2\12\1\0\2\12\1\0\3\12\4\0\1\12\1\0"+ + "\1\12\1\113\13\12\12\0\2\12\1\0\2\12\1\0"+ + "\3\12\4\0\1\12\1\0\12\12\1\114\2\12\12\0"+ + "\2\12\1\0\2\12\1\0\3\12\4\0\1\12\1\0"+ + "\1\115\14\12\12\0\2\12\1\0\2\12\1\0\3\12"+ + "\4\0\1\12\1\0\1\116\14\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\20\75\1\117\25\75"+ + "\1\0\5\12\1\120\7\12\12\0\2\12\1\0\2\12"+ + "\1\0\3\12\4\0\1\12\1\0\14\12\1\121\12\0"+ + "\2\12\1\0\2\12\1\0\3\12\4\0\1\12\1\0"+ + "\3\12\1\122\11\12\12\0\2\12\1\0\2\12\1\0"+ + "\3\12\4\0\1\12\1\0\1\12\1\123\13\12\12\0"+ + "\2\12\1\0\2\12\1\0\3\12\4\0\1\12\1\0"+ + "\6\12\1\124\6\12\12\0\2\12\1\0\2\12\1\0"+ + "\3\12\4\0\1\12\1\0\14\12\1\125\12\0\2\12"+ + "\1\0\2\12\1\0\3\12\4\0\1\12\1\0\6\12"+ + "\1\126\6\12\12\0\2\12\1\0\2\12\1\0\3\12"+ + "\4\0\1\12\1\0\2\12\1\127\12\12\12\0\2\12"+ + "\1\0\2\12\1\0\3\12\4\0\1\12\1\0\5\12"+ + "\1\130\7\12\12\0\2\12\1\0\2\12\1\0\3\12"+ + "\4\0\1\12\20\75\1\117\1\131\24\75\1\0\11\12"+ + "\1\132\3\12\12\0\2\12\1\0\2\12\1\0\3\12"+ + "\4\0\1\12\1\0\5\12\1\133\7\12\12\0\2\12"+ + "\1\0\2\12\1\0\3\12\4\0\1\12\1\0\7\12"+ + "\1\134\5\12\12\0\2\12\1\0\2\12\1\0\3\12"+ + "\4\0\1\12\1\0\1\135\14\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\7\12\1\136"+ + "\5\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\1\0\6\12\1\137\6\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\1\12\1\140"+ + "\13\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\1\0\6\12\1\141\6\12\12\0\2\12\1\0"+ + "\2\12\1\0\3\12\4\0\1\12\1\0\2\12\1\142"+ + "\12\12\12\0\2\12\1\0\2\12\1\0\3\12\4\0"+ + "\1\12\1\0\14\12\1\143\12\0\2\12\1\0\2\12"+ + "\1\0\3\12\4\0\1\12\1\0\15\12\12\0\2\12"+ + "\1\0\1\12\1\144\1\0\3\12\4\0\1\12"; + + private static int [] zzUnpackTrans() { + int [] result = new int[2090]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unknown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\6\0\1\11\10\1\3\11\2\1\5\11\1\1\1\11"+ + "\1\1\2\11\1\1\1\11\1\1\1\11\1\1\6\11"+ + "\1\1\7\11\13\1\1\0\1\11\2\1\4\11\12\1"+ + "\1\0\11\1\1\11\13\1"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[100]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /** + * The number of occupied positions in zzBuffer beyond zzEndRead. + * When a lead/high surrogate has been read from the input stream + * into the final zzBuffer position, this will have a value of 1; + * otherwise, it will have a value of 0. + */ + private int zzFinalHighSurrogate = 0; + + /* user code: */ + private int intvalue=0; + private String textvalue =""; + private int fracvalue=0; + private int fraclength=0; + private int expvalue=0; + private int expsign=1; + private int startline =0; + private int startcolumn =0; + private String stringvalue=""; + + + /** + * Creates a new scanner + * + * @param in the java.io.Reader to read input from. + */ + public JFlexXScanner(java.io.Reader in) { + this.zzReader = in; + } + + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x110000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 140) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length - zzFinalHighSurrogate) { + /* if not: blow it up */ + char newBuffer[] = new char[zzBuffer.length*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + } + + /* fill the buffer with new input */ + int requested = zzBuffer.length - zzEndRead; + int numRead = zzReader.read(zzBuffer, zzEndRead, requested); + + /* not supposed to occur according to specification of java.io.Reader */ + if (numRead == 0) { + throw new java.io.IOException("Reader returned 0 characters. See JFlex examples for workaround."); + } + if (numRead > 0) { + zzEndRead += numRead; + /* If numRead == requested, we might have requested to few chars to + encode a full Unicode character. We assume that a Reader would + otherwise never return half characters. */ + if (numRead == requested) { + if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) { + --zzEndRead; + zzFinalHighSurrogate = 1; + } + } + /* potentially more input available */ + return false; + } + + /* numRead < 0 ==> end of stream */ + return true; + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * Internal scan buffer is resized down to its initial length, if it has grown. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEOFDone = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = 0; + zzFinalHighSurrogate = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + if (zzBuffer.length > ZZ_BUFFERSIZE) + zzBuffer = new char[ZZ_BUFFERSIZE]; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public Token nextToken() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + boolean zzR = false; + int zzCh; + int zzCharCount; + for (zzCurrentPosL = zzStartRead ; + zzCurrentPosL < zzMarkedPosL ; + zzCurrentPosL += zzCharCount ) { + zzCh = Character.codePointAt(zzBufferL, zzCurrentPosL, zzMarkedPosL); + zzCharCount = Character.charCount(zzCh); + switch (zzCh) { + case '\u000B': + case '\u000C': + case '\u0085': + case '\u2028': + case '\u2029': + yyline++; + yycolumn = 0; + zzR = false; + break; + case '\r': + yyline++; + yycolumn = 0; + zzR = true; + break; + case '\n': + if (zzR) + zzR = false; + else { + yyline++; + yycolumn = 0; + } + break; + default: + zzR = false; + yycolumn += zzCharCount; + } + } + + if (zzR) { + // peek one character ahead if it is \n (if we have counted one line too much) + boolean zzPeek; + if (zzMarkedPosL < zzEndReadL) + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + else if (zzAtEOF) + zzPeek = false; + else { + boolean eof = zzRefill(); + zzEndReadL = zzEndRead; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + if (eof) + zzPeek = false; + else + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + } + if (zzPeek) yyline--; + } + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; + + // set up zzAction for empty match case: + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + } + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + switch (zzLexicalState) { + case INT: { + yybegin(YYINITIAL); + yypushback(1); + return new IntConstToken(Token.INTCONST, textvalue, startline, startcolumn, intvalue); + } + case 101: break; + case FRACTION: { + yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn,intvalue+fracvalue/Math.pow(10,fraclength)); + } + case 102: break; + case EXPVZ: { + yybegin(YYINITIAL); + yypushback(1); + return new Token(Token.INVALID, textvalue, startline, startcolumn); + } + case 103: break; + case EXP: { + yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn, (intvalue+fracvalue/Math.pow(10,fraclength))*Math.pow(10,expvalue*expsign)); + } + case 104: break; + case STRING: { + yybegin(YYINITIAL); return new Token(Token.INVALID, textvalue, startline, startcolumn); + } + case 105: break; + default: + { + return new Token(Token.EOF, yytext(), yyline+1, yycolumn+1); + } + } + } + else { + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 1: + { return new Token(Token.INVALID, yytext(), yyline+1, yycolumn+1); + } + case 52: break; + case 2: + { return new Token(Token.ID, yytext(), yyline+1, yycolumn+1); + } + case 53: break; + case 3: + { return new Token(Token.PLUS, yytext(), yyline+1, yycolumn+1); + } + case 54: break; + case 4: + { return new Token(Token.MINUS, yytext(), yyline+1, yycolumn+1); + } + case 55: break; + case 5: + { return new Token(Token.MULT, yytext(), yyline+1, yycolumn+1); + } + case 56: break; + case 6: + { return new Token(Token.DIV, yytext(), yyline+1, yycolumn+1); + } + case 57: break; + case 7: + { return new Token(Token.COLON, yytext(), yyline+1, yycolumn+1); + } + case 58: break; + case 8: + { return new Token(Token.EQUALS, yytext(), yyline+1, yycolumn+1); + } + case 59: break; + case 9: + { return new Token(Token.LBR, yytext(), yyline+1, yycolumn+1); + } + case 60: break; + case 10: + { return new Token(Token.RBR, yytext(), yyline+1, yycolumn+1); + } + case 61: break; + case 11: + { return new Token(Token.LESS, yytext(), yyline+1, yycolumn+1); + } + case 62: break; + case 12: + { return new Token(Token.MORE, yytext(), yyline+1, yycolumn+1); + } + case 63: break; + case 13: + { return new Token(Token.SEMICOLON, yytext(), yyline+1, yycolumn+1); + } + case 64: break; + case 14: + { return new Token(Token.DOT, yytext(), yyline+1, yycolumn+1); + } + case 65: break; + case 15: + { yybegin(INT); textvalue=yytext(); startline=yyline+1; startcolumn=yycolumn+1; + intvalue=yytext().charAt(0)-'0'; fracvalue=0; fraclength=0; expvalue=0; + } + case 66: break; + case 16: + { return new IntConstToken(Token.INTCONST, yytext(), yyline+1, yycolumn+1, 0); + } + case 67: break; + case 17: + { yybegin(STRING); textvalue="\""; stringvalue=""; startline=yyline+1; startcolumn=yycolumn+1; + } + case 68: break; + case 18: + { /* eat whitespace */ + } + case 69: break; + case 19: + { yybegin(YYINITIAL); + yypushback(1); + return new IntConstToken(Token.INTCONST, textvalue, startline, startcolumn, intvalue); + } + case 70: break; + case 20: + { yybegin(FRACTION); + textvalue+=yytext(); + } + case 71: break; + case 21: + { intvalue = 10*intvalue + yytext().charAt(0)-'0'; + textvalue+=yytext(); + } + case 72: break; + case 22: + { yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn,intvalue+fracvalue/Math.pow(10,fraclength)); + } + case 73: break; + case 23: + { yybegin(EXPVZ); + textvalue+=yytext(); + } + case 74: break; + case 24: + { fracvalue= 10*fracvalue+ yytext().charAt(0)-'0'; + fraclength++; + textvalue+=yytext(); + } + case 75: break; + case 25: + { yybegin(YYINITIAL); + yypushback(1); + return new Token(Token.INVALID, textvalue, startline, startcolumn); + } + case 76: break; + case 26: + { yybegin(EXP); expvalue=yytext().charAt(0)-'0'; expsign=1; textvalue+=yytext(); + } + case 77: break; + case 27: + { yybegin(YYINITIAL); + return new FloatConstToken(Token.FLOATCONST, textvalue+yytext(), startline, startcolumn,intvalue+fracvalue/Math.pow(10,fraclength)); + } + case 78: break; + case 28: + { yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn, (intvalue+fracvalue/Math.pow(10,fraclength))*Math.pow(10,expvalue*expsign)); + } + case 79: break; + case 29: + { expvalue = 10* expvalue + yytext().charAt(0)-'0'; textvalue+=yytext(); + } + case 80: break; + case 30: + { yybegin(YYINITIAL); return new Token(Token.INVALID, textvalue+yytext(), startline, startcolumn); + } + case 81: break; + case 31: + { textvalue+=yytext(); stringvalue+=yytext(); + } + case 82: break; + case 32: + { yybegin(YYINITIAL); return new StringConstToken(Token.STRINGCONST, textvalue+"\"", startline, startcolumn, stringvalue); + } + case 83: break; + case 33: + { return new Token(Token.IF, yytext(), yyline+1, yycolumn+1); + } + case 84: break; + case 34: + { return new Token(Token.ASSIGN, yytext(), yyline+1, yycolumn+1); + } + case 85: break; + case 35: + // lookahead expression with fixed base length + zzMarkedPos = Character.offsetByCodePoints + (zzBufferL, zzStartRead, zzEndRead - zzStartRead, zzStartRead, 1); + { yybegin(INT); textvalue=yytext(); startline=yyline+1; startcolumn=yycolumn+1; + intvalue=yytext().charAt(0)-'0'; fracvalue=0; fraclength=0; expvalue=0; + } + case 86: break; + case 36: + // lookahead expression with fixed base length + zzMarkedPos = Character.offsetByCodePoints + (zzBufferL, zzStartRead, zzEndRead - zzStartRead, zzStartRead, 1); + { yybegin(EXPVZ); textvalue += yytext(); + } + case 87: break; + case 37: + { yybegin(EXP); expvalue=yytext().charAt(1)-'0'; expsign=-1; textvalue+=yytext(); + } + case 88: break; + case 38: + { textvalue+="\\\""; stringvalue+="\""; + } + case 89: break; + case 39: + { return new Token(Token.END, yytext(), yyline+1, yycolumn+1); + } + case 90: break; + case 40: + { return new Token(Token.INT, yytext(), yyline+1, yycolumn+1); + } + case 91: break; + case 41: + { return new Token(Token.FOR, yytext(), yyline+1, yycolumn+1); + } + case 92: break; + case 42: + { return new Token(Token.READ, yytext(), yyline+1, yycolumn+1); + } + case 93: break; + case 43: + { return new Token(Token.ELSE, yytext(), yyline+1, yycolumn+1); + } + case 94: break; + case 44: + { return new Token(Token.THEN, yytext(), yyline+1, yycolumn+1); + } + case 95: break; + case 45: + { /* eat comments */ + } + case 96: break; + case 46: + { return new Token(Token.PRINT, yytext(), yyline+1, yycolumn+1); + } + case 97: break; + case 47: + { return new Token(Token.FLOAT, yytext(), yyline+1, yycolumn+1); + } + case 98: break; + case 48: + { return new Token(Token.WHILE, yytext(), yyline+1, yycolumn+1); + } + case 99: break; + case 49: + { return new Token(Token.BEGIN, yytext(), yyline+1, yycolumn+1); + } + case 100: break; + case 50: + { return new Token(Token.STRING, yytext(), yyline+1, yycolumn+1); + } + case 101: break; + case 51: + { return new Token(Token.PROGRAM, yytext(), yyline+1, yycolumn+1); + } + case 102: break; + default: + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/JFlexXScanner.lex b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/JFlexXScanner.lex new file mode 100644 index 0000000..5069466 --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/JFlexXScanner.lex @@ -0,0 +1,148 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis X Abstiegsparser + * - Scanner-Definition + * + * ********************************************** + */ + + +package de.dhbw.compiler.xparser; + +%% + +%class JFlexXScanner +%type Token +%function nextToken + + +%unicode +%line +%column + +%public +%final + +%xstate INT, FRACTION, EXPVZ, EXP, STRING + +%{ + private int intvalue=0; + private String textvalue =""; + private int fracvalue=0; + private int fraclength=0; + private int expvalue=0; + private int expsign=1; + private int startline =0; + private int startcolumn =0; + private String stringvalue=""; +%} + + + +%% + +read { return new Token(Token.READ, yytext(), yyline+1, yycolumn+1); } +print { return new Token(Token.PRINT, yytext(), yyline+1, yycolumn+1); } +int { return new Token(Token.INT, yytext(), yyline+1, yycolumn+1); } +float { return new Token(Token.FLOAT, yytext(), yyline+1, yycolumn+1); } +string { return new Token(Token.STRING, yytext(), yyline+1, yycolumn+1); } +\+ { return new Token(Token.PLUS, yytext(), yyline+1, yycolumn+1); } +\- { return new Token(Token.MINUS, yytext(), yyline+1, yycolumn+1); } +\* { return new Token(Token.MULT, yytext(), yyline+1, yycolumn+1); } +\/ { return new Token(Token.DIV, yytext(), yyline+1, yycolumn+1); } +:= { return new Token(Token.ASSIGN, yytext(), yyline+1, yycolumn+1); } +\( { return new Token(Token.LBR, yytext(), yyline+1, yycolumn+1); } +\) { return new Token(Token.RBR, yytext(), yyline+1, yycolumn+1); } +\< { return new Token(Token.LESS, yytext(), yyline+1, yycolumn+1); } +> { return new Token(Token.MORE, yytext(), yyline+1, yycolumn+1); } += { return new Token(Token.EQUALS, yytext(), yyline+1, yycolumn+1); } +if { return new Token(Token.IF, yytext(), yyline+1, yycolumn+1); } +then { return new Token(Token.THEN, yytext(), yyline+1, yycolumn+1); } +else { return new Token(Token.ELSE, yytext(), yyline+1, yycolumn+1); } +while { return new Token(Token.WHILE, yytext(), yyline+1, yycolumn+1); } +for { return new Token(Token.FOR, yytext(), yyline+1, yycolumn+1); } +; { return new Token(Token.SEMICOLON, yytext(), yyline+1, yycolumn+1); } +begin { return new Token(Token.BEGIN, yytext(), yyline+1, yycolumn+1); } +end { return new Token(Token.END, yytext(), yyline+1, yycolumn+1); } +program { return new Token(Token.PROGRAM, yytext(), yyline+1, yycolumn+1); } +\. { return new Token(Token.DOT, yytext(), yyline+1, yycolumn+1); } +: { return new Token(Token.COLON, yytext(), yyline+1, yycolumn+1); } + + +[a-zA-Z][a-zA-Z0-9]* { return new Token(Token.ID, yytext(), yyline+1, yycolumn+1); } + +0 { return new IntConstToken(Token.INTCONST, yytext(), yyline+1, yycolumn+1, 0); } +0/\. { yybegin(INT); textvalue=yytext(); startline=yyline+1; startcolumn=yycolumn+1; + intvalue=yytext().charAt(0)-'0'; fracvalue=0; fraclength=0; expvalue=0; } +[1-9] { yybegin(INT); textvalue=yytext(); startline=yyline+1; startcolumn=yycolumn+1; + intvalue=yytext().charAt(0)-'0'; fracvalue=0; fraclength=0; expvalue=0; } + +\" { yybegin(STRING); textvalue="\""; stringvalue=""; startline=yyline+1; startcolumn=yycolumn+1; } + +(\/\*)~(\*\/) { /* eat comments */ } +[\ \t\b\f\r\n]+ { /* eat whitespace */ } +<> { return new Token(Token.EOF, yytext(), yyline+1, yycolumn+1); } +[^] { return new Token(Token.INVALID, yytext(), yyline+1, yycolumn+1); } + + { + [a-zA-Z \.:] { textvalue+=yytext(); stringvalue+=yytext(); } + \\\" { textvalue+="\\\""; stringvalue+="\""; } + \" { yybegin(YYINITIAL); return new StringConstToken(Token.STRINGCONST, textvalue+"\"", startline, startcolumn, stringvalue); } + [^] { yybegin(YYINITIAL); return new Token(Token.INVALID, textvalue+yytext(), startline, startcolumn); } + <> { yybegin(YYINITIAL); return new Token(Token.INVALID, textvalue, startline, startcolumn); } +} + + { + [0-9] { intvalue = 10*intvalue + yytext().charAt(0)-'0'; + textvalue+=yytext();} + \. { yybegin(FRACTION); + textvalue+=yytext();} + [eE]/-?[0-9] { yybegin(EXPVZ); textvalue += yytext(); } + [^] { yybegin(YYINITIAL); + yypushback(1); + return new IntConstToken(Token.INTCONST, textvalue, startline, startcolumn, intvalue); } + <> { yybegin(YYINITIAL); + yypushback(1); + return new IntConstToken(Token.INTCONST, textvalue, startline, startcolumn, intvalue);} +} + + { + [0-9] { fracvalue= 10*fracvalue+ yytext().charAt(0)-'0'; + fraclength++; + textvalue+=yytext();} + [eE]/-?[0-9] { yybegin(EXPVZ); + textvalue+=yytext();} + [^] { yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn,intvalue+fracvalue/Math.pow(10,fraclength)); } + <> { yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn,intvalue+fracvalue/Math.pow(10,fraclength)); } +} + + { + -0|0 { yybegin(YYINITIAL); + return new FloatConstToken(Token.FLOATCONST, textvalue+yytext(), startline, startcolumn,intvalue+fracvalue/Math.pow(10,fraclength)); } + -[1-9] { yybegin(EXP); expvalue=yytext().charAt(1)-'0'; expsign=-1; textvalue+=yytext(); } + [1-9] { yybegin(EXP); expvalue=yytext().charAt(0)-'0'; expsign=1; textvalue+=yytext(); } + [^] { yybegin(YYINITIAL); + yypushback(1); + return new Token(Token.INVALID, textvalue, startline, startcolumn); } + <> { yybegin(YYINITIAL); + yypushback(1); + return new Token(Token.INVALID, textvalue, startline, startcolumn); } +} + + { + [0-9] { expvalue = 10* expvalue + yytext().charAt(0)-'0'; textvalue+=yytext(); } + [^] { yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn, (intvalue+fracvalue/Math.pow(10,fraclength))*Math.pow(10,expvalue*expsign)); } + <> { yybegin(YYINITIAL); + yypushback(1); + return new FloatConstToken(Token.FLOATCONST, textvalue, startline, startcolumn, (intvalue+fracvalue/Math.pow(10,fraclength))*Math.pow(10,expvalue*expsign)); } +} + diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/StringConstToken.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/StringConstToken.java new file mode 100644 index 0000000..085babc --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/StringConstToken.java @@ -0,0 +1,28 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * - Token-Definition stringConst + * + * ********************************************** + */ + +package de.dhbw.compiler.xparser; + +public class StringConstToken extends Token { + + private String value=""; + + public StringConstToken(int type, String text, int line, int column, String value) { + super(type,text,line,column); + this.value = value; + } + + public String getValue() { + return value; + } + + +} diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/Token.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/Token.java new file mode 100644 index 0000000..d04d584 --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/Token.java @@ -0,0 +1,167 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * - Token-Definition + * + * ********************************************** + */ + +package de.dhbw.compiler.xparser; + +public class Token { + + public static final int EOF = -1; + public static final int INVALID = 0; + public static final int ID = 1; + public static final int INTCONST = 2; + public static final int FLOATCONST = 3; + public static final int STRINGCONST = 4; + public static final int LBR = 5; + public static final int RBR = 6; + public static final int MULT = 7; + public static final int PLUS = 8; + public static final int MINUS = 9; + public static final int DOT = 10; + public static final int DIV = 11; + public static final int COLON = 12; + public static final int ASSIGN = 13; + public static final int SEMICOLON = 14; + public static final int LESS = 15; + public static final int EQUALS = 16; + public static final int MORE = 17; + public static final int BEGIN = 18; + public static final int ELSE = 19; + public static final int END = 20; + public static final int FLOAT = 21; + public static final int FOR = 22; + public static final int IF = 23; + public static final int INT = 24; + public static final int PRINT = 25; + public static final int PROGRAM = 26; + public static final int READ = 27; + public static final int STRING = 28; + public static final int THEN = 29; + public static final int WHILE = 30; + + // Token für innere Knoten des Ableitungsbaumes + public static final int TYPE = 101; + public static final int MODIFIER = 102; + public static final int DECL = 103; + public static final int EXPR = 104; + public static final int EXPR2 = 105; + public static final int EXPR3 = 106; + public static final int ASSIGNSTAT = 107; + public static final int FORSTAT = 108; + public static final int WHILESTAT = 109; + public static final int CONDSTAT = 110; + public static final int COND = 111; + public static final int STAT = 112; + public static final int BLOCK = 113; + public static final int STATLIST = 114; + public static final int STATWITHSEMI = 115; + public static final int DECLLIST = 116; + public static final int APROGRAM = 117; + public static final int UMINUS = 118; + + private int type; + private String text; + private int line; + private int columnm; + + public Token(int type, String text, int line, int column) { + this.type = type; + this.text = text; + this.line = line; + this.columnm = column; + } + + public Token(int type, String text) { + this(type,text,0,0); + } + + public Token(int type) { + this(type, getTypeName(type)); + } + + public int getType() { + return type; + } + + public String getText() { + return text; + } + + public int getLine() { + return line; + } + + public int getColumn() { + return columnm; + } + + public String toString() { + return "(" + getTypeName(type) + "," + text + "," + line + "," + columnm + ")"; + } + + public static String getTypeName(int tokenType) { + switch (tokenType) { + case EOF: return "EOF"; + case INVALID: return "INVALID"; + case ID: return "ID"; + case INTCONST: return "INTCONST"; + case FLOATCONST: return "FLOATCONST"; + case STRINGCONST: return "STRINGCONST"; + case LBR: return "LBR"; + case RBR: return "RBR"; + case MULT: return "MULT"; + case PLUS: return "PLUS"; + case MINUS: return "MINUS"; + case DOT: return "DOT"; + case DIV: return "DIV"; + case COLON: return "COLON"; + case ASSIGN: return "ASSIGN"; + case SEMICOLON: return "SEMICOLON"; + case LESS: return "LESS"; + case EQUALS: return "EQUALS"; + case MORE: return "MORE"; + case BEGIN: return "BEGIN"; + case ELSE: return "ELSE"; + case END: return "END"; + case FLOAT: return "FLOAT"; + case FOR: return "FOR"; + case IF: return "IF"; + case INT: return "INT"; + case PRINT: return "PRINT"; + case PROGRAM: return "PROGRAM"; + case READ: return "READ"; + case STRING: return "STRING"; + case THEN: return "THEN"; + case WHILE: return "WHILE"; + // Token für innere Knoten des Ableitungsbaumes + case TYPE: return "TYPE"; + case MODIFIER: return "MODIFIER"; + case DECL: return "DECL"; + case EXPR: return "EXPR"; + case EXPR2: return "EXPR2"; + case EXPR3: return "EXPR3"; + case ASSIGNSTAT: return "ASSIGNSTAT"; + case FORSTAT: return "FORSTAT"; + case WHILESTAT: return "WHILESTAT"; + case CONDSTAT: return "CONDSTAT"; + case COND: return "COND"; + case STAT: return "STAT"; + case BLOCK: return "BLOCK"; + case STATLIST: return "STATLIST"; + case STATWITHSEMI: return "STATWITHSEMI"; + case DECLLIST: return "DECLLIST"; + case APROGRAM: return "APROGRAM"; + case UMINUS: return "UMNInUS"; + default: return "Unknown token type!"; + } + + } + +} diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/TokenBuffer.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/TokenBuffer.java new file mode 100644 index 0000000..eef7fad --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/TokenBuffer.java @@ -0,0 +1,45 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * - Token-Puffer + * + * ********************************************** + */ + +package de.dhbw.compiler.xparser; + +import java.io.IOException; + +public class TokenBuffer { + + private JFlexXScanner scanner; + private int count = 0; + private Token token = null; + + public TokenBuffer(JFlexXScanner scanner) throws IOException { + this.scanner = scanner; + token = scanner.nextToken(); + count++; + } + + public Token nextToken() throws IOException { + Token help = token; + if (help.getType()!=Token.EOF) { + token = scanner.nextToken(); + count++; + } + return help; + } + + public Token lookaheadToken() { + return token; + } + + public int getTokenCount() { + return count; + } + +} diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/Tree.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/Tree.java new file mode 100644 index 0000000..ed39513 --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/Tree.java @@ -0,0 +1,97 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * - Syntaxbaum + * + * ********************************************** + */ + +package de.dhbw.compiler.xparser; + +import java.util.LinkedList; +import java.util.List; + +public class Tree { + + private Token token = null; + private LinkedList children = null; + + public Tree(Token token) { + this.token=token; + this.children= new LinkedList(); + } + + public Token getToken() { + return token; + } + + public void addLastChild(Tree child) { + this.children.addLast(child); + } + + public void addFirstChild(Tree child) { + this.children.addFirst(child); + } + + public Tree removeChild(int n) { + return this.children.remove(n); + } + + public Tree getChild(int n) { + return this.children.get(n); + } + + public int getChildCount() { + return this.children.size(); + } + + public List getChildren() { + return children; + } + + public String toGraphvizDot() { + StringBuffer dot = new StringBuffer(); + dot.append("digraph{ \n"); + this.appendNode(dot); + this.appendEdges(dot); + dot.append("}"); + return dot.toString(); + } + + private void appendNode(StringBuffer dot) { + dot.append("n"+this.hashCode()); + dot.append(" [label=\""+token.getText().replace("\\", "\\\\").replace("\"","\\\"")+"\"]\n"); + for (Tree c: children) { + c.appendNode(dot); + } + } + + private void appendEdges(StringBuffer dot) { + for (Tree c: children) { + dot.append("n"+this.hashCode()+" -> n"+c.hashCode()+"\n"); + } + for (Tree c: children) { + c.appendEdges(dot); + } + + } + + public String toString() { + StringBuffer res = new StringBuffer(); + if (children.isEmpty()) { + res.append(token.getText()); + } else { + res.append("("+this.token.getText()); + for (Tree c: children) { + res.append(" "+c.toString()); + } + res.append(")"); + } + return res.toString(); + + } + +} diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/XParser.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/XParser.java new file mode 100644 index 0000000..7e201b3 --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/XParser.java @@ -0,0 +1,25 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * - LL1-Parser + * + * ********************************************** + */ + +package de.dhbw.compiler.xparser; + +public class XParser { + + public XParser(TokenBuffer in) { + //TODO Initialization + } + + public Tree parseProgram() { + //TODO Parser + return null; + } + +} \ No newline at end of file diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/XParserMain.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/XParserMain.java new file mode 100644 index 0000000..0d8b617 --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/XParserMain.java @@ -0,0 +1,85 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * + * ********************************************** + */ + +package de.dhbw.compiler.xparser; + +import java.io.PrintWriter; +import java.io.StringReader; + + + +public class XParserMain { + + private static final String TEST = + "program test2;\n"+ + " x : int;\n"+ + " y : float;\n"+ + " z : string;\n"+ + "begin\n"+ + " x := 4+5+6.2;\n"+ + " y := 3.56+1.2e3+45.e-67+4e34+3E-1;\n"+ + " z := \"Hello \\\"World\\\"\" + \":\";\n"+ + " z := \"Peter\" + 4;\n"+ + " if 2<3 then abc := 5 else abc := 7;\n"+ + " while (x>y) y := y+1;\n"+ + " begin\n"+ + " for (x:=1; x<6; x:=x+1) y:=y+2;\n"+ + " end;\n"+ + "end."; + + private static final String TESTXmin1 = + "program xmin1;\n"+ + " read x : int;\n"+ + " print y : int;\n"+ + "begin\n"+ + " y := 25+2*x-6*x;\n"+ + " if x3 then x:=1 else x:=2;"+ + "end."; + String expected = "(program condElse (DECLLIST (DECL x int)) (STATLIST (if (> 2 3) (:= x 1) (:= x 2))))"; + testParseTree(test, expected); + } + + @Test + public void program22CondElse2() throws Exception { + String test = "program condelse2;\n"+ + " x: int;"+ + "begin\n"+ + " if 2=3 then if 4<5 then x:=1 else x:=2 else x:=3;"+ + "end."; + String expected = "(program condelse2 (DECLLIST (DECL x int)) " + + "(STATLIST (if (= 2 3) (if (< 4 5) (:= x 1) (:= x 2)) (:= x 3))))"; + testParseTree(test, expected); + } + + + @Test + public void program23CondElse3() throws Exception { + String test = "program condelse3;\n"+ + " x: int;"+ + "begin\n"+ + " if 2<3 then if 4>5 then x:=1 else if 6=7 then x:=2 else x:=3;"+ + "end."; + String expected = "(program condelse3 (DECLLIST (DECL x int)) " + + "(STATLIST (if (< 2 3) (if (> 4 5) (:= x 1) (if (= 6 7) (:= x 2) (:= x 3))))))"; + testParseTree(test, expected); + } + + + @Test + public void program24CondElse4() throws Exception { + String test = "program condelse4;\n"+ + " x: int;"+ + "begin\n"+ + " if 2<3 then if 4>5 then x:=1 else x:=2 else if 6=7 then x:=3 else x:=4;"+ + "end."; + String expected = "(program condelse4 (DECLLIST (DECL x int)) " + + "(STATLIST (if (< 2 3) (if (> 4 5) (:= x 1) (:= x 2)) (if (= 6 7) (:= x 3) (:= x 4)))))"; + testParseTree(test, expected); + } + + + @Test + public void program90Xmin1() throws Exception { + String test = "program xmin1;\n"+ + " read x : int;\n"+ + " print y : int;\n"+ + "begin\n"+ + " y := 25+2*x-6*x;\n"+ + " if x ", false, new Token(Token.MORE,">",1,3)); + } + + @Test + public void tokenBEGIN() throws Exception { + testTokenList(" begin ", false, new Token(Token.BEGIN,"begin",1,3)); + } + + @Test + public void tokenELS() throws Exception { + testTokenList(" else ", false, new Token(Token.ELSE,"else",1,3)); + } + + @Test + public void tokenEND() throws Exception { + testTokenList(" end ", false, new Token(Token.END,"end",1,3)); + } + + @Test + public void tokenFLOAT() throws Exception { + testTokenList(" float ", false, new Token(Token.FLOAT,"float",1,3)); + } + + @Test + public void tokenFOR() throws Exception { + testTokenList(" for ", false, new Token(Token.FOR,"for",1,3)); + } + + @Test + public void tokenIF() throws Exception { + testTokenList(" if ", false, new Token(Token.IF,"if",1,3)); + } + + @Test + public void tokenINT() throws Exception { + testTokenList(" int ", false, new Token(Token.INT,"int",1,3)); + } + + @Test + public void tokenPRINT() throws Exception { + testTokenList(" print ", false, new Token(Token.PRINT,"print",1,3)); + } + + @Test + public void tokenPROGRAM() throws Exception { + testTokenList(" program ", false, new Token(Token.PROGRAM,"program",1,3)); + } + + @Test + public void tokenREAD() throws Exception { + testTokenList(" read ", false, new Token(Token.READ,"read",1,3)); + } + + @Test + public void tokenSTRING() throws Exception { + testTokenList(" string ", false, new Token(Token.STRING,"string",1,3)); + } + + @Test + public void tokenTHEN() throws Exception { + testTokenList(" then ", false, new Token(Token.THEN,"then",1,3)); + } + + @Test + public void tokenWHILE() throws Exception { + testTokenList(" while ", false, new Token(Token.WHILE,"while",1,3)); + } + + @Test + public void tokenEOF() throws Exception { + testTokenList(" ", false); + testTokenList(" ", false, new Token(Token.EOF,"",1,2)); + testTokenList("", false, new Token(Token.EOF,"",1,1)); + } + + @Test + public void invalidÄ() throws Exception { + testTokenList(" ä ", false, new Token(Token.INVALID,"ä",1,2)); + } + + @Test + public void invalidGatter() throws Exception { + testTokenList(" # ", false, new Token(Token.INVALID,"#",1,2)); + } + + +} diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/test/TestXScanner2.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/test/TestXScanner2.java new file mode 100644 index 0000000..30ad661 --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/test/TestXScanner2.java @@ -0,0 +1,67 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * - Testklasse Typkonvertierung + * + * ********************************************** + */ + +package de.dhbw.compiler.xparser.test; + +import org.junit.Test; + +import de.dhbw.compiler.xparser.Token; + +public class TestXScanner2 extends TokenStreamTest { + + @Test + public void tokenIntConst() throws Exception { + testTokenList(" 0 ", true, new Token(Token.INTCONST,"0",1,3)); + testTokenList(" 1 ", true, new Token(Token.INTCONST,"1",1,3)); + testTokenList(" 12 ", true, new Token(Token.INTCONST,"12",1,3)); + testTokenList(" 123 ", true, new Token(Token.INTCONST,"123",1,3)); + testTokenList(" 1234567890 ", true, new Token(Token.INTCONST,"1234567890",1,3)); + testTokenList(" 78 ", true, new Token(Token.INTCONST,"78",1,3)); + } + + @Test + public void tokenFloatConst0() throws Exception { + testTokenList(" 0. ", true, new Token(Token.FLOATCONST,"0.",1,3)); + testTokenList(" 0.0 ", true, new Token(Token.FLOATCONST,"0.0",1,3)); + testTokenList(" 0.0e0 ", true, new Token(Token.FLOATCONST,"0.0e0",1,3)); + } + + @Test + public void tokenFloatConst1() throws Exception { + testTokenList(" 1. ", true, new Token(Token.FLOATCONST,"1.",1,3)); + testTokenList(" 1.1 ", true, new Token(Token.FLOATCONST,"1.1",1,3)); + testTokenList(" 1.1e1 ", true, new Token(Token.FLOATCONST,"1.1e1",1,3)); + testTokenList(" 1e1 ", true, new Token(Token.FLOATCONST,"1e1",1,3)); + } + + @Test + public void tokenFloatConst123() throws Exception { + testTokenList(" 0.12e34 ", true, new Token(Token.FLOATCONST,"0.12e34",1,3)); + testTokenList(" 0.045e23 ", true, new Token(Token.FLOATCONST,"0.045e23",1,3)); + testTokenList(" 123.4560e7890 ", true, new Token(Token.FLOATCONST,"123.4560e7890",1,3)); + testTokenList(" 0.12E34 ", true, new Token(Token.FLOATCONST,"0.12E34",1,3)); + testTokenList(" 0.045E23 ", true, new Token(Token.FLOATCONST,"0.045E23",1,3)); + testTokenList(" 123.4560E7890 ", true, new Token(Token.FLOATCONST,"123.4560E7890",1,3)); + } + + @Test + public void tokenStringConst() throws Exception { + testTokenList(" \"hallo .: \" ", true, new Token(Token.STRINGCONST,"\"hallo .: \"",1,3)); + testTokenList(" \" \\\" \" ", true, new Token(Token.STRINGCONST,"\" \\\" \"",1,3)); + testTokenList(" \"hallo , \" ", true, + new Token(Token.INVALID,"\"hallo ,",1,3), + new Token(Token.INVALID,"\" ",1,12)); + testTokenList(" \",\"", true, + new Token(Token.INVALID,"\",",1,3), + new Token(Token.INVALID,"\"",1,5)); + } + +} diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/test/TestXScanner3.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/test/TestXScanner3.java new file mode 100644 index 0000000..f2355bb --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/test/TestXScanner3.java @@ -0,0 +1,112 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * - Testklasse Programme + * + * ********************************************** + */ + +package de.dhbw.compiler.xparser.test; + +import org.junit.Test; + +import de.dhbw.compiler.xparser.Token; + +public class TestXScanner3 extends TokenStreamTest { + + @Test + public void program1() throws Exception { + testTokenList("program test1;\nbegin\nend.",false, + new Token(Token.PROGRAM,"program",1,1), + new Token(Token.ID,"test1",1,9), + new Token(Token.SEMICOLON,";",1,14), + new Token(Token.BEGIN,"begin",2,1), + new Token(Token.END,"end",3,1), + new Token(Token.DOT,".",3,4)); + } + + @Test + public void program2() throws Exception { + testTokenList( "program test2;\n"+ + " x : int;\n"+ + " y : float;\n"+ + " z : string;\n"+ + "begin\n"+ + " x := 4+5+6.2;\n"+ + " y := 3.56+1.2e3+45.e-67+4e34+3E-1;\n"+ + " z := \"Hello \\\"World\\\"\" + \":\";\n"+ + " z := \"Peter\" + 4;\n"+ + " a := 3+4;\n"+ + "end.", false, + // program test2; + new Token(Token.PROGRAM,"program",1,1), + new Token(Token.ID,"test2",1,9), + new Token(Token.SEMICOLON,";",1,14), + // x : int; + new Token(Token.ID,"x",2,2), + new Token(Token.COLON,":",2,4), + new Token(Token.INT,"int",2,6), + new Token(Token.SEMICOLON,";",2,9), + // y : float; + new Token(Token.ID,"y",3,2), + new Token(Token.COLON,":",3,4), + new Token(Token.FLOAT,"float",3,6), + new Token(Token.SEMICOLON,";",3,11), + // z : string; + new Token(Token.ID,"z",4,2), + new Token(Token.COLON,":",4,4), + new Token(Token.STRING,"string",4,6), + new Token(Token.SEMICOLON,";",4,12), + // begin + new Token(Token.BEGIN,"begin",5,1), + // x := 4+5+6.2; + new Token(Token.ID,"x",6,2), + new Token(Token.ASSIGN,":=",6,4), + new Token(Token.INTCONST,"4",6,7), + new Token(Token.PLUS,"+",6,8), + new Token(Token.INTCONST,"5",6,9), + new Token(Token.PLUS,"+",6,10), + new Token(Token.FLOATCONST,"6.2",6,11), + new Token(Token.SEMICOLON,";",6,14), + // y := 3.56+1.2e3+45.e-67+4e34+3E-1; + new Token(Token.ID,"y",7,2), + new Token(Token.ASSIGN,":=",7,4), + new Token(Token.FLOATCONST,"3.56",7,7), + new Token(Token.PLUS,"+",7,11), + new Token(Token.FLOATCONST,"1.2e3",7,12), + new Token(Token.PLUS,"+",7,17), + new Token(Token.FLOATCONST,"45.e-67",7,18), + new Token(Token.PLUS,"+",7,25), + new Token(Token.FLOATCONST,"4e34",7,26), + new Token(Token.PLUS,"+",7,30), + new Token(Token.FLOATCONST,"3E-1",7,31), + new Token(Token.SEMICOLON,";",7,35), + // z := \"Hello \\\"World\\\"\" + \":\"; + new Token(Token.ID,"z",8,2), + new Token(Token.ASSIGN,":=",8,4), + new Token(Token.STRINGCONST,"\"Hello \\\"World\\\"\"",8,7), + new Token(Token.PLUS,"+",8,25), + new Token(Token.STRINGCONST,"\":\"",8,27), + new Token(Token.SEMICOLON,";",8,30), + // z := \"Peter\" + 4; + new Token(Token.ID,"z",9,2), + new Token(Token.ASSIGN,":=",9,4), + new Token(Token.STRINGCONST,"\"Peter\"",9,7), + new Token(Token.PLUS,"+",9,15), + new Token(Token.INTCONST,"4",9,17), + new Token(Token.SEMICOLON,";",9,18), + // a := 3+4; + new Token(Token.ID,"a",10,2), + new Token(Token.ASSIGN,":=",10,4), + new Token(Token.INTCONST,"3",10,7), + new Token(Token.PLUS,"+",10,8), + new Token(Token.INTCONST,"4",10,9), + new Token(Token.SEMICOLON,";",10,10), + // end. + new Token(Token.END,"end",11,1), + new Token(Token.DOT,".",11,4)); + } +} diff --git a/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/test/TokenStreamTest.java b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/test/TokenStreamTest.java new file mode 100644 index 0000000..0ad2a4a --- /dev/null +++ b/ÜB-Praxis-LL1-Parser für X-Leer/src/de/dhbw/compiler/xparser/test/TokenStreamTest.java @@ -0,0 +1,66 @@ +/* ********************************************** + * Duale Hochschule Baden-Württemberg Karlsruhe + * Prof. Dr. Jörn Eisenbiegler + * + * Vorlesung Übersetzerbau + * Praxis LL(1)-Parser für X + * - Testfall-Utility für Scanner + * + * ********************************************** + */ + + +package de.dhbw.compiler.xparser.test; + +import static org.junit.Assert.assertEquals; + +import java.io.StringReader; + +import de.dhbw.compiler.xparser.FloatConstToken; +import de.dhbw.compiler.xparser.IntConstToken; +import de.dhbw.compiler.xparser.JFlexXScanner; +import de.dhbw.compiler.xparser.StringConstToken; +import de.dhbw.compiler.xparser.Token; + +public abstract class TokenStreamTest { + + protected void testTokenList(String in, boolean convert, Token... TokenList) throws Exception { + JFlexXScanner scanner = new JFlexXScanner(new StringReader(in)); + Token myToken; + + for (Token expected : TokenList) { + myToken = scanner.nextToken(); + assertEquals("Expect Token "+expected.toString()+". Error in type.", + expected.getType(), myToken.getType()); + assertEquals("Expect Token "+expected.toString()+". Error in text.", + expected.getText(), myToken.getText()); + assertEquals("Expect Token "+expected.toString()+". Error in line.", + expected.getLine(), myToken.getLine()); + assertEquals("Expect Token "+expected.toString()+". Error in column.", + expected.getColumn(), myToken.getColumn()); + if (convert) { + switch (myToken.getType()) { + case Token.INTCONST: + int intValue = Integer.parseInt(expected.getText()); + assertEquals("Expected Token value "+intValue, + intValue,((IntConstToken)myToken).getValue()); + break; + case Token.FLOATCONST: + double doubleValue = Double.parseDouble(expected.getText().replace("^", "e")); + assertEquals("Expected Token value "+doubleValue, + doubleValue,((FloatConstToken)myToken).getValue(), doubleValue*0.0000001); + break; + case Token.STRINGCONST: + String stringValue = expected.getText().substring(1, expected.getText().length()-1).replace("\\\"", "\""); + assertEquals("Expected Token value "+stringValue, + stringValue,((StringConstToken)myToken).getValue()); + break; + } + } + } + + myToken = scanner.nextToken(); + assertEquals("Expected End of File (EOF), read " + myToken.toString() + ".", Token.EOF, myToken.getType()); + } + +}