diff --git a/tools/lexer/idea-flex.skeleton b/tools/lexer/idea-flex.skeleton new file mode 100644 index 000000000000..a91ec0c86859 --- /dev/null +++ b/tools/lexer/idea-flex.skeleton @@ -0,0 +1,263 @@ + /** initial size of the lookahead buffer */ +--- private static final int ZZ_BUFFERSIZE = ...; + + /** lexical states */ +--- lexical states, charmap + + /* 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; + private static final char[] EMPTY_BUFFER = new char[0]; + private static final int YYEOF = -1; + private static java.io.Reader zzReader = null; // Fake + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + +--- isFinal list + /** 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 CharSequence zzBuffer = ""; + + /** this buffer may contains the current text array to be matched when it is cheap to acquire it */ + private char[] zzBufferArray; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** 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; + + /** + * 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; + +--- user class code + +--- constructor declaration + + public final int getTokenStart(){ + return zzStartRead; + } + + public final int getTokenEnd(){ + return getTokenStart() + yylength(); + } + + public void reset(CharSequence buffer, int start, int end,int initialState){ + zzBuffer = buffer; + zzBufferArray = com.intellij.util.text.CharArrayUtil.fromSequenceWithoutCopying(buffer); + zzCurrentPos = zzMarkedPos = zzStartRead = start; + zzPushbackPos = 0; + zzAtEOF = false; + zzAtBOL = true; + zzEndRead = end; + yybegin(initialState); + } + + // For Demetra compatibility + public void reset(CharSequence buffer, int initialState){ + zzBuffer = buffer; + zzBufferArray = null; + zzCurrentPos = zzMarkedPos = zzStartRead = 0; + zzPushbackPos = 0; + zzAtEOF = false; + zzAtBOL = true; + zzEndRead = buffer.length(); + yybegin(initialState); + } + + /** + * 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 { + return true; + } + + + /** + * 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 CharSequence yytext() { + return zzBuffer.subSequence(zzStartRead, zzMarkedPos); + } + + + /** + * 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 zzBufferArray != null ? zzBufferArray[zzStartRead+pos]:zzBuffer.charAt(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 + */ +--- zzScanError declaration + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + +--- throws clause + } + + + /** + * 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()! + */ +--- yypushback decl (contains zzScanError exception) + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + +--- zzDoEOF + /** + * 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 + */ +--- yylex declaration + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + CharSequence zzBufferL = zzBuffer; + char[] zzBufferArrayL = zzBufferArray; + char [] zzCMapL = ZZ_CMAP; + +--- local declarations + + while (true) { + zzMarkedPosL = zzMarkedPos; + +--- start admin (line, char, col count) + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + +--- start admin (lexstate etc) + + zzForAction: { + while (true) { + +--- next input, line, col, char count, next transition, isFinal action + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; +--- line count update + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; +--- char count update + +--- actions + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; +--- eofvalue + } + else { +--- no match + } + } + } + } + +--- main + +} diff --git a/tools/lexer/jflex-1.4/.classpath b/tools/lexer/jflex-1.4/.classpath new file mode 100644 index 000000000000..c7ff90e6b35c --- /dev/null +++ b/tools/lexer/jflex-1.4/.classpath @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/tools/lexer/jflex-1.4/.project b/tools/lexer/jflex-1.4/.project new file mode 100644 index 000000000000..3160ec94a23d --- /dev/null +++ b/tools/lexer/jflex-1.4/.project @@ -0,0 +1,17 @@ + + + jflex + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/tools/lexer/jflex-1.4/COPYRIGHT b/tools/lexer/jflex-1.4/COPYRIGHT new file mode 100644 index 000000000000..0109c544d770 --- /dev/null +++ b/tools/lexer/jflex-1.4/COPYRIGHT @@ -0,0 +1,303 @@ +JFlex - Copying, Warranty & License + + + +JFlex is free software, published under the terms of the GNU General Public License. + +There is absolutely NO WARRANTY for JFlex, its code and its documentation. + +The code generated by JFlex inherits the copyright of the specification it +was produced from. If it was your specification, you may use the generated +code without restriction. + + + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + + +0. + This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + + +1. + You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + +2. + You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + + + a) + You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + + b) + You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + + c) + If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + + +3. + You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + + + a) + Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + + b) + Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + + c) + Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + +4. + You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + + +5. + You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + + +6. + Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + + +7. + If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + + +8. + If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + + +9. + The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + + + +10. + If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + + +NO WARRANTY + + + +11. + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + + +12. + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + + + +END OF TERMS AND CONDITIONS diff --git a/tools/lexer/jflex-1.4/JFlex-Changes.txt b/tools/lexer/jflex-1.4/JFlex-Changes.txt new file mode 100644 index 000000000000..9048b81f42dd --- /dev/null +++ b/tools/lexer/jflex-1.4/JFlex-Changes.txt @@ -0,0 +1,12 @@ +The following changes to JFlex 1.4.1 have been done by JetBrains developers: + +July 26, 2005: + + * JFlexTask.java: Added setCharAt() method for setting the -charat option from Ant + builds. + +July 8, 2005: + + * Main.java, Options.java, Emitter.java: Added new command line option -charat. + The option replaces array index access when accessing the zzBufferL array with + calls to the .charAt() method. diff --git a/tools/lexer/jflex-1.4/bin/jflex b/tools/lexer/jflex-1.4/bin/jflex new file mode 100644 index 000000000000..80f7b76bf1d6 --- /dev/null +++ b/tools/lexer/jflex-1.4/bin/jflex @@ -0,0 +1,51 @@ +#! /bin/bash +# +# JFlex start script $Revision: 2.0 $ +# +# if Java is not in your binary path, you need to supply its +# location in this script. The script automatically finds +# JFLEX_HOME when called directly, via binary path, or symbolic +# link. +# +# Site wide installation: simply make a symlink from e.g. +# /usr/bin/jflex to this script at its original position +# +#=================================================================== +# +# configurables: + +# path to the java interpreter +JAVA=java + +# end configurables +# +#=================================================================== +# + +# calculate true location + +PRG=`type $0` +PRG=${PRG##* } + +# If PRG is a symlink, trace it to the real home directory + +while [ -L "$PRG" ] +do + newprg=$(ls -l ${PRG}) + newprg=${newprg##*-> } + [ ${newprg} = ${newprg#/} ] && newprg=${PRG%/*}/${newprg} + PRG="$newprg" +done + +PRG=${PRG%/*} +JFLEX_HOME=${PRG}/.. + +# -------------------------------------------------------------------- + +export CLASSPATH +CLASSPATH=$JFLEX_HOME/lib/JFlex.jar + +$JAVA JFlex.Main $@ + +#for more memory: +#$JAVA -Xmx128m JFlex.Main $@ diff --git a/tools/lexer/jflex-1.4/bin/jflex.bat b/tools/lexer/jflex-1.4/bin/jflex.bat new file mode 100644 index 000000000000..6ac3ccd53845 --- /dev/null +++ b/tools/lexer/jflex-1.4/bin/jflex.bat @@ -0,0 +1,19 @@ +@echo off +REM Please adjust the paths JFLEX_HOME and JAVA_HOME to suit your needs +REM (please do not add a trailing backslash) + +set JFLEX_HOME=.. + +REM only needed for JDK 1.1.x: +set JAVA_HOME=C:\JAVA + + +REM ------------------------------------------------------------------- + +set CLPATH=%JAVA_HOME%\lib\classes.zip;%JFLEX_HOME%\lib\JFlex.jar + +REM for JDK 1.1.x +REM %JAVA_HOME%\bin\java -classpath %CLPATH% JFlex.Main %1 %2 %3 %4 %5 %6 %7 %8 %9 + +REM for JDK 1.2 +java -Xmx128m -jar %JFLEX_HOME%\lib\JFlex.jar %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/tools/lexer/jflex-1.4/doc/COPYRIGHT b/tools/lexer/jflex-1.4/doc/COPYRIGHT new file mode 100644 index 000000000000..0109c544d770 --- /dev/null +++ b/tools/lexer/jflex-1.4/doc/COPYRIGHT @@ -0,0 +1,303 @@ +JFlex - Copying, Warranty & License + + + +JFlex is free software, published under the terms of the GNU General Public License. + +There is absolutely NO WARRANTY for JFlex, its code and its documentation. + +The code generated by JFlex inherits the copyright of the specification it +was produced from. If it was your specification, you may use the generated +code without restriction. + + + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + + +0. + This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + + +1. + You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + +2. + You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + + + a) + You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + + b) + You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + + c) + If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + + +3. + You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + + + a) + Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + + b) + Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + + c) + Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + +4. + You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + + +5. + You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + + +6. + Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + + +7. + If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + + +8. + If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + + +9. + The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + + + +10. + If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + + +NO WARRANTY + + + +11. + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + + +12. + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + + + +END OF TERMS AND CONDITIONS diff --git a/tools/lexer/jflex-1.4/doc/crossref.png b/tools/lexer/jflex-1.4/doc/crossref.png new file mode 100644 index 000000000000..7dd2dddf5ac2 Binary files /dev/null and b/tools/lexer/jflex-1.4/doc/crossref.png differ diff --git a/tools/lexer/jflex-1.4/doc/footnote.png b/tools/lexer/jflex-1.4/doc/footnote.png new file mode 100644 index 000000000000..4591c0eca123 Binary files /dev/null and b/tools/lexer/jflex-1.4/doc/footnote.png differ diff --git a/tools/lexer/jflex-1.4/doc/jflex_anttask.html b/tools/lexer/jflex-1.4/doc/jflex_anttask.html new file mode 100644 index 000000000000..942acf2b391d --- /dev/null +++ b/tools/lexer/jflex-1.4/doc/jflex_anttask.html @@ -0,0 +1,165 @@ + + + + +JFlex Ant Task + + + + +

JFlex Ant Task

+

+ JFlex can be easily integrated with Ant build tool. + To use JFlex with Ant, simply copy JFlex.jar to $ANT_HOME/lib/ directory. +

+

Description

+

+ The JFlex Ant Task invokes the JFlex lexical + analyzer generator on a grammar file. +

+

+ To use the JFlex task, the following line must be placed in the Ant build file: +

+
<taskdef classname="JFlex.anttask.JFlexTask" name="jflex" />
+ +

+ The JFlex task requires the file attribute to be set to the source grammar file (*.flex). + Unless the target directory is specified with the destdir option, + the generated class will be saved to the same directory where grammar file resides. + Like javac, the JFlex task creates subdirectories in destdir according to the + generated class package. +

+

+ This task only invokes JFlex if the grammar file is newer than the generated + files. +

+ +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionRequiredDefault
file="file"The grammar file to process.Yes
destdir="dir" + The directory to write the generated files to. If not set, the files + are written to the directory containing the grammar file. Note that unlike + JFlex's "-d" command line option, destdir causes the generated file to be written to + {destdir}/{package name}. This behaviour is similar to javac -d dir. + No
outdir="dir" + The directory to write the generated files to. If not set, the files + are written to the directory containing the grammar file. This options works + exactly like JFlex's "-d" command line option, it causes the output file to + be written to dir regardless of the package name. + No
verboseDisplay generation process messages.No"off"
dumpDump character classes, NFA and DFA tables.No"off"
time or

timeStatistics

Display generation time statistics.No"off"
nomin or

skipMinimization

Skip minimization step.No"off"
skel="file" or

skeleton="file"

Use external skeleton file.No"off"
dot or

generateDot

Write graphviz .dot files for the generated automata (alpha).No"off"
nobakDo not make a backup if the generated file exists.No"off"
switchUse code generation method switch.No"off"
tableUse code generation method table.No"off"
packUse code generation method pack.No"on"
+

Example

+
+<jflex
+    file="src/parser/Parser.flex"
+    destdir="build/generated/"
+/>
+
+

+ JFlex generates the lexical analyzer for src/parser/Parser.flex and saves the result + to build/generated/parser/, providing Parser.flex declares to be in package parser. +

+ +
+<jflex
+    file="src/parser/Parser.flex"
+    destdir="build/generated/"
+/>
+<javac
+    srcdir="build/generated/"
+    destdir="build/classes/"
+/>
+
+

+ The same as above plus compile generated classes to build/classes +

+
+ + + + diff --git a/tools/lexer/jflex-1.4/doc/logo.gif b/tools/lexer/jflex-1.4/doc/logo.gif new file mode 100644 index 000000000000..dcd04fb57dc9 Binary files /dev/null and b/tools/lexer/jflex-1.4/doc/logo.gif differ diff --git a/tools/lexer/jflex-1.4/doc/manual.css b/tools/lexer/jflex-1.4/doc/manual.css new file mode 100644 index 000000000000..1d69acfd988b --- /dev/null +++ b/tools/lexer/jflex-1.4/doc/manual.css @@ -0,0 +1,19 @@ +body { background-color:#FFFFFF; } +table { background-color:#F0F0F0; } +h1 { font-size:16pt; font-style:italic; font-weight:bold; font-family:arial,helvetica; + border-top-width:medium; border-top-style:solid; padding-top:5mm; margin-top:1cm; } +h2 { font-size:14pt; font-style:italic; font-weight:bold; font-family:arial,helvetica; + border-top-width:medium; border-top-style:solid; padding-top:5mm; margin-top:1cm; } +h3 { font-size:14pt; font-weight:bold; font-family:arial,helvetica; margin-top:1cm; } +h4 { font-size:12pt; font-family:arial,helvetica; } + +SMALL.TINY { font-size:xx-small } +SMALL.SCRIPTSIZE { font-size:xx-small } +SMALL.FOOTNOTESIZE { font-size:x-small } +SMALL.SMALL { font-size:small } +BIG.LARGE { font-size:large } +BIG.XLARGE { font-size:x-large } +BIG.XXLARGE { font-size:xx-large } +BIG.HUGE { font-size:xx-large } +BIG.XHUGE { font-size:xx-large } + diff --git a/tools/lexer/jflex-1.4/doc/manual.html b/tools/lexer/jflex-1.4/doc/manual.html new file mode 100644 index 000000000000..26713a5afe91 --- /dev/null +++ b/tools/lexer/jflex-1.4/doc/manual.html @@ -0,0 +1,3920 @@ + + + + + +JFlex User's Manual + + + + + + + + + + + + + + + +

+ +

+ + +
+ +

+

+The Fast Lexical Analyser Generator +
+

+
+

+
Copyright ©1998-2004 by Gerwin Klein +
+


+

JFlex User's Manual +
+


+

Version 1.4, April 12, 2004 + +
+ +

+
+ +

+Contents +

+ + + + + +


+Introduction +

+JFlex is a lexical analyzer generator for Java[*]written in Java. It is also a rewrite of the very useful tool JLex [3] which +was developed by Elliot Berk at Princeton University. As Vern Paxon states +for his C/C++ tool flex [11]: They do not share any code though. + +

+ +

+Design goals +

+The main design goals of JFlex are: + + + +

+ +

+About this manual +

+This manual gives a brief but complete description of the tool JFlex. It +assumes that you are familiar with the issue of lexical analysis. The references [1], +[2], and [13] provide a good introduction to this topic. + +

+The next section of this manual describes installation procedures +for JFlex. If you never worked with JLex or +just want to compare a JLex and a JFlex scanner specification you +should also read Working with JFlex - an example +(section [*]). All options and the complete +specification syntax are presented in +Lexical specifications (section [*]); +Encodings, Platforms, and Unicode (section [*]) +provides information about scannig text vs. binary files. +If you are interested in performance +considerations and comparing JLex with JFlex speed, +a few words on performance (section [*]) +might be just right for you. Those who want to +use their old JLex specifications may want to check out section [*] +Porting from JLex to avoid possible problems +with not portable or non standard JLex behavior that has been fixed in +JFlex. Section [*] talks about porting scanners from the +Unix tools lex and flex. Interfacing JFlex scanners with the LALR +parser generators CUP and BYacc/J is explained in working + together (section [*]). Section [*] +Bugs gives a list of currently known active bugs. +The manual concludes with notes about +Copying and License (section [*]) and +references. + +

+ +


+Installing and Running JFlex +

+ +

+ +

+Installing JFlex +

+ +

+ +


+Windows +

+To install JFlex on Windows 95/98/NT/XP, follow these three steps: + +
    +
  1. Unzip the file you downloaded into the directory you want JFlex in (using +something like +WinZip). +If you unzipped it to say C:\, the following directory structure +should be generated: + +
    +C:\JFlex\                          
    +      +--bin\                   (start scripts) 
    +      +--doc\                   (FAQ and manual)
    +      +--examples\ 
    +               +--binary\       (scanning binary files)
    +               +--byaccj\       (calculator example for BYacc/J)
    +               +--cup\          (calculator example for cup)
    +               +--interpreter\  (interpreter example for cup)
    +               +--java\         (Java lexer specification) 
    +               +--simple\       (example scanner)
    +               +--standalone\   (a simple standalone scanner) 
    +      +--lib\                   (the precompiled classes) 
    +      +--src\ 
    +          +--JFlex\             (source code of JFlex) 
    +          +--JFlex\gui          (source code of JFlex UI classes)
    +          +--java_cup\runtime\  (source code of cup runtime classes)
    +
    + +

    +

  2. +
  3. Edit the file bin\jflex.bat +(in the example it's C:\JFlex\bin\jflex.bat) +such that + +

    + +

    + +

    +

  4. +
  5. Include the bin\ directory of JFlex in your path. +(the one that contains the start script, in the example: C:\JFlex\bin). +
  6. +
+ +

+ +

+Unix with tar archive +

+ +

+To install JFlex on a Unix system, follow these two steps: + +

+ +

+You can verify the integrity of the downloaded file with +the MD5 checksum available on the JFlex download page. +If you put the checksum file in the same directory +as the archive, you run: + +

+md5sum --check jflex-1.4.tar.gz.md5 + +

+It should tell you + +

+jflex-1.4.tar.gz: OK + +

+ +

+Linux with RPM +

+ +

+ +

+ +

+You can verify the integrity of the downloaded rpm file with + +

+rpm --checksig jflex-1.4-0.rpm + +

+This requires my pgp public key. If you don't have it, you can use + +

+rpm --checksig --nopgp jflex-1.4-0.rpm + +

+or you can get it from http://www.jflex.de/public-key.asc. + +

+ +

+Running JFlex +

+You run JFlex with: + +

+jflex <options> <inputfiles> + +

+It is also possible to skip the start script in bin\ +and include the file lib\JFlex.jar +in your CLASSPATH environment variable instead. + +

+Then you run JFlex with: + +

+java JFlex.Main <options> <inputfiles> + +

+The input files and options are in both cases optional. If you don't provide a file name on +the command line, JFlex will pop up a window to ask you for one. + +

+JFlex knows about the following options: + +

+

+
+
-d <directory> +
writes the generated file to the directory <directory> + +

+

+
+
--skel <file> +
uses external skeleton <file>. This is mainly for JFlex + maintenance and special low level customizations. Use only when you + know what you are doing! JFlex comes with a skeleton file in the + src directory that reflects exactly the internal, precompiled + skeleton and can be used with the -skel option. + +

+

+
+
--nomin +
skip the DFA minimization step during scanner generation. + +

+

+
+
--jlex +
tries even harder to comply to JLex interpretation of specs. + +

+

+
+
--dot +
generate graphviz dot files for the NFA, DFA and minimized + DFA. This feature is still in alpha status, and not + fully implemented yet. + +

+

+
+
--dump +
display transition tables of NFA, initial DFA, and minimized DFA + +

+

+
+
--verbose or -v +
display generation progress messages (enabled by default) + +

+

+
+
--quiet or -q +
display error messages only (no chatter about what JFlex is + currently doing) + +

+

+
+
--time +
display time statistics about the code generation process + (not very accurate) + +

+

+
+
--version +
print version number + +

+

+
+
--info +
print system and JDK information (useful if you'd like + to report a problem) + +

+

+
+
--pack +
use the %pack code generation method by default + +

+

+
+
--table +
use the %table code generation method by default + +

+

+
+
--switch +
use the %switch code generation method by default + +

+

+
+
--help or -h +
print a help message explaining options and usage of JFlex. +
+
+ +

+ +


+A simple Example: How to work with JFlex +

+To demonstrate what a lexical specification with JFlex looks like, this +section presents a part of the specification for the Java language. +The example does not describe the whole lexical structure of Java programs, +but only a small and simplified part of it (some keywords, some operators, +comments and only two kinds of literals). It also shows how to interface +with the LALR parser generator CUP [8] and therefore +uses a class sym (generated by CUP), where integer constants for +the terminal tokens of the CUP grammar are declared. JFlex comes with a +directory examples, where you can find a small standalone scanner +that doesn't need other tools like CUP to give you a running example. +The "examples" directory also contains a complete JFlex +specification of the lexical structure of Java programs together with the +CUP parser specification for Java by +C. Scott Ananian, obtained +from the CUP [8] website (it was modified to interface with the JFlex scanner). +Both specifications adhere to the Java Language Specification [7]. + +

+

+/* JFlex example: part of Java language lexer specification */
+import java_cup.runtime.*;
+
+/**
+ * This class is a simple example lexer.
+ */
+%%
+
+
+%class Lexer
+%unicode
+%cup
+%line
+%column
+
+
+%{
+  StringBuffer string = new StringBuffer();
+
+  private Symbol symbol(int type) {
+    return new Symbol(type, yyline, yycolumn);
+  }
+  private Symbol symbol(int type, Object value) {
+    return new Symbol(type, yyline, yycolumn, value);
+  }
+%}
+
+
+LineTerminator = \r|\n|\r\n
+InputCharacter = [^\r\n]
+WhiteSpace     = {LineTerminator} | [ \t\f]
+
+/* comments */
+Comment = {TraditionalComment} | {EndOfLineComment} | {DocumentationComment}
+
+TraditionalComment   = "/*" [^*] ~"*/" | "/*" "*"+ "/"
+EndOfLineComment     = "//" {InputCharacter}* {LineTerminator}
+DocumentationComment = "/**" {CommentContent} "*"+ "/"
+CommentContent       = ( [^*] | \*+ [^/*] )*
+
+Identifier = [:jletter:] [:jletterdigit:]*
+
+DecIntegerLiteral = 0 | [1-9][0-9]*
+
+
+%state STRING
+
+%%
+
+
+/* keywords */
+<YYINITIAL> "abstract"           { return symbol(sym.ABSTRACT); }
+<YYINITIAL> "boolean"            { return symbol(sym.BOOLEAN); }
+<YYINITIAL> "break"              { return symbol(sym.BREAK); }
+
+
+<YYINITIAL> {
+  /* identifiers */ 
+  {Identifier}                   { return symbol(sym.IDENTIFIER); }
+ 
+  /* literals */
+  {DecIntegerLiteral}            { return symbol(sym.INTEGER_LITERAL); }
+  \"                             { string.setLength(0); yybegin(STRING); }
+
+  /* operators */
+  "="                            { return symbol(sym.EQ); }
+  "=="                           { return symbol(sym.EQEQ); }
+  "+"                            { return symbol(sym.PLUS); }
+
+  /* comments */
+  {Comment}                      { /* ignore */ }
+ 
+  /* whitespace */
+  {WhiteSpace}                   { /* ignore */ }
+}
+
+
+<STRING> {
+  \"                             { yybegin(YYINITIAL); 
+                                   return symbol(sym.STRING_LITERAL, 
+                                   string.toString()); }
+  [^\n\r\"\\]+                   { string.append( yytext() ); }
+  \\t                            { string.append('\t'); }
+  \\n                            { string.append('\n'); }
+
+  \\r                            { string.append('\r'); }
+  \\\"                           { string.append('\"'); }
+  \\                             { string.append('\\'); }
+}
+
+
+/* error fallback */
+.|\n                             { throw new Error("Illegal character <"+
+                                                    yytext()+">"); }
+
+ +

+From this specification JFlex generates a .java file with one +class that contains code for the scanner. The class will have a +constructor taking a java.io.Reader from which the input is +read. The class will also have a function yylex() that runs the +scanner and that can be used to get the next token from the input (in this +example the function actually has the name next_token() because +the specification uses the %cup switch). + +

+As with JLex, the specification consists of three parts, divided by %%: + +

+ +

+ +


+Code to include +

+Let's take a look at the first section, ``user code'': The text up to the +first line starting with %% is copied verbatim to the top +of the generated lexer class (before the actual class declaration). +Beside package and import statements there is usually not much +to do here. If the code ends with a javadoc class comment, the generated class +will get this comment, if not, JFlex will generate one automatically. + +

+ +


+Options and Macros +

+The second section ``options and declarations'' is more interesting. It consists +of a set of options, code that is included inside the generated scanner +class, lexical states and macro declarations. Each JFlex option must begin +a line of the specification and starts with a %. In our example +the following options are used: + +

+ +

+ +

+The code included in %{...%} +is copied verbatim into the generated lexer class source. +Here you can declare member variables and functions that are used +inside scanner actions. In our example we declare a StringBuffer ``string'' +in which we will store parts of string literals and two helper functions +``symbol'' that create java_cup.runtime.Symbol objects +with position information of the current token (see section [*] +JFlex and CUP +for how to interface with the parser generator CUP). As JFlex options, both +%{ and \%} must begin a line. + +

+The specification continues with macro declarations. Macros are +abbreviations for regular expressions, used to make lexical specifications +easier to read and understand. A macro declaration +consists of a macro identifier followed by =, then followed by +the regular expression it represents. This regular expression may +itself contain macro usages. Although this allows a grammar like specification +style, macros are still just abbreviations and not non terminals - they +cannot be recursive or mutually recursive. Cycles in macro definitions +are detected and reported at generation time by JFlex. + +

+Here some of the example macros in more detail: + +

+ +

+The last part of the second section in our +lexical specification is a lexical state declaration: +%state STRING +declares a lexical state STRING that can be +used in the ``lexical rules'' part of the specification. A state declaration +is a line starting with %state followed by a space or comma +separated list of state identifiers. There can be more than one line starting +with %state. + +

+ +


+Rules and Actions +

+The "lexical rules" section of a JFlex specification contains regular expressions +and actions (Java code) that are executed when the scanner matches the +associated regular expression. As the scanner reads its input, it keeps +track of all regular expressions and activates the action of the expression +that has the longest match. Our specification above for instance would with input +"breaker" match the regular expression for Identifier +and not the keyword "break" +followed by the Identifier "er", because rule {Identifier} +matches more of this input at once (i.e. it matches all of it) +than any other rule in the specification. If two regular expressions both +have the longest match for a certain input, the scanner chooses the action +of the expression that appears first in the specification. In that way, we +get for input "break" the keyword "break" and not an +Identifier "break". + +

+Additional to regular expression matches, one can use lexical states to +refine a specification. A lexical state acts like a start condition. +If the scanner is in lexical state STRING, only expressions that +are preceded by the start condition <STRING> can be matched. +A start condition of a regular expression can contain more than one lexical +state. It is then matched when the lexer is in any of these lexical states. +The lexical state YYINITIAL is predefined and is also the state +in which the lexer begins scanning. If a regular expression has no start +conditions it is matched in all lexical states. + +

+Since you often have a bunch of expressions with the same start conditions, +JFlex allows the same abbreviation as the Unix tool flex: +

+<STRING> {
+  expr1   { action1 }
+  expr2   { action2 }
+}
+
+means that both expr1 and expr2 have start condition <STRING>. + +

+The first three rules in our example demonstrate the syntax of a regular +expression preceded by the start condition <YYINITIAL>. + +

+<YYINITIAL> "abstract" { return symbol(sym.ABSTRACT); } + +

+matches the input "abstract" only if the scanner is in its +start state "YYINITIAL". When the string "abstract" is +matched, the scanner function returns the CUP symbol sym.ABSTRACT. +If an action does not return a value, the scanning process is resumed immediately +after executing the action. + +

+The rules enclosed in + +

+<YYINITIAL> { +
... +
}
+ +

+demonstrate the abbreviated syntax and are also only matched in state YYINITIAL. + +

+Of these rules, one may be of special interest: + +

+\" { string.setLength(0); yybegin(STRING); } + +

+If the scanner matches a double quote in state YYINITIAL we +have recognized the start of a string literal. Therefore we clear our StringBuffer +that will hold the content of this string literal and tell the scanner +with yybegin(STRING) to switch into the lexical state STRING. +Because we do not yet return a value to the parser, our scanner proceeds +immediately. + +

+In lexical state STRING another +rule demonstrates how to refer to the input that has been matched: + +

+[^\n\r\"]+ { string.append( yytext() ); } + +

+The expression [^\n\r\"]+ matches +all characters in the input up to the next backslash (indicating an +escape sequence such as \n), double quote (indicating the end +of the string), or line terminator (which must not occur in a string literal). +The matched region of the input is referred to with yytext() +and appended to the content of the string literal parsed so far. + +

+The last lexical rule in the example specification +is used as an error fallback. It matches any character in any state that +has not been matched by another rule. It doesn't conflict with any other +rule because it has the least priority (because it's the last rule) and +because it matches only one character (so it can't have longest match +precedence over any other rule). + +

+ +

+How to get it going +

+ + + +

+ +


+Lexical Specifications +

+As shown above, a lexical specification file for JFlex consists of three +parts divided by a single line starting with %%: + +

+UserCode +
%% +
Options and declarations +
%% +
Lexical rules + +

+In all parts of the specification comments of the form +/* comment text */ and the Java style end of line comments starting with // +are permitted. JFlex comments do nest - so the number of /* and */ +should be balanced. + +

+ +


+User code +

+The first part contains user code that is copied verbatim into the beginning +of the source file of the generated lexer before the scanner class is declared. +As shown in the example above, this is the place to put package +declarations and import +statements. It is possible, but not considered as good Java programming +style to put own helper class (such as token classes) in this section. +They should get their own .java file instead. + +

+ +


+Options and declarations +

+The second part of the lexical specification contains options +to customize your generated lexer (JFlex directives and Java code to include in +different parts of the lexer), declarations of lexical states and +macro definitions for use in the third section +``Lexical rules'' of the lexical specification file. + +

+Each JFlex directive must be situated at the beginning of a line +and starts with the % character. Directives that have one or +more parameters are described as follows: + +

+%class "classname" + +

+means that you start a line with %class followed by a space followed +by the name of the class for the generated scanner (the double quotes are +not to be entered, see the example specification in +section [*]). + +

+ +


+Class options and user class code +

+These options regard name, constructor, API, and related parts of the +generated scanner class. + + + +

+ +


+Scanning method +

+This section shows how the scanning method can be customized. You can redefine +the name and return type of the method and it is possible to declare +exceptions that may be thrown in one of the actions of the specification. +If no return type is specified, the scanning method will be declared as +returning values of class Yytoken. + + + +

+ +


+The end of file +

+There is always a default value that the scanning method will return when +the end of file has been reached. You may however define a specific value +to return and a specific piece of code that should be executed when the +end of file is reached. + +

+The default end of file values depends on the return type of the scanning method: + +

+ +

+User values and code to be executed at the end of file can be defined using these directives: + +

+ +

+ +


+Standalone scanners +

+ + + +

+ +


+CUP compatibility +

+You may also want to read section [*] JFlex and CUP +if you are interested in how to interface your generated +scanner with CUP. + + + +

+ +


+BYacc/J compatibility +

+You may also want to read section [*] JFlex and BYacc/J +if you are interested in how to interface your generated +scanner with Byacc/J. + + + +

+ +


+Code generation +

+The following options define what kind of lexical analyzer code JFlex +will produce. %pack is the default setting and will be used, +when no code generation method is specified. + +

+ +

+ +

+ +


+Character sets +

+ + +


+Line, character and column counting +

+ + + +

+ +


+Obsolete JLex options +

+ + + +

+ +


+State declarations +

+State declarations have the following from: + +

+%s[tate] "state identifier" [, "state identifier", ... ] for inclusive or +
%x[state] "state identifier" [, "state identifier", ... ] for exlusive states + +

+There may be more than one line of state declarations, each starting with +%state or %xstate (the first character is sufficient, +%s and %x works, too). State identifiers are letters followed +by a sequence of letters, digits or underscores. State identifiers can be separated +by whitespace or comma. + +

+The sequence + +

+%state STATE1 +
%xstate STATE3, XYZ, STATE_10 +
%state ABC STATE5 + +

+declares the set of identifiers STATE1, STATE3, XYZ, + STATE_10, ABC, STATE5 as lexical states, STATE1, ABC, STATE5 +as inclusive, and STATE3, XYZ, STATE_10 as exclusive. +See also section +[*] on the way lexical states influence how the input is +matched. + +

+ +


+Macro definitions +

+A macro definition has the form + +

+macroidentifier = regular expression + +

+That means, a macro definition is a macro identifier (letter followed +by a sequence of letters, digits or underscores), that can later be +used to reference the macro, followed by optional whitespace, followed +by an "=", followed by optional whitespace, followed by a +regular expression (see section [*] lexical + rules for more information about regular expressions). + +

+The regular expression on the right hand side must be well formed and +must not contain the ^, / or $ operators. Differently +to JLex, macros are not just pieces of text that are expanded by copying +- they are parsed and must be well formed. + +

+This is a feature. It eliminates some very hard to find bugs in +lexical specifications (such like not having parentheses around more +complicated macros - which is not necessary with JFlex). See section +[*] Porting from JLex for more +details on the problems of JLex style macros. + +

+Since it is allowed to have macro usages in macro definitions, it is +possible to use a grammar like notation to specify the desired lexical +structure. Macros however remain just abbreviations of the regular expressions +they represent. They are not non terminals of a grammar and cannot be used +recursively in any way. JFlex detects cycles in macro definitions and reports +them at generation time. JFlex also warns you about macros that have been +defined but never used in the ``lexical rules'' section of the specification. + +

+ +


+Lexical rules +

+The ``lexical rules'' section of an JFlex specification contains a set of +regular expressions and actions (Java code) that are executed when the +scanner matches the associated regular expression. + +

+ +


+Syntax +

+The syntax of the "lexical rules" section is described by the following +BNF grammar (terminal symbols are enclosed in 'quotes'): + +

+

+LexicalRules ::= Rule+ 
+Rule         ::= [StateList] ['^'] RegExp [LookAhead] Action 
+               | [StateList] '<<EOF>>' Action
+               | StateGroup 
+StateGroup   ::= StateList '{' Rule+ '}' 
+StateList    ::= '<' Identifier (',' Identifier)* '>' 
+LookAhead    ::= '$' | '/' RegExp
+Action       ::= '{' JavaCode '}' | '|'
+
+RegExp       ::= RegExp '|' RegExp 
+               | RegExp RegExp 
+               | '(' RegExp ')'
+               | ('!'|'~') RegExp
+               | RegExp ('*'|'+'|'?')
+               | RegExp "{" Number ["," Number] "}" 
+               | '[' ['^'] (Character|Character'-'Character)* ']' 
+               | PredefinedClass 
+               | '{' Identifier '}' 
+               | '"' StringCharacter+ '"' 
+               | Character 
+
+PredefinedClass ::= '[:jletter:]' 
+                  | '[:jletterdigit:]' 
+                  | '[:letter:]' 
+                  | '[:digit:]' 
+                  | '[:uppercase:]' 
+                  | '[:lowercase:]' 
+                  | '.'
+
+ +

+The grammar uses the following terminal symbols: + +

+ +

+Please note that the \n escape sequence stands for the ASCII +LF character - not for the end of line. If you would like to match the +line terminator, you should use the expression \r|\n|\r\n if you want +the Java conventions, or \r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085 +if you want to be fully Unicode compliant (see also [5]). + +

+As of version 1.1 of JFlex the whitespace characters " " +(space) and "\t" (tab) can be used to improve the readability of +regular expressions. They will be ignored by JFlex. In character +classes and strings however, whitespace characters keep standing for +themselves (so the string " " still matches exactly one space +character and [ \n] still matches an ASCII LF or a space +character). + +

+JFlex applies the following standard operator precedences in regular +expression (from highest to lowest): + +

+ +

+ +

+So the expression a | abc | !cd* for instance is parsed as +(a|(abc)) | ((!c)(d*)). + +

+ +


+Semantics +

+This section gives an informal description of which text is matched by +a regular expression (i.e. an expression described by the RegExp +production of the grammar presented above). + +

+A regular expression that consists solely of + +

+ +

+If a and b are regular expressions, then + +

+

+
a | b
+
(union) + +

+is the regular expression, that matches + all input that is matched by a or by b. + +

+

+
a b
+
(concatenation) + +

+is the regular expression, + that matches the input matched by a followed by the + input matched by b. + +

+

+
a*
+
(kleene closure) + +

+matches zero or more repetitions + of the input matched by a + +

+

+
a+
+
(iteration) + +

+is equivalent to aa* + +

+

+
a?
+
(option) + +

+matches the empty input or the input matched + by a + +

+

+
!a
+
(negation) + +

+matches everything but the strings matched by a. + Use with care: the construction of !a involves + an additional, possibly exponential NFA to DFA transformation + on the NFA for a. Note that + with negation and union you also have (by applying DeMorgan) + intersection and set difference: the intersection of + a and b is !(!a|!b), the expression + that matches everything of a not matched by b is + !(!a|b) + +

+

+
~a
+
(upto) + +

+matches everything up to (and including) the first occurrence of a text + matched by a. The expression ~a is equivalent + to !([^]* a [^]* | "") a. A traditional C-style comment + is matched by "/*" ~"*/" + +

+

+
a{n}
+
(repeat) + +

+is equivalent to n times the concatenation of a. + So a{4} for instance is equivalent to the expression a a a a. + The decimal integer n must be positive. + +

+

+
a{n,m}
+
is equivalent to at least n times and at most m times the + concatenation of a. So a{2,4} for instance is equivalent + to the expression a a a? a?. Both n and m are non + negative decimal integers and m must not be smaller than n. + +

+

+
( a )
+
matches the same input as a. + +

+

+
+ +

+In a lexical rule, a regular expression r may be preceded by a +'^' (the beginning of line operator). r is then +only matched at the beginning of a line in the input. A line begins +after each occurrence of \r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085 +(see also [5]) and at the beginning of input. +The preceding line terminator in the input is not consumed and can +be matched by another rule. + +

+In a lexical rule, a regular expression r may be followed by a +lookahead expression. A lookahead expression is either a '$' +(the end of line operator) or a '/' followed by an arbitrary +regular expression. In both cases the lookahead is not consumed and +not included in the matched text region, but it is considered +while determining which rule has the longest match (see also +[*] How the input is matched). + +

+In the '$' case r is only matched at the end of a line in +the input. The end of a line is denoted by the regular expression +\r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085. +So a$ is equivalent to a / \r|\n|\r\n|\u2028|\u2029|\u000B|\u000C|\u0085.This is a bit different to the situation described in [5]: +since in JFlex $ is a true trailing context, the end of file +does not count as end of line. + +

+ +

+For arbitrary lookahead (also called trailing context) the +expression is matched only when followed by input that matches the +trailing context. Unfortunately the lookahead expression is not +really arbitrary: In a rule r1 / r2, either the text matched +by r1 must have a fixed length (e.g. if r1 is a string) +or the beginning of the trailing context r2 must not match the +end of r1. So for example "abc" / "a"|"b" is ok because +"abc" has a fixed length, "a"|"ab" / "x"* is ok because +no prefix of "x"* matches a postfix of "a"|"ab", but +"x"|"xy" / "yx" is not possible, because the postfix "y" +of "x"|"xy" is also a prefix of "yx". JFlex will report +such cases at generation time. The algorithm JFlex currently uses for matching +trailing context expressions is the one described in [1] (leading +to the deficiencies mentioned above). + +

+As of version 1.2, JFlex allows lex/flex style «EOF» rules in +lexical specifications. A rule +

+[StateList]  <<EOF>>    { some action code }
+
+is very similar to the %eofval directive (section [*]). +The difference lies in the optional StateList that may precede the «EOF» rule. The +action code will only be executed when the end of file is read and the +scanner is currently in one of the lexical states listed in StateList. +The same StateGroup (see section [*] +How the input is matched) and precedence +rules as in the ``normal'' rule case apply +(i.e. if there is more than one «EOF» +rule for a certain lexical state, the action of the one appearing +earlier in the specification will be executed). «EOF» rules +override settings of the %cup and %byaccj options and +should not be mixed with the %eofval directive. + +

+An Action consists either of a piece of Java code enclosed in +curly braces or is the special | action. The | action is +an abbreviation for the action of the following expression. + +

+Example: +

+expression1   |
+expression2   |
+expression3   { some action }
+
+is equivalent to the expanded form +
+expression1   { some action }
+expression2   { some action }
+expression3   { some action }
+
+ +

+They are useful when you work with trailing context expressions. The +expression a | (c / d) | b is not syntactically legal, but can +easily be expressed using the | action: +

+a       |
+c / d   |
+b       { some action }
+
+ +

+ +


+How the input is matched +

+When consuming its input, the scanner determines the regular expression +that matches the longest portion of the input (longest match rule). If +there is more than one regular expression that matches the longest portion +of input (i.e. they all match the same input), the generated scanner chooses +the expression that appears first in the specification. After determining +the active regular expression, the associated action is executed. If there +is no matching regular expression, the scanner terminates the program with +an error message (if the %standalone directive has been used, the +scanner prints the unmatched input to java.lang.System.out instead +and resumes scanning). + +

+Lexical states can be used to further restrict the set of regular expressions +that match the current input. + +

+ +

+ +

+ +

+The generated class +

+JFlex generates exactly one file containing one class from the specification +(unless you have declared another class in the first specification section). + +

+The generated class contains (among other things) the DFA tables, an input buffer, +the lexical states of the specification, a constructor, and the scanning method +with the user supplied actions. + +

+The name of the class is by default Yylex, it is customizable +with the %class directive (see also section +[*]). The input buffer of the lexer is connected with an +input stream over the java.io.Reader object which is passed +to the lexer in the generated constructor. If you want to provide your +own constructor for the lexer, you should always call the generated +one in it to initialize the input buffer. The input buffer should not +be accessed directly, but only over the advertised API (see also +section [*]). Its internal implementation may change +between releases or skeleton files without notice. + +

+The main interface to the outside world is the generated scanning +method (default name yylex, default return type +Yytoken). Most of its aspects are customizable (name, return +type, declared exceptions etc., see also section +[*]). If it is called, it will consume input until +one of the expressions in the specification is matched or an error +occurs. If an expression is matched, the corresponding action is +executed. It may return a value of the specified return type (in which +case the scanning method return with this value), or if it doesn't +return a value, the scanner resumes consuming input until the next +expression is matched. If the end of file is reached, the scanner +executes the EOF action, and (also upon each further call to the scanning +method) returns the specified EOF value (see also section [*]). + +

+ +


+Scanner methods and fields accessible in actions (API) +

+Generated methods and member fields in JFlex scanners are prefixed +with yy to indicate that they are generated and to avoid name +conflicts with user code copied into the class. Since user code is +part of the same class, JFlex has no language means like the +private modifier to indicate which members and methods are +internal and which ones belong to the API. Instead, JFlex follows a +naming convention: everything starting with a zz prefix like +zzStartRead is to be considered internal and subject to +change without notice between JFlex releases. Methods and members of +the generated class that do not have a zz prefix like +yycharat belong to the API that the scanner class provides to +users in action code of the specification. They will be remain stable +and supported between JFlex releases as long as possible. + +

+Currently, the API consists of the following methods and member fields: + +

+ +

+ +


+Encodings, Platforms, and Unicode +

+ +

+This section tries to shed some light on the issues of Unicode and +encodings, cross platform scanning, and how to deal with binary data. +My thanks go to Stephen Ostermiller for his input on this topic. + +

+ +


+The Problem +

+ +

+Before we dive straight into details, let's take a look at what the +problem is. The problem is Java's platform independence when you want +to use it. For scanners the interesting part about platform +independence is character encodings and how they are handled. + +

+If a program reads a file from disk, it gets a stream of bytes. In +earlier times, when the grass was green, and the world was much +simpler, everybody knew that the byte value 65 is, of course, an A. +It was no problem to see which bytes meant which characters (actually +these times never existed, but anyway). The normal Latin alphabet +only has 26 characters, so 7 bits or 128 distinct values should surely +be enough to map them, even if you allow yourself the luxury of upper +and lower case. Nowadays, things are different. The world suddenly +grew much larger, and all kinds of people wanted all kinds of special +characters, just because they use them in their language and writing. +This is were the mess starts. Since the 128 distinct values were +already filled up with other stuff, people began to use all 8 bits of +the byte, and extended the byte/character mappings to fit their need, +and of course everybody did it differently. Some people for instance +may have said ``let's use the value 213 for the German character ä''. Others +may have found that 213 should much rather mean é, because they didn't need +German and wrote French instead. As long as you use your program and +data files only on one platform, this is no problem, as all know what +means what, and everything gets used consistently. + +

+Now Java comes into play, and wants to run everywhere (once written, +that is) and now there suddenly is a problem: how do I get the same +program to say ä to a certain byte when it runs in Germany and maybe é +when it runs in France? And also the other way around: when I want to +say é on the screen, which byte value should I send to the operating +system? + +

+Java's solution to this is to use Unicode internally. Unicode aims to +be a superset of all known character sets and is therefore a perfect base +for encoding things that might get used all over the world. To make +things work correctly, you still have to know where you are and how to +map byte values to Unicode characters and vice versa, but the +important thing is, that this mapping is at least possible (you can +map Kanji characters to Unicode, but you cannot map them to ASCII or +iso-latin-1). + +

+ +


+Scanning text files +

+ +

+Scanning text files is the standard application for scanners like +JFlex. Therefore it should also be the most convenient one. Most times +it is. + +

+The following scenario works like a breeze: +You work on a platform X, write your lexer specification there, can +use any obscure Unicode character in it as you like, and compile the +program. Your users work on any platform Y (possibly but not +necessarily something different from X), they write their input files +on Y and they run your program on Y. No problems. + +

+Java does this as follows: +If you want to read anything in Java that is supposed to contain text, +you use a FileReader or some InputStream together with +an InputStreamReader. InputStreams return the raw bytes, the +InputStreamReader converts the bytes into Unicode characters with +the platform's default encoding. If a text file is produced on the +same platform, the platform's default encoding should do the mapping +correctly. Since JFlex also uses readers and Unicode internally, this +mechanism also works for the scanner specifications. If you write an +A in your text editor and the editor uses the platform's encoding (say A is 65), +then Java translates this into the logical Unicode A internally. +If a user writes an A on a completely different platform (say A is 237 there), +then Java also translates this into the logical Unicode A internally. Scanning +is performed after that translation and both match. + +

+Note that because of this mapping from bytes to characters, you should always +use the %unicode switch in you lexer specification if you want to scan +text files. %8bit may not be enough, even if +you know that your platform only uses one byte per character. The encoding +Cp1252 used on many Windows machines for instance knows 256 characters, but +the character ´ with Cp1252 code \x92 has the Unicode value \u2019, which +is larger than 255 and which would make your scanner throw an +ArrayIndexOutOfBoundsException if it is encountered. + +

+So for the usual case you don't have to do anything but use the +%unicode switch in your lexer specification. + +

+Things may break when you produce a text file on platform X and +consume it on a different platform Y. Let's say you have a file +written on a Windows PC using the encoding Cp1252. Then you move +this file to a Linux PC with encoding ISO 8859-1 and there you want +to run your scanner on it. Java now thinks the file is encoded +in ISO 8859-1 (the platform's default encoding) while it really is +encoded in Cp1252. For most characters +Cp1252 and ISO 8859-1 are the same, but for the byte values \x80 +to \x9f they disagree: ISO 8859-1 is undefined there. You can fix +the problem by telling Java explicitly which encoding to use. When +constructing the InputStreamReader, you can give the encoding +as argument. The line +

+Reader r = new InputStreamReader(input, "Cp1252"); + +
+will do the trick. + +

+Of course the encoding to use can also come from the data itself: +for instance, when you scan a HTML page, it may have embedded +information about its character encoding in the headers. + +

+More information about encodings, which ones are supported, how +they are called, and how to set them may be found in the +official Java documentation in the chapter about +internationalization. +The link +http://java.sun.com/j2se/1.3/docs/guide/intl/ +leads to an online version of this for Sun's JDK 1.3. + +

+ +


+Scanning binaries +

+ +

+Scanning binaries is both easier and more difficult +than scanning text files. It's easier because you want +the raw bytes and not their meaning, i.e. you don't want +any translation. +It's more difficult because it's not so easy to get +``no translation'' when you use Java readers. + +

+The problem (for binaries) is that JFlex scanners are +designed to work on text. Therefore the interface is +the Reader class (there is a constructor +for InputStream instances, but it's just there +for convenience and wraps an InputStreamReader +around it to get characters, not bytes). +You can still get a binary scanner when you write +your own custom InputStreamReader class that +does explicitly no translation, but just copies +byte values to character codes instead. It sounds +quite easy, and actually it is no big deal, but there +are a few little pitfalls on the way. In the scanner +specification you can only enter positive character +codes (for bytes that is \x00 +to \xFF). Java's byte type on the other hand +is a signed 8 bit integer (-128 to 127), so you have to convert +them properly in your custom Reader. Also, you should +take care when you write your lexer spec: if you +use text in there, it gets interpreted by an encoding +first, and what scanner you get as result might depend +on which platform you run JFlex on when you generate +the scanner (this is what you want for text, but for binaries it +gets in the way). If you are not sure, or if the development +platform might change, it's probably best to use character +code escapes in all places, since they don't change their +meaning. + +

+To illustrate these points, the example in examples/binary +contains a very small binary scanner that tries to +detect if a file is a Java class file. For that +purpose it looks if the file begins with the magic number \xCAFEBABE. + +

+ +


+A few words on performance +

+This section gives some empirical results about the speed of JFlex generated +scanners in comparison to those generated by JLex, +compares a JFlex scanner with a handwritten +one, and presents some tips on how to make +your specification produce a faster scanner. + +

+ +


+Comparison of JLex and JFlex +

+Scanners generated by the tool JLex are quite fast. It was however +possible to further improve the performance of generated scanners +using JFlex. The following table shows the results that were produced +by the scanner specification of a small toy programming language (in +fact the example from the JLex website). The scanner was generated +using JLex and all three different JFlex code generation methods. Then +it was run on a W98 system using Sun's JDK 1.3 with different sample inputs +of that toy programming language. All test runs were made under the +same conditions on an otherwise idle machine. + +

+The values presented in the table denote the time from the first call +to the scanning method to returning the EOF value and the speedup in +percent. The tests were run both int the mixed (HotSpot) JVM mode and +the pure interpreted mode. The mixed mode JVM brings +about a factor of 10 performance improvement, the difference between +JLex and JFlex only decreases slightly. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 KBJVMJLex%switchspeedup%tablespeedup%packspeedup
 496hotspot325 ms261 ms24.5 %261 ms24.5 %261 ms24.5 %
 187hotspot127 ms98 ms29.6 %94 ms35.1 %96 ms32.3 %
 93hotspot66 ms50 ms32.0 %50 ms32.0 %48 ms37.5 %
 496interpr.4009 ms3025 ms32.5 %3258 ms23.1 %3231 ms24.1 %
 187interpr.1641 ms1155 ms42.1 %1245 ms31.8 %1234 ms33.0 %
 93interpr.817 ms573 ms42.6 %617 ms32.4 %613 ms33.3 %
+ +


+ +

+Since the scanning time of the lexical analyzer examined in the table +above includes lexical actions that often need to create new object instances, +another table shows the execution time for the same specification with empty +lexical actions to compare the pure scanning engines. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 KBJVMJLex%switchspeedup%tablespeedup%packspeedup
 496hotspot204 ms140 ms45.7 %138 ms47.8 %140 ms45.7 %
 187hotspot83 ms55 ms50.9 %52 ms59.6 %52 ms59.6 %
 93hotspot41 ms28 ms46.4 %26 ms57.7 %26 ms57.7 %
 496interpr.2983 ms2036 ms46.5 %2230 ms33.8 %2232 ms33.6 %
 187interpr.1260 ms793 ms58.9 %865 ms45.7 %867 ms45.3 %
 93interpr.628 ms395 ms59.0 %432 ms45.4 %432 ms45.4 %
+ +


+ +

+Execution time of single instructions depends on the platform and +the implementation of the Java Virtual Machine the program is executed +on. Therefore the tables above cannot be used as a reference to which +code generation method of JFlex is the right one to choose in general. +The following table was produced by the same lexical specification and +the same input on a Linux system also using Sun's JDK 1.3. + +

+With actions: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 KBJVMJLex%switchspeedup%tablespeedup%packspeedup
 496hotspot246 ms203 ms21.2 %193 ms27.5 %190 ms29.5 %
 187hotspot99 ms76 ms30.3 %69 ms43.5 %70 ms41.4 %
 93hotspot48 ms36 ms33.3 %34 ms41.2 %35 ms37.1 %
 496interpr.3251 ms2247 ms44.7 %2430 ms33.8 %2444 ms33.0 %
 187interpr.1320 ms848 ms55.7 %958 ms37.8 %920 ms43.5 %
 93interpr.658 ms423 ms55.6 %456 ms44.3 %452 ms45.6 %
+ +


+ +

+Without actions: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 KBJVMJLex%switchspeedup%tablespeedup%packspeedup
 496hotspot136 ms78 ms74.4 %76 ms78.9 %77 ms76.6 %
 187hotspot59 ms31 ms90.3 %48 ms22.9 %32 ms84.4 %
 93hotspot28 ms15 ms86.7 %15 ms86.7 %15 ms86.7 %
 496interpr.1992 ms1047 ms90.3 %1246 ms59.9 %1215 ms64.0 %
 187interpr.859 ms408 ms110.5 %479 ms79.3 %487 ms76.4 %
 93interpr.435 ms200 ms117.5 %237 ms83.5 %242 ms79.8 %
+ +


+ +

+Although all JFlex scanners were faster than those generated by JLex, +slight differences between JFlex code generation methods show up when compared +to the run on the W98 system. + +

+The following table compares a handwritten scanner for the Java language +obtained from the website of CUP with the JFlex generated scanner for Java +that comes with JFlex in the examples directory. They were tested +on different .java files on a Linux machine with Sun's JDK 1.3. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 linesKBJVMhandwritten scannerJFlex generated scanner
 19050496hotspot824 ms248 ms235 % faster
 6350165hotspot272 ms84 ms232 % faster
 127033hotspot53 ms18 ms194 % faster
 19050496interpreted5.83 s3.85 s51 % faster
 6350165interpreted1.95 s1.29 s51 % faster
 127033interpreted0.38 s0.25 s52 % faster
+ +


+ +

+Although JDK 1.3 seems to speed up the handwritten scanner if compared +to JDK 1.1 or 1.2 more than the generated one, the generated scanner is +still up to 3.3 times as fast as the handwritten one. One example of +a handwritten scanner that is +considerably slower than the equivalent generated one is surely no +proof for all generated scanners being faster than handwritten. It is +clearly impossible to prove something like that, since you could +always write the generated scanner by hand. From a software +engineering point of view however, there is no excuse for writing a +scanner by hand since this task takes more time, is more difficult and +therefore more error prone than writing a compact, readable and easy +to change lexical specification. (I'd like to add, that I do not +think, that the handwritten scanner from the CUP website used here in +the test is stupid or badly written or anything like that. I actually +think, Scott did a great job with it, and that for learning about +lexers it is quite valuable to study it or even to write a similar one +for oneself.) + +

+ +


+How to write a faster specification +

+Although JFlex generated scanners show good performance without +special optimizations, there are some heuristics that can make a +lexical specification produce an even faster scanner. Those are +(roughly in order of performance gain): + +

+ +

+ +

+Note that writing more rules in a specification does not make the generated +scanner slower (except when you have to switch to another code generation +method because of the larger size). + +

+The two main rules of optimization apply also for lexical specifications: + +

    +
  1. don't do it +
  2. +
  3. (for experts only) don't do it yet +
  4. +
+ +

+Some of the performance tips above contradict a readable and compact +specification style. When in doubt or when requirements are not or not +yet fixed: don't use them - the specification can always be optimized +in a later state of the development process. + +

+ +

+Porting Issues +

+ +

+ +


+Porting from JLex +

+JFlex was designed to read old JLex specifications unchanged and to +generate a scanner which behaves exactly the same as the one generated +by JLex with the only difference of being faster. + +

+This works as expected on all well formed JLex specifications. + +

+Since the statement above is somewhat absolute, let's take a look at +what ``well formed'' means here. A JLex specification is well formed, when +it + +

+ +

+ +


+Porting from lex/flex +

+This section tries to give an overview of activities and possible +problems when porting a lexical specification from the C/C++ tools lex +and flex [11] available on most Unix systems to JFlex. + +

+Most of the C/C++ specific features are naturally not present in JFlex, +but most ``clean'' lex/flex lexical specifications can be ported to +JFlex without very much work. + +

+This section is by far not complete and is based mainly on a survey of +the flex man page and very little personal experience. If you do +engage in any porting activity from lex/flex to JFlex and encounter +problems, have better solutions for points presented here or have just +some tips you would like to share, please do contact me. I will +incorporate your experiences in this manual (with all due credit to you, +of course). + +

+ +

+Basic structure +

+A lexical specification for flex has the following basic structure: +
+definitions
+%%
+rules
+%%
+user code
+
+ +

+The user code section usually contains some C code that is used +in actions of the rules part of the specification. For JFlex most +of this code will have to be included in the class code %{..%} +directive in the options and declarations section (after +translating the C code to Java, of course). + +

+ +

+Macros and Regular Expression Syntax +

+The definitions section of a flex specification is quite similar +to the options and declarations part of JFlex specs. + +

+Macro definitions in flex have the form: +

+<identifier>  <expression>
+
+To port them to JFlex macros, just insert a = between <identifier> +and <expression>. + +

+The syntax and semantics of regular expressions in flex are pretty much the +same as in JFlex. A little attention is needed for some escape sequences +present in flex (such as \a) that are not supported in JFlex. These +escape sequences should be transformed into their octal or hexadecimal +equivalent. + +

+Another point are predefined character classes. Flex offers the ones directly +supported by C, JFlex offers the ones supported by Java. These classes will +sometimes have to be listed manually (if there is need for this feature, it +may be implemented in a future JFlex version). + +

+ +

+Lexical Rules +

+Since flex is mostly Unix based, the '^' (beginning of line) and +'$' (end of line) operators, consider the \n character as only line terminator. This should usually cause not much problems, but you +should be prepared for occurrences of \r or \r\n or one of +the characters \u2028, \u2029, \u000B, \u000C, +or \u0085. They are considered to be line terminators in Unicode and +therefore may not be consumed when +^ or $ is present in a rule. +

+The trailing context algorithm of flex is better than the one used in +JFlex. Therefore lookahead expressions could cause major headaches. JFlex +will issue an error message at generation time, if it cannot generate +a scanner for a certain lookahead expression. (sorry, I have no more tips here +on that yet. If anyone knows how the flex lookahead algorithm works (or any better one) +and can be efficiently implemented, again: please contact me). + +

+ +


+Working together +

+ +

+ +


+JFlex and CUP +

+One of the main design goals of JFlex was to make interfacing with the free +Java parser generator CUP [8] as easy as possibly. +This has been done by giving +the %cup directive a special meaning. An +interface however always has two sides. This section concentrates on the +CUP side of the story. + +

+ +

+CUP version 0.10j +

+Since CUP version 0.10j, this has been simplified greatly by the new +CUP scanner interface java_cup.runtime.Scanner. JFlex lexers now implement +this interface automatically when then %cup +switch is used. There are no special parser code, init + code or scan with options any more that you have to provide +in your CUP parser specification. You can just concentrate on your grammar. + +

+If your generated Lexer has the class name Scanner, the parser +is started from the a main program like this: + +

+

+...
+  try {
+    parser p = new parser(new Scanner(new FileReader(fileName)));
+    Object result = p.parse().value;
+  }
+  catch (Exception e) {
+...
+
+ +

+ +

+Using existing JFlex/CUP specifications with CUP 0.10j +

+If you already have an existing specification and you would like to upgrade +both JFlex and CUP to their newest version, you will probably have to adjust +your specification. + +

+The main difference between the %cup switch in +JFlex 1.2.1 and lower, and the current JFlex version is, that JFlex scanners +now automatically implement the java_cup.runtime.Scanner interface. +This means, that the scanning function now changes its name from yylex() +to next_token(). + +

+The main difference from older CUP versions to 0.10j is, that CUP now +has a default constructor that accepts a java_cup.runtime.Scanner +as argument and that uses this scanner as +default (so no scan with code is necessary any more). + +

+If you have an existing CUP specification, it will probably look somewhat like this: +

+parser code {:
+  Lexer lexer;
+
+  public parser (java.io.Reader input) {
+    lexer = new Lexer(input);
+  }
+:};
+
+scan with {: return lexer.yylex(); :};
+
+ +

+To upgrade to CUP 0.10j, you could change it to look like this: +

+parser code {:
+  public parser (java.io.Reader input) {
+    super(new Lexer(input));
+  }
+:};
+
+ +

+If you do not mind to change the method that is calling the parser, +you could remove the constructor entirely (and if there is nothing else +in it, the whole parser code section as well, of course). The calling +main procedure would then construct the parser as shown in the section above. + +

+The JFlex specification does not need to be changed. + +

+ +

+Using older versions of CUP +

+For people, who like or have to use older versions of CUP, the following section +explains ``the old way''. Please note, that the standard name of the scanning +function with the %cup switch is not +yylex(), but next_token(). + +

+If you have a scanner specification that begins like this: + +

+

+package PACKAGE;
+import java_cup.runtime.*;   /* this is convenience, but not necessary */
+ 
+%%
+ 
+%class Lexer
+%cup
+..
+
+ +

+then it matches a CUP specification starting like + +

+

+package PACKAGE;
+
+parser code {:
+  Lexer lexer;
+
+  public parser (java.io.Reader input) {
+    lexer = new Lexer(input);
+  }
+:};
+
+scan with {: return lexer.next_token(); :};
+
+..
+
+ +

+This assumes that the generated parser will get the name parser. +If it doesn't, you have to adjust the constructor name. + +

+The parser can then be started in a main routine like this: + +

+

+..
+  try {
+    parser p = new parser(new FileReader(fileName));
+    Object result = p.parse().value; 
+  }
+  catch (Exception e) {
+..
+
+ +

+If you want the parser specification to be independent of the name of the generated +scanner, you can instead write an interface Lexer + +

+

+public interface Lexer {
+  public java_cup.runtime.Symbol next_token() throws java.io.IOException;
+}
+
+ +

+change the parser code to: + +

+

+package PACKAGE;
+
+parser code {:
+  Lexer lexer;
+
+  public parser (Lexer lexer) {
+    this.lexer = lexer;
+  }
+:};
+
+scan with {: return lexer.next_token(); :};
+
+..
+
+ +

+tell JFlex about the Lexer +interface using the %implements +directive: + +

+

+..
+%class Scanner     /* not Lexer now since that is our interface! */
+%implements Lexer
+%cup
+..
+
+ +

+and finally change the main routine to look like + +

+

+...
+  try {
+    parser p = new parser(new Scanner(new FileReader(fileName)));
+    Object result = p.parse().value;
+  }
+  catch (Exception e) {
+...
+
+ +

+If you want to improve the error messages that CUP generated parsers +produce, you can also override the methods report_error and report_fatal_error +in the ``parser code'' section of the CUP specification. The new methods +could for instance use yyline and yycolumn (stored in +the left and right members of class java_cup.runtime.Symbol) +to report error positions more conveniently for the user. The lexer and +parser for the Java language in the examples/java directory of the +JFlex distribution use this style of error reporting. These specifications +also demonstrate the techniques above in action. + +

+ +


+JFlex and BYacc/J +

+ +

+JFlex has builtin support for the Java extension +BYacc/J +[9] by Bob Jamison +to the classical Berkeley Yacc parser generator. +This section describes how to interface BYacc/J with JFlex. It +builds on many helpful suggestions and comments from Larry Bell. + +

+Since Yacc's architecture is a bit different from CUP's, the +interface setup also works in a slightly different manner. +BYacc/J expects a function int yylex() in the parser +class that returns each next token. Semantic values are expected +in a field yylval of type parserval where ``parser'' +is the name of the generated parser class. + +

+For a small calculator example, one could use a setup like the +following on the JFlex side: + +

+

+%%
+
+%byaccj
+
+%{
+  /* store a reference to the parser object */
+  private parser yyparser;
+
+  /* constructor taking an additional parser object */
+  public Yylex(java.io.Reader r, parser yyparser) {
+    this(r);
+    this.yyparser = yyparser;
+  }
+%}
+
+NUM = [0-9]+ ("." [0-9]+)?
+NL  = \n | \r | \r\n
+
+%%
+
+/* operators */
+"+" | 
+..
+"(" | 
+")"    { return (int) yycharat(0); }
+
+/* newline */
+{NL}   { return parser.NL; }
+
+/* float */
+{NUM}  { yyparser.yylval = new parserval(Double.parseDouble(yytext()));
+         return parser.NUM; }
+
+ +

+The lexer expects a reference to the parser in its constructor. +Since Yacc allows direct use of terminal characters like '+' +in its specifications, we just return the character code for +single char matches (e.g. the operators in the example). Symbolic +token names are stored as public static int constants in +the generated parser class. They are used as in the NL token +above. Finally, for some tokens, a semantic value may have to be +communicated to the parser. The NUM rule demonstrates that +bit. + +

+A matching BYacc/J parser specification could look like this: +

+%{
+  import java.io.*;
+%}
+      
+%token NL          /* newline  */
+%token <dval> NUM  /* a number */
+
+%type <dval> exp
+
+%left '-' '+'
+..
+%right '^'         /* exponentiation */
+      
+%%
+
+..
+      
+exp:     NUM          { $$ = $1; }
+       | exp '+' exp  { $$ = $1 + $3; }
+       ..
+       | exp '^' exp  { $$ = Math.pow($1, $3); }
+       | '(' exp ')'  { $$ = $2; }
+       ;
+
+%%
+  /* a reference to the lexer object */
+  private Yylex lexer;
+
+  /* interface to the lexer */
+  private int yylex () {
+    int yyl_return = -1;
+    try {
+      yyl_return = lexer.yylex();
+    }
+    catch (IOException e) {
+      System.err.println("IO error :"+e);
+    }
+    return yyl_return;
+  }
+
+  /* error reporting */
+  public void yyerror (String error) {
+    System.err.println ("Error: " + error);
+  }
+
+  /* lexer is created in the constructor */
+  public parser(Reader r) {
+    lexer = new Yylex(r, this);
+  }
+
+  /* that's how you use the parser */
+  public static void main(String args[]) throws IOException {
+    parser yyparser = new parser(new FileReader(args[0]));
+    yyparser.yyparse();    
+  }
+
+ +

+Here, the customized part is mostly in the user code section: +We create the lexer in the constructor of the parser and store +a reference to it for later use in the parser's int yylex() +method. This yylex in the parser only calls int yylex() +of the generated lexer and passes the result on. If something goes +wrong, it returns -1 to indicate an error. + +

+Runnable versions of the specifications above +are located in the examples/byaccj directory of the JFlex +distribution. + +

+ +


+Bugs and Deficiencies +

+ +

+ +

+Deficiencies +

+The trailing context algorithm described in [1] and used in +JFlex is incorrect. It does not work, when a postfix of the regular +expression matches a prefix of the trailing context and the length +of the text matched by the expression does not have a fixed size. +JFlex will report these cases as errors at generation time. + +

+ +

+Bugs +

+ +

+As of April 12, 2004 the following bugs are known in JFlex: + +

+ +

+If you find new ones, please use the bugs section of the +JFlex website +to report them. + +

+ +


+Copying and License +

+JFlex is free software, published under the terms of the +GNU General Public License. + +

+There is absolutely NO WARRANTY for JFlex, its code and its documentation. + +

+The code generated by JFlex inherits the copyright of the specification it +was produced from. If it was your specification, you may use the generated +code without restriction. + +

+See the file COPYRIGHT +for more information. + +

+ +


+Bibliography +

+ +

+

1 +
+ A. Aho, R. Sethi, J. Ullman, Compilers: Principles, Techniques, and Tools, 1986 + +

+

2 +
+ A. W. Appel, Modern Compiler Implementation in Java: basic techniques, 1997 + +

+

3 +
+ E. Berk, JLex: A lexical analyser generator for Java, +
http://www.cs.princeton.edu/~appel/modern/java/JLex/ +

+

4 +
+ K. Brouwer, W. Gellerich,E. Ploedereder, + Myths and Facts about the Efficient Implementation of Finite Automata and Lexical Analysis, + in: Proceedings of the 7th International Conference on Compiler Construction (CC '98), 1998 + +

+

5 +
+ M. Davis, Unicode Regular Expression Guidelines, Unicode Technical Report #18, 2000 +
http://www.unicode.org/unicode/reports/tr18/tr18-5.1.html +

+

6 +
+ P. Dencker, K. Dürre, J. Henft, Optimization of Parser Tables for portable Compilers, + in: ACM Transactions on Programming Languages and Systems 6(4), 1984 + +

+

7 +
+ J. Gosling, B. Joy, G. Steele, The Java Language Specifcation, 1996, +
http://www.javasoft.com/docs/books/jls/ +

+

8 +
+ S. E. Hudson, CUP LALR Parser Generator for Java, +
http://www.cs.princeton.edu/~appel/modern/java/CUP/ +

+

9 +
+ B. Jamison, BYacc/J, +
http://troi.lincom-asg.com/~rjamison/byacc/ +

+

10 +
+ T. Lindholm, F. Yellin, The Java Virtual Machine Specification, 1996, +
http://www.javasoft.com/docs/books/vmspec/ +

+

11 +
+ V. Paxon, flex - The fast lexical analyzer generator, 1995 + +

+

12 +
+ R. E. Tarjan, A. Yao, Storing a Sparse Table, in: Communications of the ACM 22(11), 1979 + +

+

13 +
+ R. Wilhelm, D. Maurer, Übersetzerbau, Berlin 19972 + +

+

+ +

+


Footnotes

+
+
... Java[*] +
Java is a trademark of +Sun Microsystems, Inc., and refers to Sun's Java programming language. +JFlex is not sponsored by or affiliated with Sun Microsystems, Inc. + +


+
+Mon Apr 12 20:58:12 EST 2004, Gerwin Klein +
+ + diff --git a/tools/lexer/jflex-1.4/doc/manual.pdf b/tools/lexer/jflex-1.4/doc/manual.pdf new file mode 100644 index 000000000000..96734f832122 Binary files /dev/null and b/tools/lexer/jflex-1.4/doc/manual.pdf differ diff --git a/tools/lexer/jflex-1.4/doc/manual.ps.gz b/tools/lexer/jflex-1.4/doc/manual.ps.gz new file mode 100644 index 000000000000..50c8ab54802d Binary files /dev/null and b/tools/lexer/jflex-1.4/doc/manual.ps.gz differ diff --git a/tools/lexer/jflex-1.4/examples/binary/Makefile b/tools/lexer/jflex-1.4/examples/binary/Makefile new file mode 100644 index 000000000000..52607f7f210e --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/binary/Makefile @@ -0,0 +1,22 @@ + +JAVA = java +JAVAC = javac +JFLEX = jflex + +# ------------------------------------------------- + +all: run + +run: compile + $(JAVA) BinaryLexer * + +compile: BinaryLexer.class StraightStreamReader.class + +clean: + rm -f *~ *.class BinaryLexer.java + +%.class: %.java + $(JAVAC) $^ + +BinaryLexer.java: binary.flex + $(JFLEX) $^ diff --git a/tools/lexer/jflex-1.4/examples/binary/README b/tools/lexer/jflex-1.4/examples/binary/README new file mode 100644 index 000000000000..8fceab48c4b8 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/binary/README @@ -0,0 +1,18 @@ +This directory contains a small example of a scanner for binary files. + +The example tries to detect if an input file is a java class file by +checking if the first 4 bytes contain the magic number 0xCAFEBABE. +It uses a custom Reader class that copies bytes to characters one to +one. The characters the scanner gets to read are the bytes from the +input stream without any conversion. Many thanks to Stephen Ostermiller +for providing the custom Reader class, the original version of that +class is available from http://www.smo.f2s.com/utils/ + +See the JFlex manual for details on how to scan binaries and how +this is different from scanning text files. + +Files: +binary.flex the scanner spec +StraightStreamReader.java the custom reader class (by Stephen Ostermiller) +Makefile rules for make to compile and run the example +README this file diff --git a/tools/lexer/jflex-1.4/examples/binary/StraightStreamReader.java b/tools/lexer/jflex-1.4/examples/binary/StraightStreamReader.java new file mode 100644 index 000000000000..7f418b5823cf --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/binary/StraightStreamReader.java @@ -0,0 +1,287 @@ +/* + * An InputStreamReader that does no character encoding translations. + * Copyright (C) 2001 Stephen Ostermiller + * + * Changes: (2001 by Gerwin Klein ) + * - commented out package declaration for the example + * - original version at http://www.smo.f2s.com/utils/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * See COPYING.TXT for details. + */ + +// package com.Ostermiller.util; + +import java.io.*; + +/** + * A StraightStreamReader is a bridge from byte streams to character streams: It reads bytes + * and translates them into characters without using a character encoding. The characters + * that a StraightStreamReader returns may not be valid unicode characters but they are + * guaranteed to be in the 0x00 to 0xFF range. + *

+ * Most of the time you want to do character encoding translation when translating bytes to + * characters. If you are planning on displaying the text, you should always do this and should + * use an InputStreamReader for the purpose. Sometimes it is useful to treat characters as bytes + * with some extra bits. In these cases you would want to use a StraightStreamReader. + *

+ * For top efficiency, consider wrapping an StraightStreamReader within a BufferedReader. For example:
+ * BufferedReader in = new BufferedReader(new StraightStreamReader(System.in)); + */ +public class StraightStreamReader extends Reader{ + + /** + * The input stream from which all methods in this class read. + */ + private InputStream in; + + /** + * A byte array to be used for calls to the InputStream. This + * is cached as a class variable to avoid object creation and + * deletion each time a read is called. This buffer may be + * null and may not be large enough. Make sure to check it + * before using it. + */ + private byte[] buffer; + + /** + * Create a StraightStreamReader from an InputStream + * + * @param in InputStream to wrap a Reader around. + */ + public StraightStreamReader(InputStream in) { + this.in = in; + } + + /** + * Close the stream. + * + * @throws IOException If an I/O error occurs + */ + public void close() throws IOException { + in.close(); + } + + /** + * Mark the present position in the stream. Subsequent calls to reset() + * will attempt to reposition the stream to this point. Not all + * character-input streams support the mark() operation. + * + * @param readAheadLimit Limit on the number of characters that may be read + * while still preserving the mark. After reading this many characters, + * attempting to reset the stream may fail. + * @throws IOException If the stream does not support mark(), or if some other I/O error occurs + */ + public void mark(int readAheadLimit) throws IOException { + in.mark(readAheadLimit); + } + + /** + * Tell whether this stream supports the mark() operation. + * + * @return true if and only if this stream supports the mark operation. + */ + public boolean markSupported(){ + return in.markSupported(); + } + + /** + * Read a single character. This method will block until a character is available, an + * I/O error occurs, or the end of the stream is reached. + * + * @return The character read, as an integer in the range 0 to 256 (0x00-0xff), or -1 if + * the end of the stream has been reached + * @throws IOException If an I/O error occurs + */ + public int read() throws IOException { + return in.read(); + } + + /** + * Read characters into an array. This method will block until some input is available, + * an I/O error occurs, or the end of the stream is reached. + * + * @param cbuf Destination buffer + * @return The number of bytes read, or -1 if the end of the stream has been reached + * @throws IOException If an I/O error occurs + */ + public int read(char[] cbuf) throws IOException { + return read(cbuf, 0, cbuf.length); + } + + /** + * Read characters into an array. This method will block until some input is available, + * an I/O error occurs, or the end of the stream is reached. + * + * @param cbuf Destination buffer + * @param off Offset at which to start storing characters + * @param len Maximum number of characters to read + * @return The number of bytes read, or -1 if the end of the stream has been reached + * @throws IOException If an I/O error occurs + */ + public int read(char[] cbuf, int off, int len) throws IOException { + // ensure the capacity of the buffer that we will be using + // to read from the input stream + if (buffer == null || buffer.length < len){ + buffer = new byte[len]; + } + // read from the input stream and copy it to the character array + int length = in.read(buffer, 0, len); + for (int i=0; i 0); + } + + /** + * Reset the stream. If the stream has been marked, then attempt to reposition it at the mark. + * If the stream has not been marked, then attempt to reset it in some way appropriate to the + * particular stream, for example by repositioning it to its starting point. Not all + * character-input streams support the reset() operation, and some support reset() + * without supporting mark(). + * + * @throws IOException If the stream has not been marked, or if the mark has been invalidated, + * or if the stream does not support reset(), or if some other I/O error occurs + */ + public void reset() throws IOException { + in.reset(); + } + + /** + * Skip characters. This method will block until some characters are available, + * an I/O error occurs, or the end of the stream is reached. + * + * @param n The number of characters to skip + * @return The number of characters actually skipped + * @throws IllegalArgumentException If n is negative + * @throws IOException If an I/O error occurs + */ + public long skip(long n) throws IOException { + return in.skip(n); + } + + /** + * Regression test for this class. If this class is working, this should + * run and print no errors. + *

+ * This method creates a tempory file in the working directory called "test.txt". + * This file should not exist before hand, and the program should have create, + * read, write, and delete access to this file. + * + * @param args command line arguments (ignored) + */ + private static void main(String[] args){ + try { + File f = new File("test.txt"); + if (f.exists()){ + throw new IOException(f + " already exists. I don't want to overwrite it."); + } + StraightStreamReader in; + char[] cbuf = new char[0x1000]; + int read; + int totRead; + + // write a file with all possible values of bytes + FileOutputStream out = new FileOutputStream(f); + for (int i=0x00; i<0x100; i++){ + out.write(i); + } + out.close(); + + // read it back using the read single character method + in = new StraightStreamReader(new FileInputStream(f)); + for (int i=0x00; i<0x100; i++){ + read = in.read(); + if (read != i){ + System.err.println("Error: " + i + " read as " + read); + } + } + in.close(); + + // read as much of it back as possible with one simple buffer read. + in = new StraightStreamReader(new FileInputStream(f)); + totRead = in.read(cbuf); + if (totRead != 0x100){ + System.err.println("Simple buffered read did not read the full amount: 0x" + Integer.toHexString(totRead)); + } + for (int i=0x00; i 0){ + totRead += read; + } + if (totRead != 0x100){ + System.err.println("Not enough read. Bytes read: " + Integer.toHexString(totRead)); + } + for (int i=0x00; i 0){ + totRead += read; + } + if (totRead != 0x100){ + System.err.println("Not enough read. Bytes read: " + Integer.toHexString(totRead)); + } + for (int i=0x00; i 0){ + totRead += read; + } + if (totRead != 0x100){ + System.err.println("Not enough read. Bytes read: " + Integer.toHexString(totRead)); + } + for (int i=0x00; i * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +import java.io.*; + +%% + +%class BinaryLexer +%8bit + +%int + +%{ + public static void main(String [] argv) { + for (int i = 0; i < argv.length; i++) { + try { + System.out.print("["+argv[i]+"] is "); + BinaryLexer l = new BinaryLexer(new StraightStreamReader(new FileInputStream(argv[i]))); + l.yylex(); + } + catch (Exception e) { + e.printStackTrace(System.out); + System.exit(1); + } + } + } +%} + +magic = \xCA \xFE \xBA \xBE + +%% + +{magic} [^]+ { System.out.println("a class file"); } + +[^]+ { System.out.println("not a class file"); } diff --git a/tools/lexer/jflex-1.4/examples/byaccj/Makefile b/tools/lexer/jflex-1.4/examples/byaccj/Makefile new file mode 100644 index 000000000000..28a361dda157 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/byaccj/Makefile @@ -0,0 +1,27 @@ +# only works with the Java extension of yacc: +# byacc/j from http://troi.lincom-asg.com/~rjamison/byacc/ + +JFLEX = jflex +BYACCJ = yacc -J +JAVAC = javac + +# targets: + +all: Parser.class + +run: Parser.class + java Parser + +build: clean Parser.class + +clean: + rm -f *~ *.class *.java + +Parser.class: Yylex.java Parser.java + $(JAVAC) Parser.java + +Yylex.java: calc.flex + $(JFLEX) calc.flex + +Parser.java: calc.y + $(BYACCJ) calc.y diff --git a/tools/lexer/jflex-1.4/examples/byaccj/README b/tools/lexer/jflex-1.4/examples/byaccj/README new file mode 100644 index 000000000000..ab6831e8026c --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/byaccj/README @@ -0,0 +1,22 @@ +This directory contains an interoperability example for BYacc/J and JFlex +(a small calculator) + +You need the parser generator byacc/j from +http://troi.lincom-asg.com/~rjamison/byacc/ +for this example to work (version byacc/j 1.1 has been tested). + +Use the Makefile to generate the lexer and parser. +The example can then be started with + +java Parser + + +files: + +calc.flex + JFlex specification for the lexical part of the arithmetic expressions + +calc.y + BYacc/J specification and main program for the calculator + + diff --git a/tools/lexer/jflex-1.4/examples/byaccj/calc.flex b/tools/lexer/jflex-1.4/examples/byaccj/calc.flex new file mode 100644 index 000000000000..8ad62bc4332f --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/byaccj/calc.flex @@ -0,0 +1,62 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2000 Gerwin Klein * + * All rights reserved. * + * * + * Thanks to Larry Bell and Bob Jamison for suggestions and comments. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +%% + +%byaccj + +%{ + private Parser yyparser; + + public Yylex(java.io.Reader r, Parser yyparser) { + this(r); + this.yyparser = yyparser; + } +%} + +NUM = [0-9]+ ("." [0-9]+)? +NL = \n | \r | \r\n + +%% + +/* operators */ +"+" | +"-" | +"*" | +"/" | +"^" | +"(" | +")" { return (int) yycharat(0); } + +/* newline */ +{NL} { return Parser.NL; } + +/* float */ +{NUM} { yyparser.yylval = new ParserVal(Double.parseDouble(yytext())); + return Parser.NUM; } + +/* whitespace */ +[ \t]+ { } + +\b { System.err.println("Sorry, backspace doesn't work"); } + +/* error fallback */ +[^] { System.err.println("Error: unexpected character '"+yytext()+"'"); return -1; } diff --git a/tools/lexer/jflex-1.4/examples/byaccj/calc.y b/tools/lexer/jflex-1.4/examples/byaccj/calc.y new file mode 100644 index 000000000000..7ab42c271729 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/byaccj/calc.y @@ -0,0 +1,112 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * All rights reserved. * + * * + * This is a modified version of the example from * + * http://www.lincom-asg.com/~rjamison/byacc/ * + * * + * Thanks to Larry Bell and Bob Jamison for suggestions and comments. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +%{ + import java.io.*; +%} + +%token NL /* newline */ +%token NUM /* a number */ + +%type exp + +%left '-' '+' +%left '*' '/' +%left NEG /* negation--unary minus */ +%right '^' /* exponentiation */ + +%% + +input: /* empty string */ + | input line + ; + +line: NL { if (interactive) System.out.print("Expression: "); } + | exp NL { System.out.println(" = " + $1); + if (interactive) System.out.print("Expression: "); } + ; + +exp: NUM { $$ = $1; } + | exp '+' exp { $$ = $1 + $3; } + | exp '-' exp { $$ = $1 - $3; } + | exp '*' exp { $$ = $1 * $3; } + | exp '/' exp { $$ = $1 / $3; } + | '-' exp %prec NEG { $$ = -$2; } + | exp '^' exp { $$ = Math.pow($1, $3); } + | '(' exp ')' { $$ = $2; } + ; + +%% + + private Yylex lexer; + + + private int yylex () { + int yyl_return = -1; + try { + yylval = new ParserVal(0); + yyl_return = lexer.yylex(); + } + catch (IOException e) { + System.err.println("IO error :"+e); + } + return yyl_return; + } + + + public void yyerror (String error) { + System.err.println ("Error: " + error); + } + + + public Parser(Reader r) { + lexer = new Yylex(r, this); + } + + + static boolean interactive; + + public static void main(String args[]) throws IOException { + System.out.println("BYACC/Java with JFlex Calculator Demo"); + + Parser yyparser; + if ( args.length > 0 ) { + // parse a file + yyparser = new Parser(new FileReader(args[0])); + } + else { + // interactive mode + System.out.println("[Quit with CTRL-D]"); + System.out.print("Expression: "); + interactive = true; + yyparser = new Parser(new InputStreamReader(System.in)); + } + + yyparser.yyparse(); + + if (interactive) { + System.out.println(); + System.out.println("Have a nice day"); + } + } diff --git a/tools/lexer/jflex-1.4/examples/cup/Main.java b/tools/lexer/jflex-1.4/examples/cup/Main.java new file mode 100644 index 000000000000..fba453289fe3 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/Main.java @@ -0,0 +1,39 @@ +/* + This example comes from a short article series in the Linux + Gazette by Richard A. Sevenich and Christopher Lopes, titled + "Compiler Construction Tools". The article series starts at + + http://www.linuxgazette.com/issue39/sevenich.html + + Small changes and updates to newest JFlex+Cup versions + by Gerwin Klein +*/ + +/* + Commented By: Christopher Lopes + File Name: Main.java + To Create: + After the scanner, lcalc.flex, and the parser, ycalc.cup, have been created. + > javac Main.java + + To Run: + > java Main test.txt + where test.txt is an test input file for the calculator. +*/ + +import java.io.FileReader; + +public class Main { + static public void main(String argv[]) { + /* Start the parser */ + try { + parser p = new parser(new Lexer(new FileReader(argv[0]))); + Object result = p.parse().value; + } catch (Exception e) { + /* do cleanup here -- possibly rethrow e */ + e.printStackTrace(); + } + } +} + + diff --git a/tools/lexer/jflex-1.4/examples/cup/Makefile b/tools/lexer/jflex-1.4/examples/cup/Makefile new file mode 100644 index 000000000000..fff6fbced6b4 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/Makefile @@ -0,0 +1,26 @@ +JAVA=java +JAVAC=javac +JFLEX=jflex +CUP=$(JAVA) java_cup.Main < + +all: test + +test: output.txt + @(diff output.txt output.good && echo "Test OK!") || echo "Test failed!" + +output.txt: Main.class test.txt + $(JAVA) Main test.txt > output.txt + +Main.class: Main.java Lexer.java parser.java + +%.class: %.java + $(JAVAC) $^ + +Lexer.java: lcalc.flex + $(JFLEX) lcalc.flex + +parser.java: ycalc.cup + $(CUP) ycalc.cup + +clean: + rm -f parser.java Lexer.java sym.java output.txt *.class *~ diff --git a/tools/lexer/jflex-1.4/examples/cup/README b/tools/lexer/jflex-1.4/examples/cup/README new file mode 100644 index 000000000000..6b0d333bd188 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/README @@ -0,0 +1,30 @@ +A small JFlex+Cup example + +It comes from a short article series in the Linux Gazette by Richard +A. Sevenich and Christopher Lopes, titled "Compiler Construction +Tools". The article series starts at + +http://www.linuxgazette.com/issue39/sevenich.html + +Small changes and updates to newest JFlex+Cup versions by Gerwin Klein + + +To compile: +>jflex lcalc.flex +>java java_cup.Main < ycalc.cup +>javac Main.java + +To run: +>java Main test.txt + + +Files: + +Main.java demo of a main program +Makefile makefile to compile and test the example +README this file +lcalc.flex the lexer spec +output.good how the output should look like for the test +ycalc.cup the parser spec +test.txt sample input for testing + diff --git a/tools/lexer/jflex-1.4/examples/cup/lcalc.flex b/tools/lexer/jflex-1.4/examples/cup/lcalc.flex new file mode 100644 index 000000000000..181bf0198f01 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/lcalc.flex @@ -0,0 +1,142 @@ +/* + This example comes from a short article series in the Linux + Gazette by Richard A. Sevenich and Christopher Lopes, titled + "Compiler Construction Tools". The article series starts at + + http://www.linuxgazette.com/issue39/sevenich.html + + Small changes and updates to newest JFlex+Cup versions + by Gerwin Klein +*/ + +/* + Commented By: Christopher Lopes + File Name: lcalc.flex + To Create: > jflex lcalc.flex + + and then after the parser is created + > javac Lexer.java +*/ + +/* --------------------------Usercode Section------------------------ */ + +import java_cup.runtime.*; + +%% + +/* -----------------Options and Declarations Section----------------- */ + +/* + The name of the class JFlex will create will be Lexer. + Will write the code to the file Lexer.java. +*/ +%class Lexer + +/* + The current line number can be accessed with the variable yyline + and the current column number with the variable yycolumn. +*/ +%line +%column + +/* + Will switch to a CUP compatibility mode to interface with a CUP + generated parser. +*/ +%cup + +/* + Declarations + + Code between %{ and %}, both of which must be at the beginning of a + line, will be copied letter to letter into the lexer class source. + Here you declare member variables and functions that are used inside + scanner actions. +*/ +%{ + /* To create a new java_cup.runtime.Symbol with information about + the current token, the token will have no value in this + case. */ + private Symbol symbol(int type) { + return new Symbol(type, yyline, yycolumn); + } + + /* Also creates a new java_cup.runtime.Symbol with information + about the current token, but this object has a value. */ + private Symbol symbol(int type, Object value) { + return new Symbol(type, yyline, yycolumn, value); + } +%} + + +/* + Macro Declarations + + These declarations are regular expressions that will be used latter + in the Lexical Rules Section. +*/ + +/* A line terminator is a \r (carriage return), \n (line feed), or + \r\n. */ +LineTerminator = \r|\n|\r\n + +/* White space is a line terminator, space, tab, or line feed. */ +WhiteSpace = {LineTerminator} | [ \t\f] + +/* A literal integer is is a number beginning with a number between + one and nine followed by zero or more numbers between zero and nine + or just a zero. */ +dec_int_lit = 0 | [1-9][0-9]* + +/* A identifier integer is a word beginning a letter between A and + Z, a and z, or an underscore followed by zero or more letters + between A and Z, a and z, zero and nine, or an underscore. */ +dec_int_id = [A-Za-z_][A-Za-z_0-9]* + +%% +/* ------------------------Lexical Rules Section---------------------- */ + +/* + This section contains regular expressions and actions, i.e. Java + code, that will be executed when the scanner matches the associated + regular expression. */ + + /* YYINITIAL is the state at which the lexer begins scanning. So + these regular expressions will only be matched if the scanner is in + the start state YYINITIAL. */ + + { + + /* Return the token SEMI declared in the class sym that was found. */ + ";" { return symbol(sym.SEMI); } + + /* Print the token found that was declared in the class sym and then + return it. */ + "+" { System.out.print(" + "); return symbol(sym.PLUS); } + "-" { System.out.print(" - "); return symbol(sym.MINUS); } + "*" { System.out.print(" * "); return symbol(sym.TIMES); } + "/" { System.out.print(" / "); return symbol(sym.DIVIDE); } + "(" { System.out.print(" ( "); return symbol(sym.LPAREN); } + ")" { System.out.print(" ) "); return symbol(sym.RPAREN); } + + /* If an integer is found print it out, return the token NUMBER + that represents an integer and the value of the integer that is + held in the string yytext which will get turned into an integer + before returning */ + {dec_int_lit} { System.out.print(yytext()); + return symbol(sym.NUMBER, new Integer(yytext())); } + + /* If an identifier is found print it out, return the token ID + that represents an identifier and the default value one that is + given to all identifiers. */ + {dec_int_id} { System.out.print(yytext()); + return symbol(sym.ID, new Integer(1));} + + /* Don't do anything if whitespace is found */ + {WhiteSpace} { /* just skip what was found, do nothing */ } +} + + +/* No token was found for the input so through an error. Print out an + Illegal character message with the illegal character that was found. */ +[^] { throw new Error("Illegal character <"+yytext()+">"); } diff --git a/tools/lexer/jflex-1.4/examples/cup/output.good b/tools/lexer/jflex-1.4/examples/cup/output.good new file mode 100644 index 000000000000..cbceb636f601 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/output.good @@ -0,0 +1,4 @@ +2 + 4 = 6 +5 * ( 6 - 3 ) + 1 = 16 +6 / 3 * 5 + 20 = 30 +4 * 76 / 31 = 9 diff --git a/tools/lexer/jflex-1.4/examples/cup/test.txt b/tools/lexer/jflex-1.4/examples/cup/test.txt new file mode 100644 index 000000000000..3f8344bccdb2 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/test.txt @@ -0,0 +1,4 @@ +2+4; +5*(6-3)+1; +6/3*5+20; +4*76/31; diff --git a/tools/lexer/jflex-1.4/examples/cup/ycalc.cup b/tools/lexer/jflex-1.4/examples/cup/ycalc.cup new file mode 100644 index 000000000000..a67a20d3b09a --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/cup/ycalc.cup @@ -0,0 +1,234 @@ +/* + This example comes from a short article series in the Linux + Gazette by Richard A. Sevenich and Christopher Lopes, titled + "Compiler Construction Tools". The article series starts at + + http://www.linuxgazette.com/issue39/sevenich.html + + Small changes and updates to newest JFlex+Cup versions + by Gerwin Klein +*/ + +/* + Commented By: Christopher Lopes + File Name: ycalc.cup + To Create: > java java_cup.Main < ycalc.cup +*/ + + +/* ----------------------Preliminary Declarations Section--------------------*/ + +/* Import the class java_cup.runtime.* */ +import java_cup.runtime.*; + +/* Parser code to change the way the parser reports errors (include + line and column number of the error). */ +parser code {: + + /* Change the method report_error so it will display the line and + column of where the error occurred in the input as well as the + reason for the error which is passed into the method in the + String 'message'. */ + public void report_error(String message, Object info) { + + /* Create a StringBuffer called 'm' with the string 'Error' in it. */ + StringBuffer m = new StringBuffer("Error"); + + /* Check if the information passed to the method is the same + type as the type java_cup.runtime.Symbol. */ + if (info instanceof java_cup.runtime.Symbol) { + /* Declare a java_cup.runtime.Symbol object 's' with the + information in the object info that is being typecasted + as a java_cup.runtime.Symbol object. */ + java_cup.runtime.Symbol s = ((java_cup.runtime.Symbol) info); + + /* Check if the line number in the input is greater or + equal to zero. */ + if (s.left >= 0) { + /* Add to the end of the StringBuffer error message + the line number of the error in the input. */ + m.append(" in line "+(s.left+1)); + /* Check if the column number in the input is greater + or equal to zero. */ + if (s.right >= 0) + /* Add to the end of the StringBuffer error message + the column number of the error in the input. */ + m.append(", column "+(s.right+1)); + } + } + + /* Add to the end of the StringBuffer error message created in + this method the message that was passed into this method. */ + m.append(" : "+message); + + /* Print the contents of the StringBuffer 'm', which contains + an error message, out on a line. */ + System.err.println(m); + } + + /* Change the method report_fatal_error so when it reports a fatal + error it will display the line and column number of where the + fatal error occurred in the input as well as the reason for the + fatal error which is passed into the method in the object + 'message' and then exit.*/ + public void report_fatal_error(String message, Object info) { + report_error(message, info); + System.exit(1); + } +:}; + + + +/* ------------Declaration of Terminals and Non Terminals Section----------- */ + +/* Terminals (tokens returned by the scanner). + + Terminals that have no value are listed first and then terminals + that do have an value, in this case an integer value, are listed on + the next line down. */ +terminal SEMI, PLUS, MINUS, TIMES, DIVIDE, LPAREN, RPAREN; +terminal Integer NUMBER, ID; + +/* Non terminals used in the grammar section. + + Non terminals that have an object value are listed first and then + non terminals that have an integer value are listed. An object + value means that it can be any type, it isn't set to a specific + type. So it could be an Integer or a String or whatever. */ +non terminal Object expr_list, expr_part; +non terminal Integer expr, factor, term; + + +/* -------------Precedence and Associatively of Terminals Section----------- */ + +/* + Precedence of non terminals could be defined here. If you do define + precedence here you won't need to worry about precedence in the + Grammar Section, i.e. that TIMES should have a higher precedence + than PLUS. + + The precedence defined here would look something like this where the + lower line always will have higher precedence than the line before it. + + precedence left PLUS, MINUS; + precedence left TIMES, DIVIDE; +*/ + + +/* ----------------------------Grammar Section-------------------- */ + +/* The grammar for our parser. + + expr_list ::= expr_list expr_part + | expr_part + expr_part ::= expr SEMI + expr ::= factor PLUS expr + | factor MINUS expr + | factor + factor ::= factor TIMES term + | factor DIVIDE term + | term + term ::= LPAREN expr RPAREN + | NUMBER + | ID +*/ + +/* 'expr_list' is the start of our grammar. It can lead to another + 'expr_list' followed by an 'expr_part' or it can just lead to an + 'expr_part'. The lhs of the non terminals 'expr_list' and + 'expr_part' that are in the rhs side of the production below need + to be found. Then the rhs sides of those non terminals need to be + followed in a similar manner, i.e. if there are any non terminals + in the rhs of those productions then the productions with those non + terminals need to be found and those rhs's followed. This process + keeps continuing until only terminals are found in the rhs of a + production. Then we can work our way back up the grammar bringing + any values that might have been assigned from a terminal. */ + + expr_list ::= expr_list expr_part + | + expr_part; + +/* 'expr_part' is an 'expr' followed by the terminal 'SEMI'. The ':e' + after the non terminal 'expr' is a label an is used to access the + value of 'expr' which will be an integer. The action for the + production lies between {: and :}. This action will print out the + line " = + e" where e is the value of 'expr'. Before the action + takes places we need to go deeper into the grammar since 'expr' is + a non terminal. Whenever a non terminal is encountered on the rhs + of a production we need to find the rhs of that non terminal until + there are no more non terminals in the rhs. So when we finish + going through the grammar and don't encounter any more non + terminals in the rhs productions will return until we get back to + 'expr' and at that point 'expr' will contain an integer value. */ + + expr_part ::= expr:e + {: System.out.println(" = " + e); :} + SEMI + ; + +/* 'expr' can lead to 'factor PLUS expr', 'factor MINUS expr', or + 'factor'. The 'TIMES' and 'DIVIDE' productions are not at this + level. They are at a lower level in the grammar which in affect + makes them have higher precedence. Actions for the rhs of the non + terminal 'expr' return a value to 'expr'. This value that is + created is an integer and gets stored in 'RESULT' in the action. + RESULT is the label that is assigned automatically to the rhs, in + this case 'expr'. If the rhs is just 'factor' then 'f' refers to + the non terminal 'factor'. The value of 'f' is retrieved with the + function 'intValue()' and will be stored in 'RESULT'. In the other + two cases 'f' and 'e' refers to the non terminals 'factor' and + 'expr' respectively with a terminal between them, either 'PLUS' or + 'MINUS'. The value of each is retrieved with the same function + 'intValue'. The values will be added or subtracted and then the + new integer will be stored in 'RESULT'.*/ + + expr ::= factor:f PLUS expr:e + {: RESULT = new Integer(f.intValue() + e.intValue()); :} + | + factor:f MINUS expr:e + {: RESULT = new Integer(f.intValue() - e.intValue()); :} + | + factor:f + {: RESULT = new Integer(f.intValue()); :} + ; + +/* 'factor' can lead to 'factor TIMES term', 'factor DIVIDE term', or + 'term'. Since the productions for TIMES and DIVIDE are lower in + the grammar than 'PLUS' and 'MINUS' they will have higher + precedence. The same sort of actions take place in the rhs of + 'factor' as in 'expr'. The only difference is the operations that + takes place on the values retrieved with 'intValue()', 'TIMES' and + 'DIVIDE' here instead of 'PLUS' and 'MINUS'. */ + + factor ::= factor:f TIMES term:t + {: RESULT = new Integer(f.intValue() * t.intValue()); :} + | + factor:f DIVIDE term:t + {: RESULT = new Integer(f.intValue() / t.intValue()); :} + | + term:t + {: RESULT = new Integer(t.intValue()); :} + ; + +/* 'term' can lead to 'LPAREN expr RPAREN', 'NUMBER', or 'ID'. The + first production has the non terminal 'expr' in it so the + production with its lhs side needs to be found and followed. The + next rhs has no non terminals. So the grammar ends here and can go + back up. When it goes back up it will bring the value that was + retrieved when the scanner encounter the token 'NUMBER'. 'RESULT' + is assigned 'n', which refers to 'NUMBER', as the action for this + production. The same action occurs for 'ID', except the 'i' is + used to refer to 'ID'. 'ID' is also the only thing on the rhs of + the production. And since 'ID' is a terminal the grammar will end + here and go back up. */ + + term ::= LPAREN expr:e RPAREN + {: RESULT = e; :} + | + NUMBER:n + {: RESULT = n; :} + | + ID:i + {: RESULT = i; :} + ; diff --git a/tools/lexer/jflex-1.4/examples/interpreter/AST.java b/tools/lexer/jflex-1.4/examples/interpreter/AST.java new file mode 100644 index 000000000000..194a42c4a33c --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/AST.java @@ -0,0 +1,30 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/** + * General interface for nodes in the abstract syntax tree. Contains + * only the method toString which is already inherited from Object, + * so the interface doesn't add any functionality. It only provides + * a common super type for all elements in the AST. + */ +interface AST { + public String toString(); // already inherited from Object +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Main.java b/tools/lexer/jflex-1.4/examples/interpreter/Main.java new file mode 100644 index 000000000000..4fbaf1a7a6e1 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Main.java @@ -0,0 +1,88 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +import java.io.File; +import java.io.FileReader; +import java.io.InputStreamReader; +import java.io.Reader; + +/** + * Main program of the interpreter for the AS programming language. + * Based on JFlex/CUP. + * + * Steps: + * - scanning (Yylex) + * - context free parsing and AST building (yyparse) + * - build up symbol table (setSymtabs) + * - check context conditions (checkcontext) + * - prepare interpretation (prepInterp) + * - start interpretation (interpret) + */ +public class Main { + + public static void main(String [] args) throws Exception { + Reader reader = null; + + if (args.length == 1) { + File input = new File(args[0]); + if (!input.canRead()) { + System.out.println("Error: could not read ["+input+"]"); + } + reader = new FileReader(input); + } + else { + reader = new InputStreamReader(System.in); + } + + Yylex scanner = new Yylex(reader); // create scanner + SymTab symtab = new SymTab(); // set global symbol table + scanner.setSymtab(symtab); + + parser parser = new parser(scanner); // create parser + Tprogram syntaxbaum = null; + + try { + syntaxbaum = (Tprogram) parser.parse().value; // parse + } + catch (Exception e) { + e.printStackTrace(); + } + + // System.out.println(symtab); + System.out.println(syntaxbaum); + + syntaxbaum.setSymtabs(); // set symbol table + // syntaxbaum.printSymtabs(); // print symbol table + + syntaxbaum.checkcontext(); // CoCo (DefVar, DefFun, Arity) + if(contexterror>0) return; + + syntaxbaum.prepInterp(); // var. indices and function pointers + // im Syntaxbaum setzen + syntaxbaum.interpret(); // interpretation + } + + static int contexterror = 0; // number of errors in context conditions + + public static void error(String s) { + System.out.println((contexterror++)+". "+s); + } +} diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Makefile b/tools/lexer/jflex-1.4/examples/interpreter/Makefile new file mode 100644 index 000000000000..de5afbe94d7b --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Makefile @@ -0,0 +1,42 @@ +# uses JFlex >= 1.3.2, and CUP >= 0.10j +# +# targets: +# +# make all +# generates lexer, and parser, and compiles all *.java files +# +# make run (or just: make) +# starts the program on a test example +# + + + +.SUFFIXES: $(SUFFIXES) .class .java + +.java.class: + javac $*.java + +FILE= Yylex.java parser.java sym.java \ + SymTab.java AST.java \ + Tnumber.java Tident.java Texp.java \ + Tfun.java Texpinfix.java Tuminus.java \ + Tboolexp.java Tifthenelse.java \ + Tdekl.java Tdekllist.java \ + Tparlist.java Texplist.java Tprogram.java \ + Main.java \ + SymtabEntry.java STEfun.java STEvar.java + + +run: all + java Main < example.as + +all: Yylex.java parser.java $(FILE:java=class) + +clean: + rm -f *.class *~ *.bak Yylex.java parser.java sym.java + +Yylex.java: scanner.flex + jflex scanner.flex + +parser.java: parser.cup + java java_cup.Main -interface < parser.cup diff --git a/tools/lexer/jflex-1.4/examples/interpreter/README b/tools/lexer/jflex-1.4/examples/interpreter/README new file mode 100644 index 000000000000..731bd5c1b208 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/README @@ -0,0 +1,31 @@ +This directory contains an interpreter for a small functional +programming language (called "AS"). It uses JFlex and CUP. + +Directory contents: + +- Main.java is the main program. It reads an AS program from + std in and interprets it. + +- Makefile runs jflex, cup, javac and the compiled interpreter + +- Classes beginning with "T" implement the abstract syntax tree. + They also contain context condition checking and the interpreter. + +- Symtab.java, SymtabEntry.java, STEfun.java, STEvar.java implement + the symbol table. + +- scanner.lex and parser.cup contain the scanner and parser. + +- example.as is an example program in AS + + +The language is described in: +Manfred Broy: Einfuehrung in die Informatik, Springer Verlag + +The files are a solution to excercise 3.40 in the book: +Manfred Broy,Bernhard Rumpe: +Uebungen zur Einfuehrung in die Informatik -- +Strukturierte Aufgabensammlung mit Musterloesungen, +Springer Verlag, 2001 + +Both books are only available in German. Sorry. diff --git a/tools/lexer/jflex-1.4/examples/interpreter/STEfun.java b/tools/lexer/jflex-1.4/examples/interpreter/STEfun.java new file mode 100644 index 000000000000..655813b4dcee --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/STEfun.java @@ -0,0 +1,54 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * Symbol table entry for functions. + * + * Contains arity and reference to location of definition + */ +class STEfun extends SymtabEntry { + int arity; + Tdekl dekl; // location of definition + + public STEfun(String f, Tdekl d, int a) { + super(f); + dekl=d; + arity=a; + } + + public int kind() { + return SymtabEntry.FUN; + } + + public String toString() { + return "function "+name+", arity "+arity; + } + + public int arity() { + return arity; + } + + public Tdekl getDekl() { + return dekl; + } +} + + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/STEvar.java b/tools/lexer/jflex-1.4/examples/interpreter/STEvar.java new file mode 100644 index 000000000000..c4d420db2e79 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/STEvar.java @@ -0,0 +1,57 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * Symbol table entry for variables. + * + * Contains index in the parameter list and a flag if it + * is an input variable. + */ +class STEvar extends SymtabEntry { + boolean is_input; + int index; + + public STEvar(String v, boolean ii, int ind) { + super(v); + is_input=ii; + index=ind; + } + + public int kind() { + return SymtabEntry.VAR; + } + + public String toString() { + if (is_input) + return "input var "+name+" ("+index+")"; + else + return "parameter "+name+" ("+index+")"; + } + + public int getIndex() { + return index; + } + + public boolean isInput() { + return is_input; + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/SymTab.java b/tools/lexer/jflex-1.4/examples/interpreter/SymTab.java new file mode 100644 index 000000000000..676a736cfb15 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/SymTab.java @@ -0,0 +1,79 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +import java.util.Enumeration; +import java.util.Hashtable; + +/** + * Symbol table for the interpreter, contains information about + * variables and functions. + * + * For every binding location of a name a symbol will be created. + * The symbol tables are connected hierarchically by pointers to + * the predecessor. Lookup takes predecessors into account. + */ +public class SymTab { + Hashtable h; // contains the liste of words + // key: String, value: SymtabEntry + + SymTab pred; // predecessor symbol table (if exists) + + public SymTab() { + this(null); + } + + public SymTab(SymTab p) { + h = new Hashtable(); + pred = p; + } + + public boolean enter(String s, SymtabEntry e) { + Object value = lookup(s); + h.put(s, e); + return(value==null); + } + + public SymtabEntry lookup(String s) { + Object value = h.get(s); + if (value==null && pred!=null) + value = pred.lookup(s); + return ((SymtabEntry)value); + } + + public String toString() { // for output with print + String res = "symbol table\n=============\n"; + Enumeration e = h.keys(); + String key; + + while(e.hasMoreElements()) { + key = (String)e.nextElement(); + res += key+" \t"+h.get(key)+"\n"; + } + + if (pred!=null) res+="++ predecessor!\n"; + return(res); + } + + public int size() { + return(h.size()); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/SymtabEntry.java b/tools/lexer/jflex-1.4/examples/interpreter/SymtabEntry.java new file mode 100644 index 000000000000..9eb7f1385c0d --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/SymtabEntry.java @@ -0,0 +1,48 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * Symbol table entry for names, there are subclasses for + * variables and functions. + * + * Defines constants UNKNOWN, VAR und FUN as kinds of + * symbol table entries. + */ +class SymtabEntry { + String name; + + public SymtabEntry(String v) { + name=v; + } + + public int kind() { + return UNKNOWN; + } + + public String toString() { + return("unknown "+name); + } + + static final int UNKNOWN = 12; + static final int VAR = 13; + static final int FUN = 14; +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tboolexp.java b/tools/lexer/jflex-1.4/examples/interpreter/Tboolexp.java new file mode 100644 index 000000000000..59ab0e30a885 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tboolexp.java @@ -0,0 +1,64 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for bool expressions + */ +class Tboolexp implements AST { + Texp exp1, exp2; // left and right subexpression + char kind; // '=', '<' and '!' for "<=" + + public Tboolexp(Texp e1, char k, Texp e2) { + exp1=e1; + kind=k; + exp2=e2; + } + + public String toString() { + if (kind!='!') + return(""+exp1+kind+exp2); + else + return(exp1+"<="+exp2); + } + + public void checkcontext(SymTab st) { // context conditions + exp1.checkcontext(st); + exp2.checkcontext(st); + } + + public void prepInterp(SymTab st) { // set pointers and indices + exp1.prepInterp(st); + exp2.prepInterp(st); + } + + public boolean interpret(int[] in, int[] par) { + int e1 = exp1.interpret(in,par); + int e2 = exp2.interpret(in,par); + switch(kind) { + case '=': return(e1==e2); + case '<': return(e1 * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for function declarations. + * + * Also contains a reference to the symbol table of + * the paramaters and their arity. + */ +class Tdekl implements AST { + Tident ident; // identifier + Tparlist parlist; // liste of parameter + Texp exp; // function body + + public Tdekl(Tident i, Tparlist p, Texp e) { + parlist=p; + ident=i; + exp=e; + } + + public String toString() { + return(ident+"("+parlist+") = \n "+exp); + } + + SymTab params; // symbol table of the parameters + int arity; + + public void setSymtab(SymTab st) { + params = new SymTab(st); + parlist.setSymtab(params,false,0); + arity = params.size(); + + boolean isNew = st.enter(ident.toString(), + new STEfun(ident.toString(),this,arity)); + // CoCo (Fun) + if(!isNew) Main.error("funktion "+ident+" defined twice!"); + } + + public void printSymtabs() { + System.out.print("funktion "+ident.toString()+"\n"+params); + } + + public void checkcontext() { + exp.checkcontext(params); // CoCo (DefFun,DefVar,Arity) + } + + public void prepInterp(SymTab st) { // set pointers and indices + exp.prepInterp(params); + } + + public int interpret(int[] in, int[] par) { + return(exp.interpret(in,par)); + } + + public int arity() { return(arity); } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tdekllist.java b/tools/lexer/jflex-1.4/examples/interpreter/Tdekllist.java new file mode 100644 index 000000000000..6f409a6a7829 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tdekllist.java @@ -0,0 +1,69 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for declaration lists of functions + */ +class Tdekllist implements AST { + Tdekllist dekllist; // rest list (optional null) + Tdekl dekl; // declaration + + public Tdekllist(Tdekllist p, Tdekl e) { + dekllist=p; + dekl=e; + } + + public Tdekllist(Tdekl e) { + dekllist=null; + dekl=e; + } + + public String toString() { + if (dekllist!=null) + return(dekllist+",\n"+dekl); + else + return(dekl.toString()); + } + + public void setSymtab(SymTab st) { + if (dekllist!=null) + dekllist.setSymtab(st); + dekl.setSymtab(st); + } + + public void printSymtabs() { + if (dekllist!=null) + dekllist.printSymtabs(); + dekl.printSymtabs(); + } + + public void checkcontext() { + if (dekllist!=null) + dekllist.checkcontext(); + dekl.checkcontext(); // CoCo (DefFun,DefVar,Arity) + } // in function body + + public void prepInterp(SymTab st) { // set pointers and indices + dekl.prepInterp(st); + if (dekllist!=null) dekllist.prepInterp(st); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Texp.java b/tools/lexer/jflex-1.4/examples/interpreter/Texp.java new file mode 100644 index 000000000000..8c4ef9460d9a --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Texp.java @@ -0,0 +1,43 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for an integer expression. + * + * The non terminal exp is the sum of multiple variants and + * therefore modeled as an abstract class. + * + * The interpretation function interpret is called with + * valuations of input variables in and parameters + * par. Before interpret can be called, pointers + * and variable indices must be set with prepInterp. + */ +abstract class Texp implements AST { + // test context conditions (DefFun,DefVar,Arity) + abstract public void checkcontext(SymTab st); + + // set pointers and indices for variables and functions + abstract public void prepInterp(SymTab st); + + // interpretation + abstract public int interpret(int[] in, int[] par); +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Texpinfix.java b/tools/lexer/jflex-1.4/examples/interpreter/Texpinfix.java new file mode 100644 index 000000000000..9db0b0c17c5b --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Texpinfix.java @@ -0,0 +1,64 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for infix expressions + */ +class Texpinfix extends Texp implements AST { + Texp exp1, exp2; // left and right sub expression + char kind; // kind ('+', '-', '*', '/') + + public Texpinfix(Texp e1, char k, Texp e2) { + exp1=e1; + kind=k; + exp2=e2; + } + + public String toString() { + return("("+exp1+kind+exp2+")"); + } + + public void checkcontext(SymTab st) { // context conditions + exp1.checkcontext(st); + exp2.checkcontext(st); + } + + public void prepInterp(SymTab st) { // set pointers und indices + exp1.prepInterp(st); + exp2.prepInterp(st); + } + + public int interpret(int[] in, int[] par) { + int e1 = exp1.interpret(in,par); + int e2 = exp2.interpret(in,par); + + switch (kind) { + case '+': return(e1+e2); + case '-': return(e1-e2); + case '*': return(e1*e2); + case '/': return(e1/e2); + } + + return -1; // error + } +} + + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Texplist.java b/tools/lexer/jflex-1.4/examples/interpreter/Texplist.java new file mode 100644 index 000000000000..84ffe96b8ae3 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Texplist.java @@ -0,0 +1,73 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for a list of expressions. + * + * The interpretation of a list of expressions stores the + * results of the expressions in an array that can be used + * as parameter list for function calls. + */ +class Texplist implements AST { + Texplist explist; // next list element (optional null) + Texp exp; // expression of this list node + + public Texplist(Texplist p, Texp e) { + explist=p; + exp=e; + } + + public Texplist(Texp e) { + explist=null; + exp=e; + } + + public String toString() { + if (explist!=null) + return explist+","+exp; + else + return exp.toString(); + } + + public void checkcontext(SymTab st) { + if (explist!=null) + explist.checkcontext(st); + exp.checkcontext(st); // CoCo (DefFun,DefVar,Arity) + } // in expression + + public int length() { + if (explist!=null) + return 1+explist.length(); + else + return 1; + } + + public void prepInterp(SymTab st) { // set pointers and indices + exp.prepInterp(st); + if (explist!=null) explist.prepInterp(st); + } + + public void interpret(int[] in, int[] par, int[] res, int index) { + res[index] = exp.interpret(in,par); + if (explist!=null) explist.interpret(in,par,res,index+1); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tfun.java b/tools/lexer/jflex-1.4/examples/interpreter/Tfun.java new file mode 100644 index 000000000000..9776ae98be05 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tfun.java @@ -0,0 +1,66 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for function application. + * + * Also contains pointer to declaration location of the function. + */ +class Tfun extends Texp implements AST { + Tident ident; // name of the function + Texplist explist; // parameter list + + public Tfun(Tident i, Texplist e) { + ident=i; + explist=e; + } + + public String toString() { + return ident+"("+explist+")"; + } + + public void checkcontext(SymTab st) { // CoCo (DefFun,Arity) + explist.checkcontext(st); + SymtabEntry ste = st.lookup(ident.toString()); + if (ste==null) + Main.error("function not defined: "+ident); + else if (ste.kind() != SymtabEntry.FUN) + Main.error("variable used as funktion: "+ident); + else if (((STEfun)ste).arity() != explist.length()) + Main.error("wrong arity at function call: "+ident); + } + + Tdekl fundekl; // pointer to location of function declaration + + // set pointers and indices + public void prepInterp(SymTab st) { + fundekl = ((STEfun)st.lookup(ident.toString())).getDekl(); + explist.prepInterp(st); + } + + public int interpret(int[] in, int[] par) { + int[] newparams = new int[fundekl.arity()]; + explist.interpret(in,par,newparams,0); + return fundekl.interpret(in,newparams); + } +} + + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tident.java b/tools/lexer/jflex-1.4/examples/interpreter/Tident.java new file mode 100644 index 000000000000..dc8cba98a825 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tident.java @@ -0,0 +1,62 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for an identifier + */ +class Tident extends Texp implements AST { + String name; + + public Tident(String s) { + name = s; + } + + public String toString() { + return name; + } + + public void checkcontext(SymTab st) { // CoCo (DefVar) + SymtabEntry ste = st.lookup(name); + + if (ste==null) + Main.error("variable not defined: "+name); + else if (ste.kind() != SymtabEntry.VAR) + Main.error("function used as variable: "+name); + } + + int index; // number of ident in environment + boolean is_input; // is it an input variable? + + public void prepInterp(SymTab st) { // set index for environment + STEvar ste = (STEvar)st.lookup(name); + index = ste.getIndex(); + is_input = ste.isInput(); + } + + public int interpret(int[] in, int[] par) { + if (is_input) + return(in[index]); + else + return(par[index]); + } +} + + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tifthenelse.java b/tools/lexer/jflex-1.4/examples/interpreter/Tifthenelse.java new file mode 100644 index 000000000000..e7193f87ab66 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tifthenelse.java @@ -0,0 +1,59 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for if-then-else expressions + */ +class Tifthenelse extends Texp implements AST { + Tboolexp boolexp; // condition + Texp exp1, exp2; // then and else branch + + public Tifthenelse(Tboolexp b, Texp e1, Texp e2) { + boolexp=b; + exp1=e1; + exp2=e2; + } + + public String toString() { + return "if "+boolexp+" then "+exp1+" else "+exp2+" fi"; + } + + public void checkcontext(SymTab st) { + boolexp.checkcontext(st); + exp1.checkcontext(st); + exp2.checkcontext(st); + } + + public void prepInterp(SymTab st) { + boolexp.prepInterp(st); + exp1.prepInterp(st); + exp2.prepInterp(st); + } + + public int interpret(int[] in, int[] par) { + boolean b = boolexp.interpret(in,par); + if (b) + return exp1.interpret(in,par); + else + return exp2.interpret(in,par); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tnumber.java b/tools/lexer/jflex-1.4/examples/interpreter/Tnumber.java new file mode 100644 index 000000000000..fef710ae24c5 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tnumber.java @@ -0,0 +1,47 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for a number + */ +class Tnumber extends Texp implements AST { + int n; // value of the number + + public Tnumber(String s) { + try { n = Integer.parseInt(s); } + catch (NumberFormatException e) { n=-1; }; + } + + public String toString() { + return(""+n); + } + + public void checkcontext(SymTab st) { + } + + public void prepInterp(SymTab st) { + } + + public int interpret(int[] in, int[] par) { + return(n); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tparlist.java b/tools/lexer/jflex-1.4/examples/interpreter/Tparlist.java new file mode 100644 index 000000000000..6f2ada93f0a6 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tparlist.java @@ -0,0 +1,54 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for a parameter list. + */ +class Tparlist implements AST { + Tparlist parlist; // rest of the liste (optional null) + Tident ident; // identifier + + public Tparlist(Tparlist p, Tident i) { + parlist=p; + ident=i; + } + + public Tparlist(Tident i) { + parlist=null; + ident=i; + } + + public String toString() { + if (parlist!=null) + return parlist+","+ident; + else + return ident.toString(); + } + + public void setSymtab(SymTab st, boolean isInput, int index) { + boolean isNew = st.enter(ident.toString(), + new STEvar(ident.toString(), isInput, index)); + + if (!isNew) Main.error("Variable "+ident+" defined twice!"); + if (parlist!=null) parlist.setSymtab(st, isInput, index+1); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tprogram.java b/tools/lexer/jflex-1.4/examples/interpreter/Tprogram.java new file mode 100644 index 000000000000..08a93d17fc80 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tprogram.java @@ -0,0 +1,99 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for the whole program (top node). + * + * Also contains two symbol tables, one for input variables, + * one for function names. + * + * All operations like context check, symbol table build up + * etc. start here. + */ +class Tprogram implements AST { + + Tparlist parlist; // input variables + Tdekllist dekllist; // function declarations + Texplist explist; // result expressions + Texplist arguments; // input values + + public Tprogram(Tparlist p, Tdekllist d, Texplist e, Texplist a) { + parlist=p; + dekllist=d; + explist=e; + arguments=a; + } + + public String toString() { + return("Program:\n=============\ninput "+parlist+ + "\nfunctions\n"+dekllist+"\noutput "+explist+ + "\narguments "+arguments+"\nend"); + } + + SymTab inputs; // table of input variables + SymTab functions; // table of functions + + public void setSymtabs() { // calculate symbol table entries + inputs = new SymTab(); // set input variables + parlist.setSymtab(inputs, true, 0); + functions = new SymTab(inputs); + dekllist.setSymtab(functions); + } + + public void printSymtabs() { + System.out.print("Input variables-\n"+inputs); + System.out.print("Functions-\n"+functions); + dekllist.printSymtabs(); + } + + public void checkcontext() { + dekllist.checkcontext(); // CoCo (DefFun,DefVar,Arity) + // in function bodies + explist.checkcontext(functions); // CoCo (DefFun,DefVar,Arity) + // in result expressions + arguments.checkcontext(new SymTab()); // CoCo (constants) + // in arguments + if (arguments.length()!=inputs.size()) + Main.error("Argument list and input variables list differ!"); + } + + public void prepInterp() { // set pointers and indices + dekllist.prepInterp(functions); + explist.prepInterp(functions); + } + + public void interpret() { + int[] inputEnv = new int[inputs.size()]; // set input + + arguments.interpret(null,null,inputEnv,0); + + System.out.println("Result:\n============="); + + int[] ergebnis = new int[explist.length()]; + explist.interpret(inputEnv,null,ergebnis,0); // calculate result + + int i; + for (i=explist.length()-1; i > 0; i--) + System.out.print(ergebnis[i]+", "); + System.out.println(ergebnis[i]); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/Tuminus.java b/tools/lexer/jflex-1.4/examples/interpreter/Tuminus.java new file mode 100644 index 000000000000..d269b34f4a5e --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/Tuminus.java @@ -0,0 +1,49 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + * AST node for unary minus expressions. + */ +class Tuminus extends Texp implements AST { + + Texp exp; // the negated expression + + public Tuminus(Texp e) { + exp=e; + } + + public String toString() { + return "-"+exp; + } + + public void checkcontext(SymTab st) { + exp.checkcontext(st); + } + + public void prepInterp(SymTab st) { + exp.prepInterp(st); + } + + public int interpret(int[] in, int[] par) { + return -(exp.interpret(in,par)); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/build.xml b/tools/lexer/jflex-1.4/examples/interpreter/build.xml new file mode 100644 index 000000000000..51829ba97893 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/build.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/lexer/jflex-1.4/examples/interpreter/example.as b/tools/lexer/jflex-1.4/examples/interpreter/example.as new file mode 100644 index 000000000000..81522472e175 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/example.as @@ -0,0 +1,16 @@ + +// example program for interpreter testing +// contains division and modulo functins + +input a,b +functions div(x,y) = if x < y + then 0 + else div(x-y,y)+1 + fi, + mod(x,y) = if x < y + then x + else mod(x-y,y) + fi +output div(a,b), mod(a,b) +arguments 324, 17 +end diff --git a/tools/lexer/jflex-1.4/examples/interpreter/parser.cup b/tools/lexer/jflex-1.4/examples/interpreter/parser.cup new file mode 100644 index 000000000000..3d7f856a679d --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/parser.cup @@ -0,0 +1,112 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +// definition of tokens, if applicable with token type +terminal INPUT, FUNCTIONS, OUTPUT, END, ARGUMENTS; +terminal IF, THEN, ELSE, FI, ERROR; +terminal COMMA, LPAR, RPAR; +terminal EQ, LE, LEQ, MINUS, PLUS, TIMES, DIV, UMINUS; + +terminal String ID, NUMBER; + +non terminal Tprogram program; +non terminal Tparlist parlist; +non terminal Texplist explist; +non terminal Tdekllist dekllist; +non terminal Tdekl dekl; +non terminal Texp exp; +non terminal Tboolexp boolexp; +non terminal Tident ident; +non terminal Tnumber number; + + +// precedences, left associativity +precedence left EQ, LE, LEQ; +precedence left MINUS, PLUS; +precedence left TIMES, DIV; +precedence left UMINUS; + + +// here the rules start +program ::= INPUT parlist:p FUNCTIONS dekllist:d OUTPUT explist:o + ARGUMENTS explist:a END + {: RESULT = new Tprogram(p,d,o,a); :} + ; + +parlist ::= ident:i + {: RESULT = new Tparlist(i); :} + | parlist:p COMMA ident:i + {: RESULT = new Tparlist(p,i); :} + ; + +explist ::= exp:e + {: RESULT = new Texplist(e); :} + | explist:l COMMA exp:e + {: RESULT = new Texplist(l,e); :} + ; + +dekllist ::= dekl:d + {: RESULT = new Tdekllist(d);:} + | dekllist:l COMMA dekl:d + {: RESULT = new Tdekllist(l,d); :} + ; + +dekl ::= ident:i LPAR parlist:p RPAR EQ exp:e + {: RESULT = new Tdekl(i,p,e); :} + ; + +exp ::= number:n + {: RESULT = n; :} + | ident:i + {: RESULT = i; :} + | ident:i LPAR explist:e RPAR + {: RESULT = new Tfun(i,e); :} + | LPAR exp:e RPAR + {: RESULT = e; :} + | MINUS exp:e + {: RESULT = new Tuminus(e); :} %prec UMINUS + | exp:l PLUS exp:r + {: RESULT = new Texpinfix(l,'+',r); :} + | exp:l TIMES exp:r + {: RESULT = new Texpinfix(l,'*',r); :} + | exp:l DIV exp:r + {: RESULT = new Texpinfix(l,'/',r); :} + | exp:l MINUS exp:r + {: RESULT = new Texpinfix(l,'-',r); :} + | IF boolexp:b THEN exp:t ELSE exp:e FI + {: RESULT = new Tifthenelse(b,t,e); :} + ; + +boolexp ::= exp:l EQ exp:r + {: RESULT = new Tboolexp(l,'=',r); :} + | exp:l LE exp:r + {: RESULT = new Tboolexp(l,'<',r); :} + | exp:l LEQ exp:r + {: RESULT = new Tboolexp(l,'!',r); :} + ; + +ident ::= ID:n + {: RESULT = new Tident(n); :} + ; + +number ::= NUMBER:z + {: RESULT = new Tnumber(z); :} + ; diff --git a/tools/lexer/jflex-1.4/examples/interpreter/scanner.flex b/tools/lexer/jflex-1.4/examples/interpreter/scanner.flex new file mode 100644 index 000000000000..a6c3ca7e6c91 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/interpreter/scanner.flex @@ -0,0 +1,71 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2001 Gerwin Klein * + * Copyright (C) 2001 Bernhard Rumpe * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +import java_cup.runtime.Symbol; + +%% + +%cup +%implements sym + +%{ + SymTab symtab; // externe symbol table + + public void setSymtab(SymTab symtab) { + this.symtab = symtab; + } + + private Symbol sym(int sym) { + return new Symbol(sym); + } + + private Symbol sym(int sym, Object val) { + return new Symbol(sym, val); + } +%} + +%% + +"arguments" { return sym(ARGUMENTS); } +"input" { return sym(INPUT); } +"functions" { return sym(FUNCTIONS); } +"output" { return sym(OUTPUT); } +"end" { return sym(END); } +"if" { return sym(IF); } +"then" { return sym(THEN); } +"else" { return sym(ELSE); } +"fi" { return sym(FI); } +[a-z]+ { symtab.enter(yytext(),new SymtabEntry(yytext())); + return sym(ID,yytext()); } +[0-9]+ { return sym(NUMBER,yytext()); } +"," { return sym(COMMA); } +"(" { return sym(LPAR); } +")" { return sym(RPAR); } +"=" { return sym(EQ); } +"-" { return sym(MINUS); } +"+" { return sym(PLUS); } +"*" { return sym(TIMES); } +"/" { return sym(DIV); } +"<" { return sym(LE); } +"<=" { return sym(LEQ); } +[\ \t\b\f\r\n]+ { /* eat whitespace */ } +"//"[^\n]* { /* one-line comment */ } +. { throw new Error("Unexpected character ["+yytext()+"]"); } diff --git a/tools/lexer/jflex-1.4/examples/java/JavaParser.java b/tools/lexer/jflex-1.4/examples/java/JavaParser.java new file mode 100644 index 000000000000..4c587051b460 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/JavaParser.java @@ -0,0 +1,47 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +import java.io.FileReader; + + +/** + * Simple test driver for the java parser. Just runs it on some + * input files, gives no useful output. + */ +public class JavaParser { + + public static void main(String argv[]) { + + for (int i = 0; i < argv.length; i++) { + try { + System.out.println("Parsing ["+argv[i]+"]"); + Scanner s = new Scanner(new UnicodeEscapes(new FileReader(argv[i]))); + parser p = new parser(s); + p.parse(); + + System.out.println("No errors."); + } + catch (Exception e) { + e.printStackTrace(System.out); + System.exit(1); + } + } + } + +} diff --git a/tools/lexer/jflex-1.4/examples/java/JavaSymbol.java b/tools/lexer/jflex-1.4/examples/java/JavaSymbol.java new file mode 100644 index 000000000000..d27b63dfe69f --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/JavaSymbol.java @@ -0,0 +1,31 @@ + +public class JavaSymbol extends java_cup.runtime.Symbol { + private int line; + private int column; + + public JavaSymbol(int type, int line, int column) { + this(type, line, column, -1, -1, null); + } + + public JavaSymbol(int type, int line, int column, Object value) { + this(type, line, column, -1, -1, value); + } + + public JavaSymbol(int type, int line, int column, int left, int right, Object value) { + super(type, left, right, value); + this.line = line; + this.column = column; + } + + public int getLine() { + return line; + } + + public int getColumn() { + return column; + } + + public String toString() { + return "line "+line+", column "+column+", sym: "+sym+(value == null ? "" : (", value: '"+value+"'")); + } +} diff --git a/tools/lexer/jflex-1.4/examples/java/Makefile b/tools/lexer/jflex-1.4/examples/java/Makefile new file mode 100644 index 000000000000..655ebd368150 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/Makefile @@ -0,0 +1,48 @@ +# You need CUP v0.10j (or newer) for this makefile to work (for java12.cup) +# +# CUP classes should be included in CLASSPATH + +CUP = java java_cup.Main -interface < +JFLEX = jflex +JAVA = java +JAVAC = javac +#JAVAC = jikes +JAVACFLAGS = + +# -------------------------------------------------- + +all: test + +test: lexer-output.txt + @(diff lexer-output.txt lexer-output.good && echo "Test OK!") || echo "Test failed!" + +lexer-output.txt: compile + $(JAVA) TestLexer TestLexer.java > lexer-output.txt + + +compile: scanner parser unicode + $(JAVAC) $(JAVACFLAGS) JavaParser.java TestLexer.java + +parser: parser.java + +parser.java: java12.cup + $(CUP) java12.cup + +scanner: Scanner.java + +Scanner.java: java.flex + $(JFLEX) java.flex + +unicode: UnicodeEscapes.java + +UnicodeEscapes.java: unicode.flex + $(JFLEX) unicode.flex + +clean: + rm -f *.class + rm -f *~ + rm -f Scanner.java + rm -f parser.java + rm -f sym.java + rm -f UnicodeEscapes.java + rm -f lexer-output.txt diff --git a/tools/lexer/jflex-1.4/examples/java/README b/tools/lexer/jflex-1.4/examples/java/README new file mode 100644 index 000000000000..096582bf4417 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/README @@ -0,0 +1,41 @@ +This directory contains a scanner and parser for the Java programming language. + +You need the parser generator CUP v0.10j (or newer) for the parser to work. +Use the Makefile to generate the lexer and parser, or type: + +jflex unicode.flex +jflex java.flex +java java_cup.Main -interface < java12.cup +javac JavaParser.java TestLexer.java + + +The parser can be tested with: +java JavaParser + +The scanner (without parser attached) can be test with: +java TestLexer + + +files: + +unicode.flex + JFlex specification for the Unicode preprocessing phase + (see section 3.3 of the Java Language Specification). + Demonstrates how to implement a FilterReader with JFlex. + +java.flex + JFlex specification for the "real" Java 1.2 lexer. + +java12.cup + CUP specification for the Java 1.2 parser + Copyright (C) 1998 by C. Scott Ananian + (with small modifications to interface with the Lexer) + +JavaParser.java + a simple main class to run the parser (no other useful output though) + +TestLexer.java + a simple test driver for the scanner, produces debug output + +lexer-output.good + lexer output for input file TestLexer.java for testing diff --git a/tools/lexer/jflex-1.4/examples/java/TestLexer.java b/tools/lexer/jflex-1.4/examples/java/TestLexer.java new file mode 100644 index 000000000000..90e4f35681bf --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/TestLexer.java @@ -0,0 +1,62 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +import java_cup.runtime.Symbol; + +import java.io.FileReader; + + +/** + * Simple test driver for the java lexer. Just runs it on some + * input files and produces debug output. Needs symbol class from + * parser. + */ +public class TestLexer { + + /** some numerals to for lexer testing */ + int intDec = 37; + long longDec = 37l; + int intHex = 0x0001; + long longHex = 0xFFFFl; + int intOct = 0377; + long longOc = 007l; + + + public static void main(String argv[]) { + + for (int i = 0; i < argv.length; i++) { + try { + System.out.println("Lexing ["+argv[i]+"]"); + Scanner scanner = new Scanner(new UnicodeEscapes(new FileReader(argv[i]))); + + Symbol s; + do { + s = scanner.debug_next_token(); + System.out.println("token: "+s); + } while (s.sym != sym.EOF); + + System.out.println("No errors."); + } + catch (Exception e) { + e.printStackTrace(System.out); + System.exit(1); + } + } + } +} diff --git a/tools/lexer/jflex-1.4/examples/java/java.flex b/tools/lexer/jflex-1.4/examples/java/java.flex new file mode 100644 index 000000000000..cdce5b6a11cb --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/java.flex @@ -0,0 +1,312 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Java 1.2 language lexer specification */ + +/* Use together with unicode.flex for Unicode preprocesssing */ +/* and java12.cup for a Java 1.2 parser */ + +/* Note that this lexer specification is not tuned for speed. + It is in fact quite slow on integer and floating point literals, + because the input is read twice and the methods used to parse + the numbers are not very fast. + For a production quality application (e.g. a Java compiler) + this could be optimized */ + + +import java_cup.runtime.*; + +%% + +%public +%class Scanner +%implements sym + +%unicode + +%line +%column + +%cup +%cupdebug + +%{ + StringBuffer string = new StringBuffer(); + + private Symbol symbol(int type) { + return new JavaSymbol(type, yyline+1, yycolumn+1); + } + + private Symbol symbol(int type, Object value) { + return new JavaSymbol(type, yyline+1, yycolumn+1, value); + } + + /** + * assumes correct representation of a long value for + * specified radix in scanner buffer from start + * to end + */ + private long parseLong(int start, int end, int radix) { + long result = 0; + long digit; + + for (int i = start; i < end; i++) { + digit = Character.digit(yycharat(i),radix); + result*= radix; + result+= digit; + } + + return result; + } +%} + +/* main character classes */ +LineTerminator = \r|\n|\r\n +InputCharacter = [^\r\n] + +WhiteSpace = {LineTerminator} | [ \t\f] + +/* comments */ +Comment = {TraditionalComment} | {EndOfLineComment} | + {DocumentationComment} + +TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" +EndOfLineComment = "//" {InputCharacter}* {LineTerminator}? +DocumentationComment = "/*" "*"+ [^/*] ~"*/" + +/* identifiers */ +Identifier = [:jletter:][:jletterdigit:]* + +/* integer literals */ +DecIntegerLiteral = 0 | [1-9][0-9]* +DecLongLiteral = {DecIntegerLiteral} [lL] + +HexIntegerLiteral = 0 [xX] 0* {HexDigit} {1,8} +HexLongLiteral = 0 [xX] 0* {HexDigit} {1,16} [lL] +HexDigit = [0-9a-fA-F] + +OctIntegerLiteral = 0+ [1-3]? {OctDigit} {1,15} +OctLongLiteral = 0+ 1? {OctDigit} {1,21} [lL] +OctDigit = [0-7] + +/* floating point literals */ +FloatLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? [fF] +DoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}? + +FLit1 = [0-9]+ \. [0-9]* +FLit2 = \. [0-9]+ +FLit3 = [0-9]+ +Exponent = [eE] [+-]? [0-9]+ + +/* string and character literals */ +StringCharacter = [^\r\n\"\\] +SingleCharacter = [^\r\n\'\\] + +%state STRING, CHARLITERAL + +%% + + { + + /* keywords */ + "abstract" { return symbol(ABSTRACT); } + "boolean" { return symbol(BOOLEAN); } + "break" { return symbol(BREAK); } + "byte" { return symbol(BYTE); } + "case" { return symbol(CASE); } + "catch" { return symbol(CATCH); } + "char" { return symbol(CHAR); } + "class" { return symbol(CLASS); } + "const" { return symbol(CONST); } + "continue" { return symbol(CONTINUE); } + "do" { return symbol(DO); } + "double" { return symbol(DOUBLE); } + "else" { return symbol(ELSE); } + "extends" { return symbol(EXTENDS); } + "final" { return symbol(FINAL); } + "finally" { return symbol(FINALLY); } + "float" { return symbol(FLOAT); } + "for" { return symbol(FOR); } + "default" { return symbol(DEFAULT); } + "implements" { return symbol(IMPLEMENTS); } + "import" { return symbol(IMPORT); } + "instanceof" { return symbol(INSTANCEOF); } + "int" { return symbol(INT); } + "interface" { return symbol(INTERFACE); } + "long" { return symbol(LONG); } + "native" { return symbol(NATIVE); } + "new" { return symbol(NEW); } + "goto" { return symbol(GOTO); } + "if" { return symbol(IF); } + "public" { return symbol(PUBLIC); } + "short" { return symbol(SHORT); } + "super" { return symbol(SUPER); } + "switch" { return symbol(SWITCH); } + "synchronized" { return symbol(SYNCHRONIZED); } + "package" { return symbol(PACKAGE); } + "private" { return symbol(PRIVATE); } + "protected" { return symbol(PROTECTED); } + "transient" { return symbol(TRANSIENT); } + "return" { return symbol(RETURN); } + "void" { return symbol(VOID); } + "static" { return symbol(STATIC); } + "while" { return symbol(WHILE); } + "this" { return symbol(THIS); } + "throw" { return symbol(THROW); } + "throws" { return symbol(THROWS); } + "try" { return symbol(TRY); } + "volatile" { return symbol(VOLATILE); } + "strictfp" { return symbol(STRICTFP); } + + /* boolean literals */ + "true" { return symbol(BOOLEAN_LITERAL, new Boolean(true)); } + "false" { return symbol(BOOLEAN_LITERAL, new Boolean(false)); } + + /* null literal */ + "null" { return symbol(NULL_LITERAL); } + + + /* separators */ + "(" { return symbol(LPAREN); } + ")" { return symbol(RPAREN); } + "{" { return symbol(LBRACE); } + "}" { return symbol(RBRACE); } + "[" { return symbol(LBRACK); } + "]" { return symbol(RBRACK); } + ";" { return symbol(SEMICOLON); } + "," { return symbol(COMMA); } + "." { return symbol(DOT); } + + /* operators */ + "=" { return symbol(EQ); } + ">" { return symbol(GT); } + "<" { return symbol(LT); } + "!" { return symbol(NOT); } + "~" { return symbol(COMP); } + "?" { return symbol(QUESTION); } + ":" { return symbol(COLON); } + "==" { return symbol(EQEQ); } + "<=" { return symbol(LTEQ); } + ">=" { return symbol(GTEQ); } + "!=" { return symbol(NOTEQ); } + "&&" { return symbol(ANDAND); } + "||" { return symbol(OROR); } + "++" { return symbol(PLUSPLUS); } + "--" { return symbol(MINUSMINUS); } + "+" { return symbol(PLUS); } + "-" { return symbol(MINUS); } + "*" { return symbol(MULT); } + "/" { return symbol(DIV); } + "&" { return symbol(AND); } + "|" { return symbol(OR); } + "^" { return symbol(XOR); } + "%" { return symbol(MOD); } + "<<" { return symbol(LSHIFT); } + ">>" { return symbol(RSHIFT); } + ">>>" { return symbol(URSHIFT); } + "+=" { return symbol(PLUSEQ); } + "-=" { return symbol(MINUSEQ); } + "*=" { return symbol(MULTEQ); } + "/=" { return symbol(DIVEQ); } + "&=" { return symbol(ANDEQ); } + "|=" { return symbol(OREQ); } + "^=" { return symbol(XOREQ); } + "%=" { return symbol(MODEQ); } + "<<=" { return symbol(LSHIFTEQ); } + ">>=" { return symbol(RSHIFTEQ); } + ">>>=" { return symbol(URSHIFTEQ); } + + /* string literal */ + \" { yybegin(STRING); string.setLength(0); } + + /* character literal */ + \' { yybegin(CHARLITERAL); } + + /* numeric literals */ + + {DecIntegerLiteral} { return symbol(INTEGER_LITERAL, new Integer(yytext())); } + {DecLongLiteral} { return symbol(INTEGER_LITERAL, new Long(yytext().substring(0,yylength()-1))); } + + {HexIntegerLiteral} { return symbol(INTEGER_LITERAL, new Integer((int) parseLong(2, yylength(), 16))); } + {HexLongLiteral} { return symbol(INTEGER_LITERAL, new Long(parseLong(2, yylength()-1, 16))); } + + {OctIntegerLiteral} { return symbol(INTEGER_LITERAL, new Integer((int) parseLong(0, yylength(), 8))); } + {OctLongLiteral} { return symbol(INTEGER_LITERAL, new Long(parseLong(0, yylength()-1, 8))); } + + {FloatLiteral} { return symbol(FLOATING_POINT_LITERAL, new Float(yytext().substring(0,yylength()-1))); } + {DoubleLiteral} { return symbol(FLOATING_POINT_LITERAL, new Double(yytext())); } + {DoubleLiteral}[dD] { return symbol(FLOATING_POINT_LITERAL, new Double(yytext().substring(0,yylength()-1))); } + + /* comments */ + {Comment} { /* ignore */ } + + /* whitespace */ + {WhiteSpace} { /* ignore */ } + + /* identifiers */ + {Identifier} { return symbol(IDENTIFIER, yytext()); } +} + + { + \" { yybegin(YYINITIAL); return symbol(STRING_LITERAL, string.toString()); } + + {StringCharacter}+ { string.append( yytext() ); } + + /* escape sequences */ + "\\b" { string.append( '\b' ); } + "\\t" { string.append( '\t' ); } + "\\n" { string.append( '\n' ); } + "\\f" { string.append( '\f' ); } + "\\r" { string.append( '\r' ); } + "\\\"" { string.append( '\"' ); } + "\\'" { string.append( '\'' ); } + "\\\\" { string.append( '\\' ); } + \\[0-3]?{OctDigit}?{OctDigit} { char val = (char) Integer.parseInt(yytext().substring(1),8); + string.append( val ); } + + /* error cases */ + \\. { throw new RuntimeException("Illegal escape sequence \""+yytext()+"\""); } + {LineTerminator} { throw new RuntimeException("Unterminated string at end of line"); } +} + + { + {SingleCharacter}\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character(yytext().charAt(0))); } + + /* escape sequences */ + "\\b"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\b'));} + "\\t"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\t'));} + "\\n"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\n'));} + "\\f"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\f'));} + "\\r"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\r'));} + "\\\""\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\"'));} + "\\'"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\''));} + "\\\\"\' { yybegin(YYINITIAL); return symbol(CHARACTER_LITERAL, new Character('\\')); } + \\[0-3]?{OctDigit}?{OctDigit}\' { yybegin(YYINITIAL); + int val = Integer.parseInt(yytext().substring(1,yylength()-1),8); + return symbol(CHARACTER_LITERAL, new Character((char)val)); } + + /* error cases */ + \\. { throw new RuntimeException("Illegal escape sequence \""+yytext()+"\""); } + {LineTerminator} { throw new RuntimeException("Unterminated character literal at end of line"); } +} + +/* error fallback */ +.|\n { throw new RuntimeException("Illegal character \""+yytext()+ + "\" at line "+yyline+", column "+yycolumn); } +<> { return symbol(EOF); } \ No newline at end of file diff --git a/tools/lexer/jflex-1.4/examples/java/java12.cup b/tools/lexer/jflex-1.4/examples/java/java12.cup new file mode 100644 index 000000000000..d8c258775b48 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/java12.cup @@ -0,0 +1,885 @@ +import java_cup.runtime.*; + + +/* August 1999 - modified by Gerwin Klein + to interface with JFlex scanners, + allows empty semicolon in class decls. + + changed productions: + + class_member_declaration ::= + field_declaration + | method_declaration + [..] + | interface_declaration + | SEMICOLON + ; + + interface_member_declaration ::= + constant_declaration + | abstract_method_declaration + | class_declaration + | interface_declaration + | SEMICOLON + ; + +*/ + + +/* Java 1.2 parser for CUP. + * Copyright (C) 1998 C. Scott Ananian + * This program is released under the terms of the GPL; see the file + * COPYING for more details. There is NO WARRANTY on this code. + */ + +/* +JDK 1.2 Features added: + strictfp modifier. + explicit_constructor_invocation ::= ... + | primary DOT THIS LPAREN argument_list_opt RPAREN SEMICOLON ; + field_access ::= ... + | name DOT SUPER DOT IDENTIFIER ; + method_invocation ::= ... + | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN ; +*/ + +parser code {: + public void report_error(String message, Object info) { + StringBuffer m = new StringBuffer("Error "); + + if (info instanceof java_cup.runtime.Symbol) + m.append( "("+info.toString()+")" ); + + m.append(" : "+message); + + System.out.println(m); + } + + public void report_fatal_error(String message, Object info) { + report_error(message, info); + throw new RuntimeException("Fatal Syntax Error"); + } +:}; + +terminal BOOLEAN; // primitive_type +terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type +terminal FLOAT, DOUBLE; // floating_point_type +terminal LBRACK, RBRACK; // array_type +terminal DOT; // qualified_name +terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON; +terminal PACKAGE; // package_declaration +terminal IMPORT; // import_declaration +terminal PUBLIC, PROTECTED, PRIVATE; // modifier +terminal STATIC; // modifier +terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE; +terminal CLASS; // class_declaration +terminal EXTENDS; // super +terminal IMPLEMENTS; // interfaces +terminal VOID; // method_header +terminal THROWS; // throws +terminal THIS, SUPER; // explicit_constructor_invocation +terminal INTERFACE; // interface_declaration +terminal IF, ELSE; // if_then_statement, if_then_else_statement +terminal SWITCH; // switch_statement +terminal CASE, DEFAULT; // switch_label +terminal DO, WHILE; // while_statement, do_statement +terminal FOR; // for_statement +terminal BREAK; // break_statement +terminal CONTINUE; // continue_statement +terminal RETURN; // return_statement +terminal THROW; // throw_statement +terminal TRY; // try_statement +terminal CATCH; // catch_clause +terminal FINALLY; // finally +terminal NEW; // class_instance_creation_expression +terminal PLUSPLUS; // postincrement_expression +terminal MINUSMINUS; // postdecrement_expression +terminal PLUS, MINUS, COMP, NOT, DIV, MOD; +terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression +terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression +terminal EQEQ, NOTEQ; // equality_expression +terminal AND; // and_expression +terminal XOR; // exclusive_or_expression +terminal OR; // inclusive_or_expression +terminal ANDAND; // conditional_and_expression +terminal OROR; // conditional_or_expression +terminal QUESTION; // conditional_expression +terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator +terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator +terminal ANDEQ, XOREQ, OREQ; // assignment_operator + +terminal java.lang.Number INTEGER_LITERAL; +terminal java.lang.Number FLOATING_POINT_LITERAL; +terminal java.lang.Boolean BOOLEAN_LITERAL; +terminal java.lang.Character CHARACTER_LITERAL; +terminal java.lang.String STRING_LITERAL; +terminal java.lang.String IDENTIFIER; // name +terminal NULL_LITERAL; + +// strictfp keyword, new in Java 1.2 +terminal STRICTFP; + +// Reserved but unused: +terminal CONST, GOTO; + +// 19.2) The Syntactic Grammar +non terminal goal; +// 19.3) Lexical Structure +non terminal literal; +// 19.4) Types, Values, and Variables +non terminal type, primitive_type, numeric_type; +non terminal integral_type, floating_point_type; +non terminal reference_type; +non terminal class_or_interface_type; +non terminal class_type, interface_type; +non terminal array_type; +// 19.5) Names +non terminal name, simple_name, qualified_name; +// 19.6) Packages +non terminal compilation_unit; +non terminal package_declaration_opt, package_declaration; +non terminal import_declarations_opt, import_declarations; +non terminal type_declarations_opt, type_declarations; +non terminal import_declaration; +non terminal single_type_import_declaration; +non terminal type_import_on_demand_declaration; +non terminal type_declaration; +// 19.7) Productions used only in the LALR(1) grammar +non terminal modifiers_opt, modifiers, modifier; +// 19.8.1) Class Declaration +non terminal class_declaration, super, super_opt; +non terminal interfaces, interfaces_opt, interface_type_list; +non terminal class_body; +non terminal class_body_declarations, class_body_declarations_opt; +non terminal class_body_declaration, class_member_declaration; +// 19.8.2) Field Declarations +non terminal field_declaration, variable_declarators, variable_declarator; +non terminal variable_declarator_id, variable_initializer; +// 19.8.3) Method Declarations +non terminal method_declaration, method_header, method_declarator; +non terminal formal_parameter_list_opt, formal_parameter_list; +non terminal formal_parameter; +non terminal throws_opt, throws; +non terminal class_type_list, method_body; +// 19.8.4) Static Initializers +non terminal static_initializer; +// 19.8.5) Constructor Declarations +non terminal constructor_declaration, constructor_declarator; +non terminal constructor_body; +non terminal explicit_constructor_invocation; +// 19.9.1) Interface Declarations +non terminal interface_declaration; +non terminal extends_interfaces_opt, extends_interfaces; +non terminal interface_body; +non terminal interface_member_declarations_opt, interface_member_declarations; +non terminal interface_member_declaration, constant_declaration; +non terminal abstract_method_declaration; +// 19.10) Arrays +non terminal array_initializer; +non terminal variable_initializers; +// 19.11) Blocks and Statements +non terminal block; +non terminal block_statements_opt, block_statements, block_statement; +non terminal local_variable_declaration_statement, local_variable_declaration; +non terminal statement, statement_no_short_if; +non terminal statement_without_trailing_substatement; +non terminal empty_statement; +non terminal labeled_statement, labeled_statement_no_short_if; +non terminal expression_statement, statement_expression; +non terminal if_then_statement; +non terminal if_then_else_statement, if_then_else_statement_no_short_if; +non terminal switch_statement, switch_block; +non terminal switch_block_statement_groups; +non terminal switch_block_statement_group; +non terminal switch_labels, switch_label; +non terminal while_statement, while_statement_no_short_if; +non terminal do_statement; +non terminal for_statement, for_statement_no_short_if; +non terminal for_init_opt, for_init; +non terminal for_update_opt, for_update; +non terminal statement_expression_list; +non terminal identifier_opt; +non terminal break_statement, continue_statement; +non terminal return_statement, throw_statement; +non terminal synchronized_statement, try_statement; +non terminal catches_opt, catches, catch_clause; +non terminal finally; +// 19.12) Expressions +non terminal primary, primary_no_new_array; +non terminal class_instance_creation_expression; +non terminal argument_list_opt, argument_list; +non terminal array_creation_expression; +non terminal dim_exprs, dim_expr, dims_opt, dims; +non terminal field_access, method_invocation, array_access; +non terminal postfix_expression; +non terminal postincrement_expression, postdecrement_expression; +non terminal unary_expression, unary_expression_not_plus_minus; +non terminal preincrement_expression, predecrement_expression; +non terminal cast_expression; +non terminal multiplicative_expression, additive_expression; +non terminal shift_expression, relational_expression, equality_expression; +non terminal and_expression, exclusive_or_expression, inclusive_or_expression; +non terminal conditional_and_expression, conditional_or_expression; +non terminal conditional_expression, assignment_expression; +non terminal assignment; +non terminal left_hand_side; +non terminal assignment_operator; +non terminal expression_opt, expression; +non terminal constant_expression; + + +start with goal; + +// 19.2) The Syntactic Grammar +goal ::= compilation_unit + ; + +// 19.3) Lexical Structure. +literal ::= INTEGER_LITERAL + | FLOATING_POINT_LITERAL + | BOOLEAN_LITERAL + | CHARACTER_LITERAL + | STRING_LITERAL + | NULL_LITERAL + ; + +// 19.4) Types, Values, and Variables +type ::= primitive_type + | reference_type + ; +primitive_type ::= + numeric_type + | BOOLEAN + ; +numeric_type::= integral_type + | floating_point_type + ; +integral_type ::= + BYTE + | SHORT + | INT + | LONG + | CHAR + ; +floating_point_type ::= + FLOAT + | DOUBLE + ; + +reference_type ::= + class_or_interface_type + | array_type + ; +class_or_interface_type ::= name; + +class_type ::= class_or_interface_type; +interface_type ::= class_or_interface_type; + +array_type ::= primitive_type dims + | name dims + ; + +// 19.5) Names +name ::= simple_name + | qualified_name + ; +simple_name ::= IDENTIFIER + ; +qualified_name ::= + name DOT IDENTIFIER + ; + +// 19.6) Packages +compilation_unit ::= + package_declaration_opt + import_declarations_opt + type_declarations_opt + ; +package_declaration_opt ::= package_declaration | ; +import_declarations_opt ::= import_declarations | ; +type_declarations_opt ::= type_declarations | ; + +import_declarations ::= + import_declaration + | import_declarations import_declaration + ; +type_declarations ::= + type_declaration + | type_declarations type_declaration + ; +package_declaration ::= + PACKAGE name SEMICOLON + ; +import_declaration ::= + single_type_import_declaration + | type_import_on_demand_declaration + ; +single_type_import_declaration ::= + IMPORT name SEMICOLON + ; +type_import_on_demand_declaration ::= + IMPORT name DOT MULT SEMICOLON + ; +type_declaration ::= + class_declaration + | interface_declaration + | SEMICOLON + ; + +// 19.7) Productions used only in the LALR(1) grammar +modifiers_opt::= + | modifiers + ; +modifiers ::= modifier + | modifiers modifier + ; +modifier ::= PUBLIC | PROTECTED | PRIVATE + | STATIC + | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE + | STRICTFP // note that semantic analysis must check that the + // context of the modifier allows strictfp. + ; + +// 19.8) Classes + +// 19.8.1) Class Declaration: +class_declaration ::= + modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body + ; +super ::= EXTENDS class_type + ; +super_opt ::= + | super + ; +interfaces ::= IMPLEMENTS interface_type_list + ; +interfaces_opt::= + | interfaces + ; +interface_type_list ::= + interface_type + | interface_type_list COMMA interface_type + ; +class_body ::= LBRACE class_body_declarations_opt RBRACE + ; +class_body_declarations_opt ::= + | class_body_declarations ; +class_body_declarations ::= + class_body_declaration + | class_body_declarations class_body_declaration + ; +class_body_declaration ::= + class_member_declaration + | static_initializer + | constructor_declaration + | block + ; +class_member_declaration ::= + field_declaration + | method_declaration + /* repeat the prod for 'class_declaration' here: */ + | modifiers_opt CLASS IDENTIFIER super_opt interfaces_opt class_body + | interface_declaration + | SEMICOLON + ; + +// 19.8.2) Field Declarations +field_declaration ::= + modifiers_opt type variable_declarators SEMICOLON + ; +variable_declarators ::= + variable_declarator + | variable_declarators COMMA variable_declarator + ; +variable_declarator ::= + variable_declarator_id + | variable_declarator_id EQ variable_initializer + ; +variable_declarator_id ::= + IDENTIFIER + | variable_declarator_id LBRACK RBRACK + ; +variable_initializer ::= + expression + | array_initializer + ; + +// 19.8.3) Method Declarations +method_declaration ::= + method_header method_body + ; +method_header ::= + modifiers_opt type method_declarator throws_opt + | modifiers_opt VOID method_declarator throws_opt + ; +method_declarator ::= + IDENTIFIER LPAREN formal_parameter_list_opt RPAREN + | method_declarator LBRACK RBRACK // deprecated + // be careful; the above production also allows 'void foo() []' + ; +formal_parameter_list_opt ::= + | formal_parameter_list + ; +formal_parameter_list ::= + formal_parameter + | formal_parameter_list COMMA formal_parameter + ; +formal_parameter ::= + type variable_declarator_id + | FINAL type variable_declarator_id + ; +throws_opt ::= + | throws + ; +throws ::= THROWS class_type_list + ; +class_type_list ::= + class_type + | class_type_list COMMA class_type + ; +method_body ::= block + | SEMICOLON + ; + +// 19.8.4) Static Initializers +static_initializer ::= + STATIC block + ; + +// 19.8.5) Constructor Declarations +constructor_declaration ::= + modifiers_opt constructor_declarator throws_opt + constructor_body + ; +constructor_declarator ::= + simple_name LPAREN formal_parameter_list_opt RPAREN + ; +constructor_body ::= + LBRACE explicit_constructor_invocation + block_statements RBRACE + | LBRACE explicit_constructor_invocation RBRACE + | LBRACE block_statements RBRACE + | LBRACE RBRACE + ; +explicit_constructor_invocation ::= + THIS LPAREN argument_list_opt RPAREN SEMICOLON + | SUPER LPAREN argument_list_opt RPAREN SEMICOLON + | primary DOT THIS LPAREN argument_list_opt RPAREN SEMICOLON + | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON + ; + +// 19.9) Interfaces + +// 19.9.1) Interface Declarations +interface_declaration ::= + modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt + interface_body + ; +extends_interfaces_opt ::= + | extends_interfaces + ; +extends_interfaces ::= + EXTENDS interface_type + | extends_interfaces COMMA interface_type + ; +interface_body ::= + LBRACE interface_member_declarations_opt RBRACE + ; +interface_member_declarations_opt ::= + | interface_member_declarations + ; +interface_member_declarations ::= + interface_member_declaration + | interface_member_declarations interface_member_declaration + ; +interface_member_declaration ::= + constant_declaration + | abstract_method_declaration + | class_declaration + | interface_declaration + | SEMICOLON + ; +constant_declaration ::= + field_declaration + ; +abstract_method_declaration ::= + method_header SEMICOLON + ; + +// 19.10) Arrays +array_initializer ::= + LBRACE variable_initializers COMMA RBRACE + | LBRACE variable_initializers RBRACE + | LBRACE COMMA RBRACE + | LBRACE RBRACE + ; +variable_initializers ::= + variable_initializer + | variable_initializers COMMA variable_initializer + ; + +// 19.11) Blocks and Statements +block ::= LBRACE block_statements_opt RBRACE + ; +block_statements_opt ::= + | block_statements + ; +block_statements ::= + block_statement + | block_statements block_statement + ; +block_statement ::= + local_variable_declaration_statement + | statement + | class_declaration + | interface_declaration + ; +local_variable_declaration_statement ::= + local_variable_declaration SEMICOLON + ; +local_variable_declaration ::= + type variable_declarators + | FINAL type variable_declarators + ; +statement ::= statement_without_trailing_substatement + | labeled_statement + | if_then_statement + | if_then_else_statement + | while_statement + | for_statement + ; +statement_no_short_if ::= + statement_without_trailing_substatement + | labeled_statement_no_short_if + | if_then_else_statement_no_short_if + | while_statement_no_short_if + | for_statement_no_short_if + ; +statement_without_trailing_substatement ::= + block + | empty_statement + | expression_statement + | switch_statement + | do_statement + | break_statement + | continue_statement + | return_statement + | synchronized_statement + | throw_statement + | try_statement + ; +empty_statement ::= + SEMICOLON + ; +labeled_statement ::= + IDENTIFIER COLON statement + ; +labeled_statement_no_short_if ::= + IDENTIFIER COLON statement_no_short_if + ; +expression_statement ::= + statement_expression SEMICOLON + ; +statement_expression ::= + assignment + | preincrement_expression + | predecrement_expression + | postincrement_expression + | postdecrement_expression + | method_invocation + | class_instance_creation_expression + ; +if_then_statement ::= + IF LPAREN expression RPAREN statement + ; +if_then_else_statement ::= + IF LPAREN expression RPAREN statement_no_short_if + ELSE statement + ; +if_then_else_statement_no_short_if ::= + IF LPAREN expression RPAREN statement_no_short_if + ELSE statement_no_short_if + ; +switch_statement ::= + SWITCH LPAREN expression RPAREN switch_block + ; +switch_block ::= + LBRACE switch_block_statement_groups switch_labels RBRACE + | LBRACE switch_block_statement_groups RBRACE + | LBRACE switch_labels RBRACE + | LBRACE RBRACE + ; +switch_block_statement_groups ::= + switch_block_statement_group + | switch_block_statement_groups switch_block_statement_group + ; +switch_block_statement_group ::= + switch_labels block_statements + ; +switch_labels ::= + switch_label + | switch_labels switch_label + ; +switch_label ::= + CASE constant_expression COLON + | DEFAULT COLON + ; + +while_statement ::= + WHILE LPAREN expression RPAREN statement + ; +while_statement_no_short_if ::= + WHILE LPAREN expression RPAREN statement_no_short_if + ; +do_statement ::= + DO statement WHILE LPAREN expression RPAREN SEMICOLON + ; +for_statement ::= + FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON + for_update_opt RPAREN statement + ; +for_statement_no_short_if ::= + FOR LPAREN for_init_opt SEMICOLON expression_opt SEMICOLON + for_update_opt RPAREN statement_no_short_if + ; +for_init_opt ::= + | for_init + ; +for_init ::= statement_expression_list + | local_variable_declaration + ; +for_update_opt ::= + | for_update + ; +for_update ::= statement_expression_list + ; +statement_expression_list ::= + statement_expression + | statement_expression_list COMMA statement_expression + ; + +identifier_opt ::= + | IDENTIFIER + ; + +break_statement ::= + BREAK identifier_opt SEMICOLON + ; + +continue_statement ::= + CONTINUE identifier_opt SEMICOLON + ; +return_statement ::= + RETURN expression_opt SEMICOLON + ; +throw_statement ::= + THROW expression SEMICOLON + ; +synchronized_statement ::= + SYNCHRONIZED LPAREN expression RPAREN block + ; +try_statement ::= + TRY block catches + | TRY block catches_opt finally + ; +catches_opt ::= + | catches + ; +catches ::= catch_clause + | catches catch_clause + ; +catch_clause ::= + CATCH LPAREN formal_parameter RPAREN block + ; +finally ::= FINALLY block + ; + +// 19.12) Expressions +primary ::= primary_no_new_array + | array_creation_expression + ; +primary_no_new_array ::= + literal + | THIS + | LPAREN expression RPAREN + | class_instance_creation_expression + | field_access + | method_invocation + | array_access + | primitive_type DOT CLASS + | VOID DOT CLASS + | array_type DOT CLASS + | name DOT CLASS + | name DOT THIS + ; +class_instance_creation_expression ::= + NEW class_type LPAREN argument_list_opt RPAREN + | NEW class_type LPAREN argument_list_opt RPAREN class_body + | primary DOT NEW IDENTIFIER + LPAREN argument_list_opt RPAREN + | primary DOT NEW IDENTIFIER + LPAREN argument_list_opt RPAREN class_body + ; +argument_list_opt ::= + | argument_list + ; +argument_list ::= + expression + | argument_list COMMA expression + ; +array_creation_expression ::= + NEW primitive_type dim_exprs dims_opt + | NEW class_or_interface_type dim_exprs dims_opt + | NEW primitive_type dims array_initializer + | NEW class_or_interface_type dims array_initializer + ; +dim_exprs ::= dim_expr + | dim_exprs dim_expr + ; +dim_expr ::= LBRACK expression RBRACK + ; +dims_opt ::= + | dims + ; +dims ::= LBRACK RBRACK + | dims LBRACK RBRACK + ; +field_access ::= + primary DOT IDENTIFIER + | SUPER DOT IDENTIFIER + | name DOT SUPER DOT IDENTIFIER + ; +method_invocation ::= + name LPAREN argument_list_opt RPAREN + | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN + | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN + | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN + ; +array_access ::= + name LBRACK expression RBRACK + | primary_no_new_array LBRACK expression RBRACK + ; +postfix_expression ::= + primary + | name + | postincrement_expression + | postdecrement_expression + ; +postincrement_expression ::= + postfix_expression PLUSPLUS + ; +postdecrement_expression ::= + postfix_expression MINUSMINUS + ; +unary_expression ::= + preincrement_expression + | predecrement_expression + | PLUS unary_expression + | MINUS unary_expression + | unary_expression_not_plus_minus + ; +preincrement_expression ::= + PLUSPLUS unary_expression + ; +predecrement_expression ::= + MINUSMINUS unary_expression + ; +unary_expression_not_plus_minus ::= + postfix_expression + | COMP unary_expression + | NOT unary_expression + | cast_expression + ; +cast_expression ::= + LPAREN primitive_type dims_opt RPAREN unary_expression + | LPAREN expression RPAREN unary_expression_not_plus_minus + | LPAREN name dims RPAREN unary_expression_not_plus_minus + ; +multiplicative_expression ::= + unary_expression + | multiplicative_expression MULT unary_expression + | multiplicative_expression DIV unary_expression + | multiplicative_expression MOD unary_expression + ; +additive_expression ::= + multiplicative_expression + | additive_expression PLUS multiplicative_expression + | additive_expression MINUS multiplicative_expression + ; +shift_expression ::= + additive_expression + | shift_expression LSHIFT additive_expression + | shift_expression RSHIFT additive_expression + | shift_expression URSHIFT additive_expression + ; +relational_expression ::= + shift_expression + | relational_expression LT shift_expression + | relational_expression GT shift_expression + | relational_expression LTEQ shift_expression + | relational_expression GTEQ shift_expression + | relational_expression INSTANCEOF reference_type + ; +equality_expression ::= + relational_expression + | equality_expression EQEQ relational_expression + | equality_expression NOTEQ relational_expression + ; +and_expression ::= + equality_expression + | and_expression AND equality_expression + ; +exclusive_or_expression ::= + and_expression + | exclusive_or_expression XOR and_expression + ; +inclusive_or_expression ::= + exclusive_or_expression + | inclusive_or_expression OR exclusive_or_expression + ; +conditional_and_expression ::= + inclusive_or_expression + | conditional_and_expression ANDAND inclusive_or_expression + ; +conditional_or_expression ::= + conditional_and_expression + | conditional_or_expression OROR conditional_and_expression + ; +conditional_expression ::= + conditional_or_expression + | conditional_or_expression QUESTION expression + COLON conditional_expression + ; +assignment_expression ::= + conditional_expression + | assignment + ; +assignment ::= left_hand_side assignment_operator assignment_expression + ; +left_hand_side ::= + name + | field_access + | array_access + ; +assignment_operator ::= + EQ + | MULTEQ + | DIVEQ + | MODEQ + | PLUSEQ + | MINUSEQ + | LSHIFTEQ + | RSHIFTEQ + | URSHIFTEQ + | ANDEQ + | XOREQ + | OREQ + ; +expression_opt ::= + | expression + ; +expression ::= assignment_expression + ; +constant_expression ::= + expression + ; diff --git a/tools/lexer/jflex-1.4/examples/java/lexer-output.good b/tools/lexer/jflex-1.4/examples/java/lexer-output.good new file mode 100644 index 000000000000..d6d9af33c3d4 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/lexer-output.good @@ -0,0 +1,376 @@ +Lexing [TestLexer.java] +line:20 col:1 --import--IMPORT-- +token: line 20, column 1, sym: 23 +line:20 col:8 --java--IDENTIFIER-- +token: line 20, column 8, sym: 98, value: 'java' +line:20 col:12 --.--DOT-- +token: line 20, column 12, sym: 12 +line:20 col:13 --io--IDENTIFIER-- +token: line 20, column 13, sym: 98, value: 'io' +line:20 col:15 --.--DOT-- +token: line 20, column 15, sym: 12 +line:20 col:16 --*--MULT-- +token: line 20, column 16, sym: 14 +line:20 col:17 --;--SEMICOLON-- +token: line 20, column 17, sym: 13 +line:21 col:1 --import--IMPORT-- +token: line 21, column 1, sym: 23 +line:21 col:8 --java_cup--IDENTIFIER-- +token: line 21, column 8, sym: 98, value: 'java_cup' +line:21 col:16 --.--DOT-- +token: line 21, column 16, sym: 12 +line:21 col:17 --runtime--IDENTIFIER-- +token: line 21, column 17, sym: 98, value: 'runtime' +line:21 col:24 --.--DOT-- +token: line 21, column 24, sym: 12 +line:21 col:25 --Symbol--IDENTIFIER-- +token: line 21, column 25, sym: 98, value: 'Symbol' +line:21 col:31 --;--SEMICOLON-- +token: line 21, column 31, sym: 13 +line:29 col:1 --public--PUBLIC-- +token: line 29, column 1, sym: 24 +line:29 col:8 --class--CLASS-- +token: line 29, column 8, sym: 34 +line:29 col:14 --TestLexer--IDENTIFIER-- +token: line 29, column 14, sym: 98, value: 'TestLexer' +line:29 col:24 --{--LBRACE-- +token: line 29, column 24, sym: 16 +line:32 col:3 --int--INT-- +token: line 32, column 3, sym: 5 +line:32 col:7 --intDec--IDENTIFIER-- +token: line 32, column 7, sym: 98, value: 'intDec' +line:32 col:14 --=--EQ-- +token: line 32, column 14, sym: 18 +line:32 col:16 --37--INTEGER_LITERAL-- +token: line 32, column 16, sym: 93, value: '37' +line:32 col:18 --;--SEMICOLON-- +token: line 32, column 18, sym: 13 +line:33 col:3 --long--LONG-- +token: line 33, column 3, sym: 6 +line:33 col:8 --longDec--IDENTIFIER-- +token: line 33, column 8, sym: 98, value: 'longDec' +line:33 col:16 --=--EQ-- +token: line 33, column 16, sym: 18 +line:33 col:18 --37l--INTEGER_LITERAL-- +token: line 33, column 18, sym: 93, value: '37' +line:33 col:21 --;--SEMICOLON-- +token: line 33, column 21, sym: 13 +line:34 col:3 --int--INT-- +token: line 34, column 3, sym: 5 +line:34 col:7 --intHex--IDENTIFIER-- +token: line 34, column 7, sym: 98, value: 'intHex' +line:34 col:14 --=--EQ-- +token: line 34, column 14, sym: 18 +line:34 col:16 --0x0001--INTEGER_LITERAL-- +token: line 34, column 16, sym: 93, value: '1' +line:34 col:22 --;--SEMICOLON-- +token: line 34, column 22, sym: 13 +line:35 col:3 --long--LONG-- +token: line 35, column 3, sym: 6 +line:35 col:8 --longHex--IDENTIFIER-- +token: line 35, column 8, sym: 98, value: 'longHex' +line:35 col:16 --=--EQ-- +token: line 35, column 16, sym: 18 +line:35 col:18 --0xFFFFl--INTEGER_LITERAL-- +token: line 35, column 18, sym: 93, value: '65535' +line:35 col:25 --;--SEMICOLON-- +token: line 35, column 25, sym: 13 +line:36 col:3 --int--INT-- +token: line 36, column 3, sym: 5 +line:36 col:7 --intOct--IDENTIFIER-- +token: line 36, column 7, sym: 98, value: 'intOct' +line:36 col:14 --=--EQ-- +token: line 36, column 14, sym: 18 +line:36 col:16 --0377--INTEGER_LITERAL-- +token: line 36, column 16, sym: 93, value: '255' +line:36 col:20 --;--SEMICOLON-- +token: line 36, column 20, sym: 13 +line:37 col:3 --long--LONG-- +token: line 37, column 3, sym: 6 +line:37 col:8 --longOc--IDENTIFIER-- +token: line 37, column 8, sym: 98, value: 'longOc' +line:37 col:15 --=--EQ-- +token: line 37, column 15, sym: 18 +line:37 col:17 --007l--INTEGER_LITERAL-- +token: line 37, column 17, sym: 93, value: '7' +line:37 col:21 --;--SEMICOLON-- +token: line 37, column 21, sym: 13 +line:40 col:3 --public--PUBLIC-- +token: line 40, column 3, sym: 24 +line:40 col:10 --static--STATIC-- +token: line 40, column 10, sym: 27 +line:40 col:17 --void--VOID-- +token: line 40, column 17, sym: 37 +line:40 col:22 --main--IDENTIFIER-- +token: line 40, column 22, sym: 98, value: 'main' +line:40 col:26 --(--LPAREN-- +token: line 40, column 26, sym: 19 +line:40 col:27 --String--IDENTIFIER-- +token: line 40, column 27, sym: 98, value: 'String' +line:40 col:34 --argv--IDENTIFIER-- +token: line 40, column 34, sym: 98, value: 'argv' +line:40 col:38 --[--LBRACK-- +token: line 40, column 38, sym: 10 +line:40 col:39 --]--RBRACK-- +token: line 40, column 39, sym: 11 +line:40 col:40 --)--RPAREN-- +token: line 40, column 40, sym: 20 +line:40 col:42 --{--LBRACE-- +token: line 40, column 42, sym: 16 +line:42 col:5 --for--FOR-- +token: line 42, column 5, sym: 49 +line:42 col:9 --(--LPAREN-- +token: line 42, column 9, sym: 19 +line:42 col:10 --int--INT-- +token: line 42, column 10, sym: 5 +line:42 col:14 --i--IDENTIFIER-- +token: line 42, column 14, sym: 98, value: 'i' +line:42 col:16 --=--EQ-- +token: line 42, column 16, sym: 18 +line:42 col:18 --0--INTEGER_LITERAL-- +token: line 42, column 18, sym: 93, value: '0' +line:42 col:19 --;--SEMICOLON-- +token: line 42, column 19, sym: 13 +line:42 col:21 --i--IDENTIFIER-- +token: line 42, column 21, sym: 98, value: 'i' +line:42 col:23 --<--LT-- +token: line 42, column 23, sym: 69 +line:42 col:25 --argv--IDENTIFIER-- +token: line 42, column 25, sym: 98, value: 'argv' +line:42 col:29 --.--DOT-- +token: line 42, column 29, sym: 12 +line:42 col:30 --length--IDENTIFIER-- +token: line 42, column 30, sym: 98, value: 'length' +line:42 col:36 --;--SEMICOLON-- +token: line 42, column 36, sym: 13 +line:42 col:38 --i--IDENTIFIER-- +token: line 42, column 38, sym: 98, value: 'i' +line:42 col:39 --++--PLUSPLUS-- +token: line 42, column 39, sym: 58 +line:42 col:41 --)--RPAREN-- +token: line 42, column 41, sym: 20 +line:42 col:43 --{--LBRACE-- +token: line 42, column 43, sym: 16 +line:43 col:7 --try--TRY-- +token: line 43, column 7, sym: 54 +line:43 col:11 --{--LBRACE-- +token: line 43, column 11, sym: 16 +line:44 col:9 --System--IDENTIFIER-- +token: line 44, column 9, sym: 98, value: 'System' +line:44 col:15 --.--DOT-- +token: line 44, column 15, sym: 12 +line:44 col:16 --out--IDENTIFIER-- +token: line 44, column 16, sym: 98, value: 'out' +line:44 col:19 --.--DOT-- +token: line 44, column 19, sym: 12 +line:44 col:20 --println--IDENTIFIER-- +token: line 44, column 20, sym: 98, value: 'println' +line:44 col:27 --(--LPAREN-- +token: line 44, column 27, sym: 19 +line:44 col:37 --"--STRING_LITERAL-- +token: line 44, column 37, sym: 97, value: 'Lexing [' +line:44 col:38 --+--PLUS-- +token: line 44, column 38, sym: 60 +line:44 col:39 --argv--IDENTIFIER-- +token: line 44, column 39, sym: 98, value: 'argv' +line:44 col:43 --[--LBRACK-- +token: line 44, column 43, sym: 10 +line:44 col:44 --i--IDENTIFIER-- +token: line 44, column 44, sym: 98, value: 'i' +line:44 col:45 --]--RBRACK-- +token: line 44, column 45, sym: 11 +line:44 col:46 --+--PLUS-- +token: line 44, column 46, sym: 60 +line:44 col:49 --"--STRING_LITERAL-- +token: line 44, column 49, sym: 97, value: ']' +line:44 col:50 --)--RPAREN-- +token: line 44, column 50, sym: 20 +line:44 col:51 --;--SEMICOLON-- +token: line 44, column 51, sym: 13 +line:45 col:9 --Scanner--IDENTIFIER-- +token: line 45, column 9, sym: 98, value: 'Scanner' +line:45 col:17 --scanner--IDENTIFIER-- +token: line 45, column 17, sym: 98, value: 'scanner' +line:45 col:25 --=--EQ-- +token: line 45, column 25, sym: 18 +line:45 col:27 --new--NEW-- +token: line 45, column 27, sym: 57 +line:45 col:31 --Scanner--IDENTIFIER-- +token: line 45, column 31, sym: 98, value: 'Scanner' +line:45 col:38 --(--LPAREN-- +token: line 45, column 38, sym: 19 +line:45 col:39 --new--NEW-- +token: line 45, column 39, sym: 57 +line:45 col:43 --UnicodeEscapes--IDENTIFIER-- +token: line 45, column 43, sym: 98, value: 'UnicodeEscapes' +line:45 col:57 --(--LPAREN-- +token: line 45, column 57, sym: 19 +line:45 col:58 --new--NEW-- +token: line 45, column 58, sym: 57 +line:45 col:62 --FileReader--IDENTIFIER-- +token: line 45, column 62, sym: 98, value: 'FileReader' +line:45 col:72 --(--LPAREN-- +token: line 45, column 72, sym: 19 +line:45 col:73 --argv--IDENTIFIER-- +token: line 45, column 73, sym: 98, value: 'argv' +line:45 col:77 --[--LBRACK-- +token: line 45, column 77, sym: 10 +line:45 col:78 --i--IDENTIFIER-- +token: line 45, column 78, sym: 98, value: 'i' +line:45 col:79 --]--RBRACK-- +token: line 45, column 79, sym: 11 +line:45 col:80 --)--RPAREN-- +token: line 45, column 80, sym: 20 +line:45 col:81 --)--RPAREN-- +token: line 45, column 81, sym: 20 +line:45 col:82 --)--RPAREN-- +token: line 45, column 82, sym: 20 +line:45 col:83 --;--SEMICOLON-- +token: line 45, column 83, sym: 13 +line:47 col:9 --Symbol--IDENTIFIER-- +token: line 47, column 9, sym: 98, value: 'Symbol' +line:47 col:16 --s--IDENTIFIER-- +token: line 47, column 16, sym: 98, value: 's' +line:47 col:17 --;--SEMICOLON-- +token: line 47, column 17, sym: 13 +line:48 col:9 --do--DO-- +token: line 48, column 9, sym: 47 +line:48 col:12 --{--LBRACE-- +token: line 48, column 12, sym: 16 +line:49 col:11 --s--IDENTIFIER-- +token: line 49, column 11, sym: 98, value: 's' +line:49 col:13 --=--EQ-- +token: line 49, column 13, sym: 18 +line:49 col:15 --scanner--IDENTIFIER-- +token: line 49, column 15, sym: 98, value: 'scanner' +line:49 col:22 --.--DOT-- +token: line 49, column 22, sym: 12 +line:49 col:23 --debug_next_token--IDENTIFIER-- +token: line 49, column 23, sym: 98, value: 'debug_next_token' +line:49 col:39 --(--LPAREN-- +token: line 49, column 39, sym: 19 +line:49 col:40 --)--RPAREN-- +token: line 49, column 40, sym: 20 +line:49 col:41 --;--SEMICOLON-- +token: line 49, column 41, sym: 13 +line:50 col:11 --System--IDENTIFIER-- +token: line 50, column 11, sym: 98, value: 'System' +line:50 col:17 --.--DOT-- +token: line 50, column 17, sym: 12 +line:50 col:18 --out--IDENTIFIER-- +token: line 50, column 18, sym: 98, value: 'out' +line:50 col:21 --.--DOT-- +token: line 50, column 21, sym: 12 +line:50 col:22 --println--IDENTIFIER-- +token: line 50, column 22, sym: 98, value: 'println' +line:50 col:29 --(--LPAREN-- +token: line 50, column 29, sym: 19 +line:50 col:38 --"--STRING_LITERAL-- +token: line 50, column 38, sym: 97, value: 'token: ' +line:50 col:39 --+--PLUS-- +token: line 50, column 39, sym: 60 +line:50 col:40 --s--IDENTIFIER-- +token: line 50, column 40, sym: 98, value: 's' +line:50 col:41 --)--RPAREN-- +token: line 50, column 41, sym: 20 +line:50 col:42 --;--SEMICOLON-- +token: line 50, column 42, sym: 13 +line:51 col:9 --}--RBRACE-- +token: line 51, column 9, sym: 17 +line:51 col:11 --while--WHILE-- +token: line 51, column 11, sym: 48 +line:51 col:17 --(--LPAREN-- +token: line 51, column 17, sym: 19 +line:51 col:18 --s--IDENTIFIER-- +token: line 51, column 18, sym: 98, value: 's' +line:51 col:19 --.--DOT-- +token: line 51, column 19, sym: 12 +line:51 col:20 --sym--IDENTIFIER-- +token: line 51, column 20, sym: 98, value: 'sym' +line:51 col:24 --!=--NOTEQ-- +token: line 51, column 24, sym: 75 +line:51 col:27 --sym--IDENTIFIER-- +token: line 51, column 27, sym: 98, value: 'sym' +line:51 col:30 --.--DOT-- +token: line 51, column 30, sym: 12 +line:51 col:31 --EOF--IDENTIFIER-- +token: line 51, column 31, sym: 98, value: 'EOF' +line:51 col:34 --)--RPAREN-- +token: line 51, column 34, sym: 20 +line:51 col:35 --;--SEMICOLON-- +token: line 51, column 35, sym: 13 +line:53 col:9 --System--IDENTIFIER-- +token: line 53, column 9, sym: 98, value: 'System' +line:53 col:15 --.--DOT-- +token: line 53, column 15, sym: 12 +line:53 col:16 --out--IDENTIFIER-- +token: line 53, column 16, sym: 98, value: 'out' +line:53 col:19 --.--DOT-- +token: line 53, column 19, sym: 12 +line:53 col:20 --println--IDENTIFIER-- +token: line 53, column 20, sym: 98, value: 'println' +line:53 col:27 --(--LPAREN-- +token: line 53, column 27, sym: 19 +line:53 col:39 --"--STRING_LITERAL-- +token: line 53, column 39, sym: 97, value: 'No errors.' +line:53 col:40 --)--RPAREN-- +token: line 53, column 40, sym: 20 +line:53 col:41 --;--SEMICOLON-- +token: line 53, column 41, sym: 13 +line:54 col:7 --}--RBRACE-- +token: line 54, column 7, sym: 17 +line:55 col:7 --catch--CATCH-- +token: line 55, column 7, sym: 55 +line:55 col:13 --(--LPAREN-- +token: line 55, column 13, sym: 19 +line:55 col:14 --Exception--IDENTIFIER-- +token: line 55, column 14, sym: 98, value: 'Exception' +line:55 col:24 --e--IDENTIFIER-- +token: line 55, column 24, sym: 98, value: 'e' +line:55 col:25 --)--RPAREN-- +token: line 55, column 25, sym: 20 +line:55 col:27 --{--LBRACE-- +token: line 55, column 27, sym: 16 +line:56 col:9 --e--IDENTIFIER-- +token: line 56, column 9, sym: 98, value: 'e' +line:56 col:10 --.--DOT-- +token: line 56, column 10, sym: 12 +line:56 col:11 --printStackTrace--IDENTIFIER-- +token: line 56, column 11, sym: 98, value: 'printStackTrace' +line:56 col:26 --(--LPAREN-- +token: line 56, column 26, sym: 19 +line:56 col:27 --System--IDENTIFIER-- +token: line 56, column 27, sym: 98, value: 'System' +line:56 col:33 --.--DOT-- +token: line 56, column 33, sym: 12 +line:56 col:34 --out--IDENTIFIER-- +token: line 56, column 34, sym: 98, value: 'out' +line:56 col:37 --)--RPAREN-- +token: line 56, column 37, sym: 20 +line:56 col:38 --;--SEMICOLON-- +token: line 56, column 38, sym: 13 +line:57 col:9 --System--IDENTIFIER-- +token: line 57, column 9, sym: 98, value: 'System' +line:57 col:15 --.--DOT-- +token: line 57, column 15, sym: 12 +line:57 col:16 --exit--IDENTIFIER-- +token: line 57, column 16, sym: 98, value: 'exit' +line:57 col:20 --(--LPAREN-- +token: line 57, column 20, sym: 19 +line:57 col:21 --1--INTEGER_LITERAL-- +token: line 57, column 21, sym: 93, value: '1' +line:57 col:22 --)--RPAREN-- +token: line 57, column 22, sym: 20 +line:57 col:23 --;--SEMICOLON-- +token: line 57, column 23, sym: 13 +line:58 col:7 --}--RBRACE-- +token: line 58, column 7, sym: 17 +line:59 col:5 --}--RBRACE-- +token: line 59, column 5, sym: 17 +line:60 col:3 --}--RBRACE-- +token: line 60, column 3, sym: 17 +line:61 col:1 --}--RBRACE-- +token: line 61, column 1, sym: 17 +line:62 col:1 ----EOF-- +token: line 62, column 1, sym: 0 +No errors. diff --git a/tools/lexer/jflex-1.4/examples/java/unicode.flex b/tools/lexer/jflex-1.4/examples/java/unicode.flex new file mode 100644 index 000000000000..31af811a72e7 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/java/unicode.flex @@ -0,0 +1,149 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/* §3.3 of the Java Language Specification : + +UnicodeInputCharacter: + + UnicodeEscape + + RawInputCharacter + + UnicodeEscape: + + \ UnicodeMarker HexDigit HexDigit HexDigit HexDigit + + UnicodeMarker: + + u + + UnicodeMarker u + + RawInputCharacter: + + any Unicode character + + HexDigit: one of + + 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F + +only an even number of '\' is eligible to start a Unicode escape sequence + +*/ + +import java.io.*; + +%% + +%public +%final +%class UnicodeEscapes +%extends FilterReader + +%int +%function read + +%switch +%16bit + +UnicodeEscape = {UnicodeMarker} {HexDigit} {4} +UnicodeMarker = "u"+ +HexDigit = [0-9a-fA-F] + +%state DIGITS + +%init{ + super(in); +%init} + +%{ + private boolean even; + + private int value() { + int r = 0; + + for (int k = zzMarkedPos-4; k < zzMarkedPos; k++) { + int c = zzBuffer[k]; + + if (c >= 'a') + c-= 'a'-10; + else if (c >= 'A') + c-= 'A'-10; + else + c-= '0'; + + r <<= 4; + r += c; + } + + return r; + } + + public int read(char cbuf[], int off, int len) throws IOException { + if ( !ready() ) return -1; + + len+= off; + + for (int i=off; i { + \\ { even = false; return '\\'; } + \\ / \\ { even = !even; return '\\'; } + \\ / "u" { + if (even) { + even = false; + return '\\'; + } + else + yybegin(DIGITS); + } + .|\n { return zzBuffer[zzStartRead]; } + + <> { return -1; } +} + + { + {UnicodeEscape} { yybegin(YYINITIAL); return value(); } + .|\n { throw new Error("incorrect Unicode escape"); } + + <> { throw new Error("EOF in Unicode escape"); } +} diff --git a/tools/lexer/jflex-1.4/examples/simple/Makefile b/tools/lexer/jflex-1.4/examples/simple/Makefile new file mode 100644 index 000000000000..d46a13e02feb --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/Makefile @@ -0,0 +1,23 @@ +JAVA=java +JAVAC=javac +JFLEX=jflex +CUP=$(JAVA) java_cup.Main < + +all: test + +test: output.txt + @(diff output.txt output.good && echo "Test OK!") || echo "Test failed!" + +output.txt: Yylex.class test.txt + $(JAVA) Yylex test.txt > output.txt + +Yylex.class: Yylex.java Yytoken.java Utility.java + +%.class: %.java + $(JAVAC) $^ + +Yylex.java: simple.flex + $(JFLEX) simple.flex + +clean: + rm -f Yylex.java output.txt *.class *~ diff --git a/tools/lexer/jflex-1.4/examples/simple/README b/tools/lexer/jflex-1.4/examples/simple/README new file mode 100644 index 000000000000..b050b3e242b1 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/README @@ -0,0 +1,29 @@ +This directory contains a scanner for a toy programming language. + +It is the example from the JLex website with some small modifications, +to make it a bit more readable. + +It does nothing really useful, because there is no parser for the +toy programming language. It's just a demonstatration how a small simple +scanner looks like. + +files: + +YYtoken.java: + the tokens returned by the scanner + +Utility.java: + small class collecting some utility functions + +simple.flex: + the example specification + +test.txt: + sample input + +output.good: + output matching the sample input from test.txt + +Makefile: (for Unix only) + make to generate scanner and run test + make clean to remove generated files diff --git a/tools/lexer/jflex-1.4/examples/simple/Utility.java b/tools/lexer/jflex-1.4/examples/simple/Utility.java new file mode 100644 index 000000000000..889b030531d0 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/Utility.java @@ -0,0 +1,19 @@ +class Utility { + + private static final String errorMsg[] = { + "Error: Unmatched end-of-comment punctuation.", + "Error: Unmatched start-of-comment punctuation.", + "Error: Unclosed string.", + "Error: Illegal character." + }; + + public static final int E_ENDCOMMENT = 0; + public static final int E_STARTCOMMENT = 1; + public static final int E_UNCLOSEDSTR = 2; + public static final int E_UNMATCHED = 3; + + public static void error(int code) { + System.out.println(errorMsg[code]); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/simple/Yytoken.java b/tools/lexer/jflex-1.4/examples/simple/Yytoken.java new file mode 100644 index 000000000000..ed60fb8f10c5 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/Yytoken.java @@ -0,0 +1,24 @@ +class Yytoken { + public int m_index; + public String m_text; + public int m_line; + public int m_charBegin; + public int m_charEnd; + + Yytoken (int index, String text, int line, int charBegin, int charEnd) { + m_index = index; + m_text = text; + m_line = line; + m_charBegin = charBegin; + m_charEnd = charEnd; + } + + public String toString() { + return "Text : "+m_text+ + "\nindex : "+m_index+ + "\nline : "+m_line+ + "\ncBeg. : "+m_charBegin+ + "\ncEnd. : "+m_charEnd; + } +} + diff --git a/tools/lexer/jflex-1.4/examples/simple/output.good b/tools/lexer/jflex-1.4/examples/simple/output.good new file mode 100644 index 000000000000..04599b114d0e --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/output.good @@ -0,0 +1,660 @@ +line: 1 match: --class-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : class +index : 43 +line : 0 +cBeg. : 0 +cEnd. : 5 +line: 1 match: -- -- +action [76] { } +line: 1 match: --Utility-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : Utility +index : 43 +line : 0 +cBeg. : 6 +cEnd. : 13 +line: 1 match: -- -- +action [76] { } +line: 1 match: --{-- +action [36] { return (new Yytoken(7,yytext(),yyline,yychar,yychar+1)); } +Text : { +index : 7 +line : 0 +cBeg. : 14 +cEnd. : 15 +line: 1 match: -- + + -- +action [76] { } +line: 3 match: --private-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : private +index : 43 +line : 2 +cBeg. : 21 +cEnd. : 28 +line: 3 match: -- -- +action [76] { } +line: 3 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 2 +cBeg. : 29 +cEnd. : 35 +line: 3 match: -- -- +action [76] { } +line: 3 match: --final-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : final +index : 43 +line : 2 +cBeg. : 36 +cEnd. : 41 +line: 3 match: -- -- +action [76] { } +line: 3 match: --String-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : String +index : 43 +line : 2 +cBeg. : 42 +cEnd. : 48 +line: 3 match: -- -- +action [76] { } +line: 3 match: --errorMsg-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : errorMsg +index : 43 +line : 2 +cBeg. : 49 +cEnd. : 57 +line: 3 match: --[-- +action [34] { return (new Yytoken(5,yytext(),yyline,yychar,yychar+1)); } +Text : [ +index : 5 +line : 2 +cBeg. : 57 +cEnd. : 58 +line: 3 match: --]-- +action [35] { return (new Yytoken(6,yytext(),yyline,yychar,yychar+1)); } +Text : ] +index : 6 +line : 2 +cBeg. : 58 +cEnd. : 59 +line: 3 match: -- -- +action [76] { } +line: 3 match: --=-- +action [43] { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } +Text : = +index : 14 +line : 2 +cBeg. : 60 +cEnd. : 61 +line: 3 match: -- -- +action [76] { } +line: 3 match: --{-- +action [36] { return (new Yytoken(7,yytext(),yyline,yychar,yychar+1)); } +Text : { +index : 7 +line : 2 +cBeg. : 62 +cEnd. : 63 +line: 3 match: -- + -- +action [76] { } +line: 4 match: --"Error: Unmatched end-of-comment punctuation."-- +action [57] { String str = yytext().substring(1,yylength()-1); + return (new Yytoken(40,str,yyline,yychar,yychar+yylength())); } +Text : Error: Unmatched end-of-comment punctuation. +index : 40 +line : 3 +cBeg. : 68 +cEnd. : 114 +line: 4 match: --,-- +action [29] { return (new Yytoken(0,yytext(),yyline,yychar,yychar+1)); } +Text : , +index : 0 +line : 3 +cBeg. : 114 +cEnd. : 115 +line: 4 match: -- + -- +action [76] { } +line: 5 match: --"Error: Unmatched start-of-comment punctuation."-- +action [57] { String str = yytext().substring(1,yylength()-1); + return (new Yytoken(40,str,yyline,yychar,yychar+yylength())); } +Text : Error: Unmatched start-of-comment punctuation. +index : 40 +line : 4 +cBeg. : 120 +cEnd. : 168 +line: 5 match: --,-- +action [29] { return (new Yytoken(0,yytext(),yyline,yychar,yychar+1)); } +Text : , +index : 0 +line : 4 +cBeg. : 168 +cEnd. : 169 +line: 5 match: -- + -- +action [76] { } +line: 6 match: --"Error: Unclosed string."-- +action [57] { String str = yytext().substring(1,yylength()-1); + return (new Yytoken(40,str,yyline,yychar,yychar+yylength())); } +Text : Error: Unclosed string. +index : 40 +line : 5 +cBeg. : 174 +cEnd. : 199 +line: 6 match: --,-- +action [29] { return (new Yytoken(0,yytext(),yyline,yychar,yychar+1)); } +Text : , +index : 0 +line : 5 +cBeg. : 199 +cEnd. : 200 +line: 6 match: -- + -- +action [76] { } +line: 7 match: --"Error: Illegal character."-- +action [57] { String str = yytext().substring(1,yylength()-1); + return (new Yytoken(40,str,yyline,yychar,yychar+yylength())); } +Text : Error: Illegal character. +index : 40 +line : 6 +cBeg. : 205 +cEnd. : 232 +line: 7 match: -- + -- +action [76] { } +line: 8 match: --}-- +action [37] { return (new Yytoken(8,yytext(),yyline,yychar,yychar+1)); } +Text : } +index : 8 +line : 7 +cBeg. : 237 +cEnd. : 238 +line: 8 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 7 +cBeg. : 238 +cEnd. : 239 +line: 8 match: -- + + -- +action [76] { } +line: 10 match: --public-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : public +index : 43 +line : 9 +cBeg. : 245 +cEnd. : 251 +line: 10 match: -- -- +action [76] { } +line: 10 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 9 +cBeg. : 252 +cEnd. : 258 +line: 10 match: -- -- +action [76] { } +line: 10 match: --final-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : final +index : 43 +line : 9 +cBeg. : 259 +cEnd. : 264 +line: 10 match: -- -- +action [76] { } +line: 10 match: --int-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : int +index : 43 +line : 9 +cBeg. : 265 +cEnd. : 268 +line: 10 match: -- -- +action [76] { } +line: 10 match: --E_ENDCOMMENT-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : E_ENDCOMMENT +index : 43 +line : 9 +cBeg. : 269 +cEnd. : 281 +line: 10 match: -- -- +action [76] { } +line: 10 match: --=-- +action [43] { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } +Text : = +index : 14 +line : 9 +cBeg. : 282 +cEnd. : 283 +line: 10 match: -- -- +action [76] { } +line: 10 match: --0-- +action [68] { return (new Yytoken(42,yytext(),yyline,yychar,yychar+yylength())); } +Text : 0 +index : 42 +line : 9 +cBeg. : 284 +cEnd. : 285 +line: 10 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 9 +cBeg. : 285 +cEnd. : 286 +line: 10 match: -- + -- +action [76] { } +line: 11 match: --public-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : public +index : 43 +line : 10 +cBeg. : 290 +cEnd. : 296 +line: 11 match: -- -- +action [76] { } +line: 11 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 10 +cBeg. : 297 +cEnd. : 303 +line: 11 match: -- -- +action [76] { } +line: 11 match: --final-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : final +index : 43 +line : 10 +cBeg. : 304 +cEnd. : 309 +line: 11 match: -- -- +action [76] { } +line: 11 match: --int-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : int +index : 43 +line : 10 +cBeg. : 310 +cEnd. : 313 +line: 11 match: -- -- +action [76] { } +line: 11 match: --E_STARTCOMMENT-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : E_STARTCOMMENT +index : 43 +line : 10 +cBeg. : 314 +cEnd. : 328 +line: 11 match: -- -- +action [76] { } +line: 11 match: --=-- +action [43] { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } +Text : = +index : 14 +line : 10 +cBeg. : 329 +cEnd. : 330 +line: 11 match: -- -- +action [76] { } +line: 11 match: --1-- +action [68] { return (new Yytoken(42,yytext(),yyline,yychar,yychar+yylength())); } +Text : 1 +index : 42 +line : 10 +cBeg. : 331 +cEnd. : 332 +line: 11 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 10 +cBeg. : 332 +cEnd. : 333 +line: 11 match: -- + -- +action [76] { } +line: 12 match: --public-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : public +index : 43 +line : 11 +cBeg. : 337 +cEnd. : 343 +line: 12 match: -- -- +action [76] { } +line: 12 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 11 +cBeg. : 344 +cEnd. : 350 +line: 12 match: -- -- +action [76] { } +line: 12 match: --final-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : final +index : 43 +line : 11 +cBeg. : 351 +cEnd. : 356 +line: 12 match: -- -- +action [76] { } +line: 12 match: --int-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : int +index : 43 +line : 11 +cBeg. : 357 +cEnd. : 360 +line: 12 match: -- -- +action [76] { } +line: 12 match: --E_UNCLOSEDSTR-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : E_UNCLOSEDSTR +index : 43 +line : 11 +cBeg. : 361 +cEnd. : 374 +line: 12 match: -- -- +action [76] { } +line: 12 match: --=-- +action [43] { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } +Text : = +index : 14 +line : 11 +cBeg. : 375 +cEnd. : 376 +line: 12 match: -- -- +action [76] { } +line: 12 match: --2-- +action [68] { return (new Yytoken(42,yytext(),yyline,yychar,yychar+yylength())); } +Text : 2 +index : 42 +line : 11 +cBeg. : 377 +cEnd. : 378 +line: 12 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 11 +cBeg. : 378 +cEnd. : 379 +line: 12 match: -- + -- +action [76] { } +line: 13 match: --public-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : public +index : 43 +line : 12 +cBeg. : 383 +cEnd. : 389 +line: 13 match: -- -- +action [76] { } +line: 13 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 12 +cBeg. : 390 +cEnd. : 396 +line: 13 match: -- -- +action [76] { } +line: 13 match: --final-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : final +index : 43 +line : 12 +cBeg. : 397 +cEnd. : 402 +line: 13 match: -- -- +action [76] { } +line: 13 match: --int-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : int +index : 43 +line : 12 +cBeg. : 403 +cEnd. : 406 +line: 13 match: -- -- +action [76] { } +line: 13 match: --E_UNMATCHED-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : E_UNMATCHED +index : 43 +line : 12 +cBeg. : 407 +cEnd. : 418 +line: 13 match: -- -- +action [76] { } +line: 13 match: --=-- +action [43] { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } +Text : = +index : 14 +line : 12 +cBeg. : 419 +cEnd. : 420 +line: 13 match: -- -- +action [76] { } +line: 13 match: --3-- +action [68] { return (new Yytoken(42,yytext(),yyline,yychar,yychar+yylength())); } +Text : 3 +index : 42 +line : 12 +cBeg. : 421 +cEnd. : 422 +line: 13 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 12 +cBeg. : 422 +cEnd. : 423 +line: 13 match: -- + + -- +action [76] { } +line: 15 match: --public-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : public +index : 43 +line : 14 +cBeg. : 428 +cEnd. : 434 +line: 15 match: -- -- +action [76] { } +line: 15 match: --static-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : static +index : 43 +line : 14 +cBeg. : 435 +cEnd. : 441 +line: 15 match: -- -- +action [76] { } +line: 15 match: --void-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : void +index : 43 +line : 14 +cBeg. : 442 +cEnd. : 446 +line: 15 match: -- -- +action [76] { } +line: 15 match: --error-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : error +index : 43 +line : 14 +cBeg. : 447 +cEnd. : 452 +line: 15 match: --(-- +action [32] { return (new Yytoken(3,yytext(),yyline,yychar,yychar+1)); } +Text : ( +index : 3 +line : 14 +cBeg. : 452 +cEnd. : 453 +line: 15 match: --int-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : int +index : 43 +line : 14 +cBeg. : 453 +cEnd. : 456 +line: 15 match: -- -- +action [76] { } +line: 15 match: --code-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : code +index : 43 +line : 14 +cBeg. : 457 +cEnd. : 461 +line: 15 match: --)-- +action [33] { return (new Yytoken(4,yytext(),yyline,yychar,yychar+1)); } +Text : ) +index : 4 +line : 14 +cBeg. : 461 +cEnd. : 462 +line: 15 match: -- -- +action [76] { } +line: 15 match: --{-- +action [36] { return (new Yytoken(7,yytext(),yyline,yychar,yychar+1)); } +Text : { +index : 7 +line : 14 +cBeg. : 463 +cEnd. : 464 +line: 15 match: -- + -- +action [76] { } +line: 16 match: --System-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : System +index : 43 +line : 15 +cBeg. : 468 +cEnd. : 474 +line: 16 match: --.-- +action [38] { return (new Yytoken(9,yytext(),yyline,yychar,yychar+1)); } +Text : . +index : 9 +line : 15 +cBeg. : 474 +cEnd. : 475 +line: 16 match: --out-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : out +index : 43 +line : 15 +cBeg. : 475 +cEnd. : 478 +line: 16 match: --.-- +action [38] { return (new Yytoken(9,yytext(),yyline,yychar,yychar+1)); } +Text : . +index : 9 +line : 15 +cBeg. : 478 +cEnd. : 479 +line: 16 match: --println-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : println +index : 43 +line : 15 +cBeg. : 479 +cEnd. : 486 +line: 16 match: --(-- +action [32] { return (new Yytoken(3,yytext(),yyline,yychar,yychar+1)); } +Text : ( +index : 3 +line : 15 +cBeg. : 486 +cEnd. : 487 +line: 16 match: --errorMsg-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : errorMsg +index : 43 +line : 15 +cBeg. : 487 +cEnd. : 495 +line: 16 match: --[-- +action [34] { return (new Yytoken(5,yytext(),yyline,yychar,yychar+1)); } +Text : [ +index : 5 +line : 15 +cBeg. : 495 +cEnd. : 496 +line: 16 match: --code-- +action [70] { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +Text : code +index : 43 +line : 15 +cBeg. : 496 +cEnd. : 500 +line: 16 match: --]-- +action [35] { return (new Yytoken(6,yytext(),yyline,yychar,yychar+1)); } +Text : ] +index : 6 +line : 15 +cBeg. : 500 +cEnd. : 501 +line: 16 match: --)-- +action [33] { return (new Yytoken(4,yytext(),yyline,yychar,yychar+1)); } +Text : ) +index : 4 +line : 15 +cBeg. : 501 +cEnd. : 502 +line: 16 match: --;-- +action [31] { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } +Text : ; +index : 2 +line : 15 +cBeg. : 502 +cEnd. : 503 +line: 16 match: -- + -- +action [76] { } +line: 17 match: --}-- +action [37] { return (new Yytoken(8,yytext(),yyline,yychar,yychar+1)); } +Text : } +index : 8 +line : 16 +cBeg. : 506 +cEnd. : 507 +line: 17 match: -- +-- +action [76] { } +line: 18 match: --}-- +action [37] { return (new Yytoken(8,yytext(),yyline,yychar,yychar+1)); } +Text : } +index : 8 +line : 17 +cBeg. : 508 +cEnd. : 509 +line: 18 match: -- + +-- +action [76] { } +null diff --git a/tools/lexer/jflex-1.4/examples/simple/simple.flex b/tools/lexer/jflex-1.4/examples/simple/simple.flex new file mode 100644 index 000000000000..790133952271 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/simple.flex @@ -0,0 +1,86 @@ +/* this is the scanner example from the JLex website + (with small modifications to make it more readable) */ + +%% + +%{ + private int comment_count = 0; +%} + +%line +%char +%state COMMENT +%full + +%debug + +ALPHA=[A-Za-z] +DIGIT=[0-9] +NONNEWLINE_WHITE_SPACE_CHAR=[\ \t\b\012] +NEWLINE=\r|\n|\r\n +WHITE_SPACE_CHAR=[\n\r\ \t\b\012] +STRING_TEXT=(\\\"|[^\n\r\"]|\\{WHITE_SPACE_CHAR}+\\)* +COMMENT_TEXT=([^*/\n]|[^*\n]"/"[^*\n]|[^/\n]"*"[^/\n]|"*"[^/\n]|"/"[^*\n])* +Ident = {ALPHA}({ALPHA}|{DIGIT}|_)* + +%% + + { + "," { return (new Yytoken(0,yytext(),yyline,yychar,yychar+1)); } + ":" { return (new Yytoken(1,yytext(),yyline,yychar,yychar+1)); } + ";" { return (new Yytoken(2,yytext(),yyline,yychar,yychar+1)); } + "(" { return (new Yytoken(3,yytext(),yyline,yychar,yychar+1)); } + ")" { return (new Yytoken(4,yytext(),yyline,yychar,yychar+1)); } + "[" { return (new Yytoken(5,yytext(),yyline,yychar,yychar+1)); } + "]" { return (new Yytoken(6,yytext(),yyline,yychar,yychar+1)); } + "{" { return (new Yytoken(7,yytext(),yyline,yychar,yychar+1)); } + "}" { return (new Yytoken(8,yytext(),yyline,yychar,yychar+1)); } + "." { return (new Yytoken(9,yytext(),yyline,yychar,yychar+1)); } + "+" { return (new Yytoken(10,yytext(),yyline,yychar,yychar+1)); } + "-" { return (new Yytoken(11,yytext(),yyline,yychar,yychar+1)); } + "*" { return (new Yytoken(12,yytext(),yyline,yychar,yychar+1)); } + "/" { return (new Yytoken(13,yytext(),yyline,yychar,yychar+1)); } + "=" { return (new Yytoken(14,yytext(),yyline,yychar,yychar+1)); } + "<>" { return (new Yytoken(15,yytext(),yyline,yychar,yychar+2)); } + "<" { return (new Yytoken(16,yytext(),yyline,yychar,yychar+1)); } + "<=" { return (new Yytoken(17,yytext(),yyline,yychar,yychar+2)); } + ">" { return (new Yytoken(18,yytext(),yyline,yychar,yychar+1)); } + ">=" { return (new Yytoken(19,yytext(),yyline,yychar,yychar+2)); } + "&" { return (new Yytoken(20,yytext(),yyline,yychar,yychar+1)); } + "|" { return (new Yytoken(21,yytext(),yyline,yychar,yychar+1)); } + ":=" { return (new Yytoken(22,yytext(),yyline,yychar,yychar+2)); } + + {NONNEWLINE_WHITE_SPACE_CHAR}+ { } + + "/*" { yybegin(COMMENT); comment_count++; } + + \"{STRING_TEXT}\" { + String str = yytext().substring(1,yylength()-1); + return (new Yytoken(40,str,yyline,yychar,yychar+yylength())); + } + + \"{STRING_TEXT} { + String str = yytext().substring(1,yytext().length()); + Utility.error(Utility.E_UNCLOSEDSTR); + return (new Yytoken(41,str,yyline,yychar,yychar + str.length())); + } + + {DIGIT}+ { return (new Yytoken(42,yytext(),yyline,yychar,yychar+yylength())); } + + {Ident} { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); } +} + + { + "/*" { comment_count++; } + "*/" { if (--comment_count == 0) yybegin(YYINITIAL); } + {COMMENT_TEXT} { } +} + + +{NEWLINE} { } + +. { + System.out.println("Illegal character: <" + yytext() + ">"); + Utility.error(Utility.E_UNMATCHED); +} + diff --git a/tools/lexer/jflex-1.4/examples/simple/test.txt b/tools/lexer/jflex-1.4/examples/simple/test.txt new file mode 100644 index 000000000000..889b030531d0 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/simple/test.txt @@ -0,0 +1,19 @@ +class Utility { + + private static final String errorMsg[] = { + "Error: Unmatched end-of-comment punctuation.", + "Error: Unmatched start-of-comment punctuation.", + "Error: Unclosed string.", + "Error: Illegal character." + }; + + public static final int E_ENDCOMMENT = 0; + public static final int E_STARTCOMMENT = 1; + public static final int E_UNCLOSEDSTR = 2; + public static final int E_UNMATCHED = 3; + + public static void error(int code) { + System.out.println(errorMsg[code]); + } +} + diff --git a/tools/lexer/jflex-1.4/examples/standalone/Makefile b/tools/lexer/jflex-1.4/examples/standalone/Makefile new file mode 100644 index 000000000000..c9a9ab6951f7 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/standalone/Makefile @@ -0,0 +1,13 @@ +all: run + +run: Subst.class + java Subst sample.inp + +Subst.class: Subst.java + javac Subst.java + +Subst.java: standalone.flex + jflex standalone.flex + +clean: + rm -rf *.class *~ *.java diff --git a/tools/lexer/jflex-1.4/examples/standalone/README b/tools/lexer/jflex-1.4/examples/standalone/README new file mode 100644 index 000000000000..1be85a86998f --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/standalone/README @@ -0,0 +1,20 @@ +This is a small example of a standalone text substitution scanner. + +It reads a name after the keyword name and replaces all occurences +of "hello" by "hello !". + +sample.inp + contains a sample input for the scanner + +standalone.flex + the lexical specification for the scanner + +build.xml + ant build file + +to run the example use ant or type: + +jflex standalone.flex +javac Subst.java +java Subst sample.inp + diff --git a/tools/lexer/jflex-1.4/examples/standalone/build.xml b/tools/lexer/jflex-1.4/examples/standalone/build.xml new file mode 100644 index 000000000000..3d8bae7ca2a5 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/standalone/build.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/lexer/jflex-1.4/examples/standalone/sample.inp b/tools/lexer/jflex-1.4/examples/standalone/sample.inp new file mode 100644 index 000000000000..550ac7373812 --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/standalone/sample.inp @@ -0,0 +1,8 @@ +name someone + +Hello +This is a sample input file for the +standalone example scanner. + +Have a nice day! + diff --git a/tools/lexer/jflex-1.4/examples/standalone/standalone.flex b/tools/lexer/jflex-1.4/examples/standalone/standalone.flex new file mode 100644 index 000000000000..0c7e12f94d8f --- /dev/null +++ b/tools/lexer/jflex-1.4/examples/standalone/standalone.flex @@ -0,0 +1,44 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +/** + This is a small example of a standalone text substitution scanner + It reads a name after the keyword name and substitutes all occurences + of "hello" with "hello !". There is a sample input file + "sample.inp" provided in this directory +*/ + +%% + +%public +%class Subst +%standalone + +%unicode + +%{ + String name; +%} + +%% + +"name " [a-zA-Z]+ { name = yytext().substring(5); } +[Hh] "ello" { System.out.print(yytext()+" "+name+"!"); } + diff --git a/tools/lexer/jflex-1.4/lib/JFlex.jar b/tools/lexer/jflex-1.4/lib/JFlex.jar new file mode 100644 index 000000000000..ac5ec6e9f4a9 Binary files /dev/null and b/tools/lexer/jflex-1.4/lib/JFlex.jar differ diff --git a/tools/lexer/jflex-1.4/lib/jflex-mode.el b/tools/lexer/jflex-1.4/lib/jflex-mode.el new file mode 100644 index 000000000000..4149b04d9830 --- /dev/null +++ b/tools/lexer/jflex-1.4/lib/jflex-mode.el @@ -0,0 +1,114 @@ +; -*- Mode: Emacs-Lisp; -*- + +;;; jflex-mode + +;;; author: Gerwin Klein +;;; $Revision: 2.1 $, $Date: 2003/06/08 11:01:12 $ + +(require 'derived) +(require 'font-lock) + +(define-derived-mode jflex-mode java-mode "JFlex" + "Major mode for editing JFlex files" + + ;; set the indentation + (setq c-basic-offset 2) + + (c-set-offset 'knr-argdecl-intro 0) + (c-set-offset 'topmost-intro-cont 0) + + ;; remove auto and hungry anything + (c-toggle-auto-hungry-state -1) + (c-toggle-auto-state -1) + (c-toggle-hungry-state -1) + + (use-local-map jflex-mode-map) + + ;; get rid of that damn electric-brace + (define-key jflex-mode-map "{" 'self-insert-command) + (define-key jflex-mode-map "}" 'self-insert-command) + + (define-key jflex-mode-map [tab] 'jflex-indent-command) + + ) + +(defalias 'jflex-indent-command 'c-indent-command) + +(defconst jflex-font-lock-keywords + (append + '( + ("^%%" . font-lock-reference-face) + "^%{" + "^%init{" + "^%initthrow{" + "^%eof{" + "^%eofthrow{" + "^%yylexthrow{" + "^%eofval{" + "^%}" + "^%init}" + "^%initthrow}" + "^%eof}" + "^%eofthrow}" + "^%yylexthrow}" + "^%eofval}" + "^%standalone" + "^%scanerror" + "^%switch" + "^%states" ; fixme: state identifiers + "^%state" + "^%s" + "^%xstates" + "^%xstate" + "^%x" + "^%char" + "^%line" + "^%column" + "^%byaccj" + "^%cupsym" + "^%cupdebug" + "^%cup" + "^%eofclose" + "^%class" + "^%function" + "^%type" + "^%integer" + "^%intwrap" + "^%int" + "^%yyeof" + "^%notunix" + "^%7bit" + "^%full" + "^%8bit" + "^%unicode" + "^%16bit" + "^%caseless" + "^%ignorecase" + "^%implements" + "^%extends" + "^%public" + "^%apiprivate" + "^%final" + "^%abstract" + "^%debug" + "^%table" + "^%pack" + "^%include" + "^%buffer" + "^%initthrow" + "^%eofthrow" + "^%yylexthrow" + "^%throws" + ("%[%{}0-9a-zA-Z]+" . font-lock-warning-face) ; errors + ("{[ \t]*[a-zA-Z][0-9a-zA-Z_]+[ \t]*}" . font-lock-variable-name-face) ; macro uses + "<>" ; special <> symbol + ("<[ \t]*[a-zA-Z][0-9a-zA-Z_]+[ \t]*\\(,[ \t]*[a-zA-Z][0-9a-zA-Z_]+[ \t]*\\)*>" . font-lock-type-face) ; lex state list + ) + java-font-lock-keywords-2) + "JFlex keywords for font-lock mode") + +(put 'jflex-mode 'font-lock-defaults + '(jflex-font-lock-keywords + nil nil ((?_ . "w")) beginning-of-defun)) + +(provide 'jflex-mode) diff --git a/tools/lexer/jflex-1.4/lib/jflex.vim b/tools/lexer/jflex-1.4/lib/jflex.vim new file mode 100644 index 000000000000..a6b5c3c40d41 --- /dev/null +++ b/tools/lexer/jflex-1.4/lib/jflex.vim @@ -0,0 +1,149 @@ +" Vim syntax file +" Language: JFlex +" Maintainer: Gerwin Klein +" Last Change: $Revision: 2.1 $, $Date: 2003/06/08 11:01:12 $ + +" Thanks to Michael Brailsford for help and suggestions + +" Quit when a syntax file was already loaded {{{ +if exists("b:current_syntax") + finish +endif +"}}} + +" Include java syntax {{{ +if version >= 600 + runtime! syntax/java.vim + unlet b:current_syntax +else + so $VIMRUNTIME/syntax/java.vim +endif +"}}} + +syn cluster jflexOptions contains=jflexOption,jflexCodeInclude,jflexComment,jflexMacroIdent,jflexMacroRegExp,jflexOptionError +syn cluster jflexRules contains=jflexRule,jflexComment,jflexActionCode,jflexRuleStates,jflexRegExp + +" java code section +syn region jflexStart start="/\*\|//\|import\|package\|class"me=s end="^%%"me=e-2 contains=@javaTop nextgroup=jflexOptionReg + +" %% +" options +syn region jflexOptionReg matchgroup=jflexSectionSep start="^%%" end="^%%"me=e-2 contains=@jflexOptions nextgroup=jflexRulesReg + +syn match jflexOptionError "%\i*" contained + +syn match jflexOption "^\(%s\|%x\)" contained +syn match jflexOption "^%state" contained +syn match jflexOption "^%states" contained +syn match jflexOption "^%xstate" contained +syn match jflexOption "^%xstates" contained +syn match jflexOption "^%char" contained +syn match jflexOption "^%line" contained +syn match jflexOption "^%column" contained +syn match jflexOption "^%byaccj" contained +syn match jflexOption "^%cup" contained +syn match jflexOption "^%cupsym" contained +syn match jflexOption "^%cupdebug" contained +syn match jflexOption "^%eofclose" contained +syn match jflexOption "^%class" contained +syn match jflexOption "^%function" contained +syn match jflexOption "^%type" contained +syn match jflexOption "^%integer" contained +syn match jflexOption "^%int" contained +syn match jflexOption "^%intwrap" contained +syn match jflexOption "^%yyeof" contained +syn match jflexOption "^%notunix" contained +syn match jflexOption "^%7bit" contained +syn match jflexOption "^%8bit" contained +syn match jflexOption "^%full" contained +syn match jflexOption "^%16bit" contained +syn match jflexOption "^%unicode" contained +syn match jflexOption "^%caseless" contained +syn match jflexOption "^%ignorecase" contained +syn match jflexOption "^%implements" contained +syn match jflexOption "^%extends" contained +syn match jflexOption "^%public" contained +syn match jflexOption "^%apiprivate" contained +syn match jflexOption "^%final" contained +syn match jflexOption "^%abstract" contained +syn match jflexOption "^%debug" contained +syn match jflexOption "^%standalone" contained +syn match jflexOption "^%switch" contained +syn match jflexOption "^%table" contained +syn match jflexOption "^%pack" contained +syn match jflexOption "^%include" contained +syn match jflexOption "^%buffer" contained +syn match jflexOption "^%initthrow" contained +syn match jflexOption "^%eofthrow" contained +syn match jflexOption "^%yylexthrow" contained +syn match jflexOption "^%throws" contained +syn match jflexOption "^%scannerror" contained + +syn match jflexMacroIdent "\I\i*\s*="me=e-1 contained nextgroup=jflexMacroRegExp + +syn region jflexMacroRegExp matchgroup=jflexOperator start="=" end="^\(%\|\I\|\i\|/\)"me=e-1 contains=NONE contained + +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%{" end="^%}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%init{" end="^%init}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%initthrow{" end="^%initthrow}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%eof{" end="^%eof}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%eofthrow{" end="^%eofthrow}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%yylexthrow{" end="^%yylexthrow}" contains=@javaTop contained +syn region jflexCodeInclude matchgroup=jflexCodeIncludeMark start="^%eofval{" end="^%eofval}" contains=@javaTop contained + +" rules (end pattern shouldn't occur, if it does anyway we just stay in jflexRulesReg) +syn region jflexRulesReg matchgroup=jflexSectionSep start="^%%" end="^%%"me=e-2 contains=@jflexRules + +" at first everything but strings is a regexp +syn match jflexRegExp "\([^\" \t]\|\\\"\)\+" contained + +" take out comments +syn match jflexComment "//.*" contained +syn region jflexComment start="/\*" end="\*/" contained contains=jflexComment + +" lex states +syn match jflexRuleStates "<\s*\I\i*\(\s*,\s*\I\i*\)*\s*>" contained skipnl skipwhite nextgroup=jflexStateGroup + +" action code (only after states braces and macro use) +syn region jflexActionCode matchgroup=Delimiter start="{" end="}" contained contains=@javaTop,jflexJavaBraces + +" macro use +syn match jflexRegExp "{\s*\I\i*\s*}" contained + +" state braces (only active after ) +syn region jflexStateGroup matchgroup=jflexRuleStates start="{$" start="{\s" end="}" contained contains=@jflexRules + +" string +syn region jflexRegExp matchgroup=String start=+"+ skip=+\\\\\|\\"+ end=+"+ contained + +" not to be confused with a state +syn match jflexRegExp "<>" contained + +" escape sequence +syn match jflexRegExp "\\." contained + + +" keep braces in actions balanced +syn region jflexJavaBraces start="{" end="}" contained contains=@javaTop,jflexJavaBraces + + +" syncing +syn sync clear +syn sync minlines=10 +syn sync match jflexSync grouphere jflexOptionReg "^%[a-z]" +syn sync match jflexSync grouphere jflexRulesReg "^<" + + +" highlighting +hi link jflexOption Special +hi link jflexMacroIdent Ident +hi link jflexMacroRegExp Macro +hi link jflexOptionError Error +hi link jflexComment Comment +hi link jflexOperator Operator +hi link jflexRuleStates Special +hi link jflexRegExp Function +hi jflexSectionSep guifg=yellow ctermfg=yellow guibg=blue ctermbg=blue gui=bold cterm=bold +hi link jflexCodeIncludeMark jflexSectionSep + +let b:current_syntax="jflex" diff --git a/tools/lexer/jflex-1.4/src/JFlex/Action.java b/tools/lexer/jflex-1.4/src/JFlex/Action.java new file mode 100644 index 000000000000..de2e9a251096 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Action.java @@ -0,0 +1,149 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Encapsulates an action in the specification. + * + * It stores the Java code as String together with a priority (line number in the specification). + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.6 $, $Date: 2004/11/06 23:03:30 $ + */ +final public class Action { + + + /** + * The Java code this Action represents + */ + String content; + + /** + * The priority (i.e. line number in the specification) of this Action. + */ + int priority; + + /** + * True iff the action belongs to an lookahead expresstion + * (a/b or r$) + */ + private boolean isLookAction; + + + /** + * Creates a new Action object with specified content and line number. + * + * @param content java code + * @param priority line number + */ + public Action(String content, int priority) { + this.content = content.trim(); + this.priority = priority; + } + + + /** + * Compares the priority value of this Action with the specified action. + * + * @param other the other Action to compare this Action with. + * + * @return this Action if it has higher priority - the specified one, if not. + */ + public Action getHigherPriority(Action other) { + if (other == null) return this; + + // the smaller the number the higher the priority + if (other.priority > this.priority) + return this; + else + return other; + } + + + /** + * Returns the String representation of this object. + * + * @return string representation of the action + */ + public String toString() { + return "Action (priority "+priority+", lookahead "+isLookAction+") :"+Out.NL+content; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + + /** + * Returns true iff the parameter is an + * Action with the same content as this one. + * + * @param a the object to compare this Action with + * @return true if the action strings are equal + */ + public boolean isEquiv(Action a) { + return this == a || this.content.equals(a.content); + } + + + /** + * Calculate hash value. + * + * @return a hash value for this Action + */ + public int hashCode() { + return content.hashCode(); + } + + + /** + * Test for equality to another object. + * + * This action equals another object if the other + * object is an equivalent action. + * + * @param o the other object. + * + * @see Action#isEquiv(Action) + */ + public boolean equals(Object o) { + if (o instanceof Action) + return isEquiv((Action) o); + else + return false; + } + + /** + * Return look ahead flag. + * + * @return true if this actions belongs to a lookahead rule + */ + public boolean isLookAction() { + return isLookAction; + } + + /** + * Sets the look ahead flag for this action + * + * @param b set to true if this action belongs to a look ahead rule + */ + public void setLookAction(boolean b) { + isLookAction = b; + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/CharClassException.java b/tools/lexer/jflex-1.4/src/JFlex/CharClassException.java new file mode 100644 index 000000000000..d720cd0bf97a --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CharClassException.java @@ -0,0 +1,49 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + + +/** + * This Exception is used in class CharClasses. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:30 $ + */ +public class CharClassException extends RuntimeException { + + /** + * Creates a new CharClassException without message + */ + public CharClassException() { + } + + + /** + * Creates a new CharClassException with the specified message + * + * @param message the error description presented to the user. + */ + public CharClassException(String message) { + super(message); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/CharClassInterval.java b/tools/lexer/jflex-1.4/src/JFlex/CharClassInterval.java new file mode 100644 index 000000000000..caa6ad4d6eef --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CharClassInterval.java @@ -0,0 +1,73 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +/** + * Stores an interval of characters together with the character class + * + * A character belongs to an interval, if its Unicode value is greater than or equal + * to the Unicode value of start and smaller than or euqal to the Unicode + * value of end. + * + * All characters of the interval must belong to the same character class. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:30 $ + */ +public class CharClassInterval { + + /** + * The first character of the interval + */ + int start; + + /** + * The last character of the interval + */ + int end; + + /** + * The code of the class all characters of this interval belong to. + */ + int charClass; + + + /** + * Creates a new CharClassInterval from start to end + * that belongs to character class charClass. + * + * @param start The first character of the interval + * @param end The last character of the interval + * @param charClass The code of the class all characters of this interval belong to. + */ + public CharClassInterval(int start, int end, int charClass) { + this.start = start; + this.end = end; + this.charClass = charClass; + } + + /** + * returns string representation of this class interval + */ + public String toString() { + return "["+start+"-"+end+"="+charClass+"]"; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/CharClasses.java b/tools/lexer/jflex-1.4/src/JFlex/CharClasses.java new file mode 100644 index 000000000000..01fc24eaa023 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CharClasses.java @@ -0,0 +1,388 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.Vector; + + +/** + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.6 $, $Date: 2004/11/06 23:03:32 $ + */ +public class CharClasses { + + /** debug flag (for char classes only) */ + private static final boolean DEBUG = false; + + /** the largest character that can be used in char classes */ + public static final char maxChar = '\uFFFF'; + + /** the char classes */ + private Vector /* of IntCharSet */ classes; + + /** the largest character actually used in a specification */ + private char maxCharUsed; + + /** + * Constructs a new CharClass object that provides space for + * classes of characters from 0 to maxCharCode. + * + * Initially all characters are in class 0. + * + * @param maxCharCode the last character code to be + * considered. (127 for 7bit Lexers, + * 255 for 8bit Lexers and 0xFFFF + * for Unicode Lexers). + */ + public CharClasses(int maxCharCode) { + if (maxCharCode < 0 || maxCharCode > 0xFFFF) + throw new IllegalArgumentException(); + + maxCharUsed = (char) maxCharCode; + + classes = new Vector(); + classes.addElement(new IntCharSet(new Interval((char) 0, maxChar))); + } + + + /** + * Returns the greatest Unicode value of the current input character set. + */ + public char getMaxCharCode() { + return maxCharUsed; + } + + + /** + * Sets the larges Unicode value of the current input character set. + * + * @param charCode the largest character code, used for the scanner + * (i.e. %7bit, %8bit, %16bit etc.) + */ + public void setMaxCharCode(int charCode) { + if (charCode < 0 || charCode > 0xFFFF) + throw new IllegalArgumentException(); + + maxCharUsed = (char) charCode; + } + + + /** + * Returns the current number of character classes. + */ + public int getNumClasses() { + return classes.size(); + } + + + + /** + * Updates the current partition, so that the specified set of characters + * gets a new character class. + * + * Characters that are elements of set are not in the same + * equivalence class with characters that are not elements of set. + * + * @param set the set of characters to distinguish from the rest + * @param caseless if true upper/lower/title case are considered equivalent + */ + public void makeClass(IntCharSet set, boolean caseless) { + if (caseless) set = set.getCaseless(); + + if ( DEBUG ) { + Out.dump("makeClass("+set+")"); + dump(); + } + + int oldSize = classes.size(); + for (int i = 0; i < oldSize; i++) { + IntCharSet x = (IntCharSet) classes.elementAt(i); + + if (x.equals(set)) return; + + IntCharSet and = x.and(set); + + if ( and.containsElements() ) { + if ( x.equals(and) ) { + set.sub(and); + continue; + } + else if ( set.equals(and) ) { + x.sub(and); + classes.addElement(and); + if (DEBUG) { + Out.dump("makeClass(..) finished"); + dump(); + } + return; + } + + set.sub(and); + x.sub(and); + classes.addElement(and); + } + } + + if (DEBUG) { + Out.dump("makeClass(..) finished"); + dump(); + } + } + + + /** + * Returns the code of the character class the specified character belongs to. + */ + public int getClassCode(char letter) { + int i = -1; + while (true) { + IntCharSet x = (IntCharSet) classes.elementAt(++i); + if ( x.contains(letter) ) return i; + } + } + + /** + * Dump charclasses to the dump output stream + */ + public void dump() { + Out.dump(toString()); + } + + + /** + * Return a string representation of one char class + * + * @param theClass the index of the class to + */ + public String toString(int theClass) { + return classes.elementAt(theClass).toString(); + } + + + /** + * Return a string representation of the char classes + * stored in this class. + * + * Enumerates the classes by index. + */ + public String toString() { + StringBuffer result = new StringBuffer("CharClasses:"); + + result.append(Out.NL); + + for (int i = 0; i < classes.size(); i++) + result.append("class "+i+":"+Out.NL+classes.elementAt(i)+Out.NL); + + return result.toString(); + } + + + /** + * Creates a new character class for the single character singleChar. + * + * @param caseless if true upper/lower/title case are considered equivalent + */ + public void makeClass(char singleChar, boolean caseless) { + makeClass(new IntCharSet(singleChar), caseless); + } + + + /** + * Creates a new character class for each character of the specified String. + * + * @param caseless if true upper/lower/title case are considered equivalent + */ + public void makeClass(String str, boolean caseless) { + for (int i = 0; i < str.length(); i++) makeClass(str.charAt(i), caseless); + } + + + /** + * Updates the current partition, so that the specified set of characters + * gets a new character class. + * + * Characters that are elements of the set v are not in the same + * equivalence class with characters that are not elements of the set v. + * + * @param v a Vector of Interval objects. + * This Vector represents a set of characters. The set of characters is + * the union of all intervalls in the Vector. + * + * @param caseless if true upper/lower/title case are considered equivalent + */ + public void makeClass(Vector /* Interval */ v, boolean caseless) { + makeClass(new IntCharSet(v), caseless); + } + + + /** + * Updates the current partition, so that the set of all characters not contained in the specified + * set of characters gets a new character class. + * + * Characters that are elements of the set v are not in the same + * equivalence class with characters that are not elements of the set v. + * + * This method is equivalent to makeClass(v) + * + * @param v a Vector of Interval objects. + * This Vector represents a set of characters. The set of characters is + * the union of all intervalls in the Vector. + * + * @param caseless if true upper/lower/title case are considered equivalent + */ + public void makeClassNot(Vector v, boolean caseless) { + makeClass(new IntCharSet(v), caseless); + } + + + /** + * Returns an array that contains the character class codes of all characters + * in the specified set of input characters. + */ + private int [] getClassCodes(IntCharSet set, boolean negate) { + + if (DEBUG) { + Out.dump("getting class codes for "+set); + if (negate) + Out.dump("[negated]"); + } + + int size = classes.size(); + + // [fixme: optimize] + int temp [] = new int [size]; + int length = 0; + + for (int i = 0; i < size; i++) { + IntCharSet x = (IntCharSet) classes.elementAt(i); + if ( negate ) { + if ( !set.and(x).containsElements() ) { + temp[length++] = i; + if (DEBUG) Out.dump("code "+i); + } + } + else { + if ( set.and(x).containsElements() ) { + temp[length++] = i; + if (DEBUG) Out.dump("code "+i); + } + } + } + + int result [] = new int [length]; + System.arraycopy(temp, 0, result, 0, length); + + return result; + } + + + /** + * Returns an array that contains the character class codes of all characters + * in the specified set of input characters. + * + * @param intervallVec a Vector of Intervalls, the set of characters to get + * the class codes for + * + * @return an array with the class codes for intervallVec + */ + public int [] getClassCodes(Vector /* Interval */ intervallVec) { + return getClassCodes(new IntCharSet(intervallVec), false); + } + + + /** + * Returns an array that contains the character class codes of all characters + * that are not in the specified set of input characters. + * + * @param intervallVec a Vector of Intervalls, the complement of the + * set of characters to get the class codes for + * + * @return an array with the class codes for the complement of intervallVec + */ + public int [] getNotClassCodes(Vector /* Interval */ intervallVec) { + return getClassCodes(new IntCharSet(intervallVec), true); + } + + + /** + * Check consistency of the stored classes [debug]. + * + * all classes must be disjoint, checks if all characters + * have a class assigned. + */ + public void check() { + for (int i = 0; i < classes.size(); i++) + for (int j = i+1; j < classes.size(); j++) { + IntCharSet x = (IntCharSet) classes.elementAt(i); + IntCharSet y = (IntCharSet) classes.elementAt(j); + if ( x.and(y).containsElements() ) { + System.out.println("Error: non disjoint char classes "+i+" and "+j); + System.out.println("class "+i+": "+x); + System.out.println("class "+j+": "+y); + } + } + + // check if each character has a classcode + // (= if getClassCode terminates) + for (char c = 0; c < maxChar; c++) { + getClassCode(c); + if (c % 100 == 0) System.out.print("."); + } + + getClassCode(maxChar); + } + + + /** + * Returns an array of all CharClassIntervalls in this + * char class collection. + * + * The array is ordered by char code, i.e. + * result[i+1].start = result[i].end+1 + * + * Each CharClassInterval contains the number of the + * char class it belongs to. + */ + public CharClassInterval [] getIntervalls() { + int i, c; + int size = classes.size(); + int numIntervalls = 0; + + for (i = 0; i < size; i++) + numIntervalls+= ((IntCharSet) classes.elementAt(i)).numIntervalls(); + + CharClassInterval [] result = new CharClassInterval[numIntervalls]; + + i = 0; + c = 0; + while (i < numIntervalls) { + int code = getClassCode((char) c); + IntCharSet set = (IntCharSet) classes.elementAt(code); + Interval iv = set.getNext(); + + result[i++] = new CharClassInterval(iv.start, iv.end, code); + c = iv.end+1; + } + + return result; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/CharSet.java b/tools/lexer/jflex-1.4/src/JFlex/CharSet.java new file mode 100644 index 000000000000..322228087cbd --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CharSet.java @@ -0,0 +1,112 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:31 $ + */ +public final class CharSet { + + final static int BITS = 6; // the number of bits to shift (2^6 = 64) + final static int MOD = (1<> BITS)+1]; + add(character); + } + + + public void add(int character) { + resize(character); + + if ( (bits[character >> BITS] & (1L << (character & MOD))) == 0) numElements++; + + bits[character >> BITS] |= (1L << (character & MOD)); + } + + + private int nbits2size (int nbits) { + return ((nbits >> BITS) + 1); + } + + + private void resize(int nbits) { + int needed = nbits2size(nbits); + + if (needed < bits.length) return; + + long newbits[] = new long[Math.max(bits.length*2,needed)]; + System.arraycopy(bits, 0, newbits, 0, bits.length); + + bits = newbits; + } + + + public boolean isElement(int character) { + int index = character >> BITS; + if (index >= bits.length) return false; + return (bits[index] & (1L << (character & MOD))) != 0; + } + + + public CharSetEnumerator characters() { + return new CharSetEnumerator(this); + } + + + public boolean containsElements() { + return numElements > 0; + } + + public int size() { + return numElements; + } + + public String toString() { + CharSetEnumerator set = characters(); + + StringBuffer result = new StringBuffer("{"); + + if ( set.hasMoreElements() ) result.append(""+set.nextElement()); + + while ( set.hasMoreElements() ) { + int i = set.nextElement(); + result.append( ", "+(int)i); + } + + result.append("}"); + + return result.toString(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/CharSetEnumerator.java b/tools/lexer/jflex-1.4/src/JFlex/CharSetEnumerator.java new file mode 100644 index 000000000000..4f5f1c2ba4e9 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CharSetEnumerator.java @@ -0,0 +1,88 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Enumerator for the elements of a CharSet. + * + * Does not implement java.util.Enumeration, but supports the same protocol. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:30 $ + */ +final public class CharSetEnumerator { + + private int index; + private int offset; + private long mask = 1; + + private CharSet set; + + public CharSetEnumerator(CharSet characters) { + set = characters; + + while (index < set.bits.length && set.bits[index] == 0) + index++; + + if (index >= set.bits.length) return; + + while (offset <= CharSet.MOD && ((set.bits[index] & mask) == 0)) { + mask<<= 1; + offset++; + } + } + + private void advance() { + do { + offset++; + mask<<= 1; + } while (offset <= CharSet.MOD && ((set.bits[index] & mask) == 0)); + + if (offset > CharSet.MOD) { + do + index++; + while (index < set.bits.length && set.bits[index] == 0); + + if (index >= set.bits.length) return; + + offset = 0; + mask = 1; + + while (offset <= CharSet.MOD && ((set.bits[index] & mask) == 0)) { + mask<<= 1; + offset++; + } + } + } + + public boolean hasMoreElements() { + return index < set.bits.length; + } + + public int nextElement() { + int x = (index << CharSet.BITS) + offset; + advance(); + return x; + } + +} + diff --git a/tools/lexer/jflex-1.4/src/JFlex/CountEmitter.java b/tools/lexer/jflex-1.4/src/JFlex/CountEmitter.java new file mode 100644 index 000000000000..177adf4f7771 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/CountEmitter.java @@ -0,0 +1,115 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * jflex 1.4 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +/** + * An emitter for an array encoded as count/value pairs in a string. + * + * @author Gerwin Klein + * @version $Revision: 1.6 $, $Date: 2004/04/12 10:07:48 $ + */ +public class CountEmitter extends PackEmitter { + /** number of entries in expanded array */ + private int numEntries; + + /** translate all values by this amount */ + private int translate = 0; + + + /** + * Create a count/value emitter for a specific field. + * + * @param name name of the generated array + */ + protected CountEmitter(String name) { + super(name); + } + + /** + * Emits count/value unpacking code for the generated array. + * + * @see JFlex.PackEmitter#emitUnPack() + */ + public void emitUnpack() { + // close last string chunk: + println("\";"); + + nl(); + println(" private static int [] zzUnpack"+name+"() {"); + println(" int [] result = new int["+numEntries+"];"); + println(" int offset = 0;"); + + for (int i = 0; i < chunks; i++) { + println(" offset = zzUnpack"+name+"("+constName()+"_PACKED_"+i+", offset, result);"); + } + + println(" return result;"); + println(" }"); + nl(); + + println(" private static int zzUnpack"+name+"(String packed, int offset, int [] result) {"); + println(" int i = 0; /* index in packed string */"); + println(" int j = offset; /* index in unpacked array */"); + println(" int l = packed.length();"); + println(" while (i < l) {"); + println(" int count = packed.charAt(i++);"); + println(" int value = packed.charAt(i++);"); + if (translate == 1) { + println(" value--;"); + } + else if (translate != 0) { + println(" value-= "+translate); + } + println(" do result[j++] = value; while (--count > 0);"); + println(" }"); + println(" return j;"); + println(" }"); + } + + /** + * Translate all values by given amount. + * + * Use to move value interval from [0, 0xFFFF] to something different. + * + * @param i amount the value will be translated by. + * Example: i = 1 allows values in [-1, 0xFFFE]. + */ + public void setValTranslation(int i) { + this.translate = i; + } + + /** + * Emit one count/value pair. + * + * Automatically translates value by the translate value. + * + * @param count + * @param value + * + * @see CountEmitter#setValTranslation(int) + */ + public void emit(int count, int value) { + numEntries+= count; + breaks(); + emitUC(count); + emitUC(value+translate); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/DFA.java b/tools/lexer/jflex-1.4/src/JFlex/DFA.java new file mode 100644 index 000000000000..37e2556504ee --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/DFA.java @@ -0,0 +1,940 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Enumeration; +import java.util.Hashtable; + + +/** + * DFA representation in JFlex. + * Contains minimization algorithm. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.7 $, $Date: 2004/11/06 23:03:31 $ + */ +final public class DFA { + + /** + * The initial number of states + */ + private static final int STATES = 500; + + /** + * The code for "no target state" in the transition table. + */ + public static final int NO_TARGET = -1; + + /** + * table[current_state][character] is the next state for current_state + * with input character, NO_TARGET if there is no transition for + * this input in current_state + */ + int [][] table; + + + /** + * isFinal[state] == true <=> the state state is + * a final state. + */ + boolean [] isFinal; + + /** + * isPushback[state] == true <=> the state state is + * a final state of an expression that can only be matched when followed by + * a certain lookaead. + */ + boolean [] isPushback; + + + /** + * isLookEnd[state] == true <=> the state state is + * a final state of a lookahead expression. + */ + boolean [] isLookEnd; + + + /** + * action[state] is the action that is to be carried out in + * state state, null if there is no action. + */ + Action [] action; + + /** + * lexState[i] is the start-state of lexical state i + */ + int lexState []; + + /** + * The number of states in this DFA + */ + int numStates; + + + /** + * The current maximum number of input characters + */ + int numInput; + + + /** + * all actions that are used in this DFA + */ + Hashtable usedActions = new Hashtable(); + + public DFA(int numLexStates, int numInp) { + numInput = numInp; + + int statesNeeded = Math.max(numLexStates, STATES); + + table = new int [statesNeeded] [numInput]; + action = new Action [statesNeeded]; + isFinal = new boolean [statesNeeded]; + isPushback = new boolean [statesNeeded]; + isLookEnd = new boolean [statesNeeded]; + lexState = new int [numLexStates]; + numStates = 0; + + for (int i = 0; i < statesNeeded; i++) { + for (char j = 0; j < numInput; j++) + table [i][j] = NO_TARGET; + } + } + + + public void setLexState(int lState, int trueState) { + lexState[lState] = trueState; + } + + private void ensureStateCapacity(int newNumStates) { + int oldLength = isFinal.length; + + if ( newNumStates < oldLength ) return; + + int newLength = oldLength*2; + while ( newLength <= newNumStates ) newLength*= 2; + + boolean [] newFinal = new boolean [newLength]; + boolean [] newPushback = new boolean [newLength]; + boolean [] newLookEnd = new boolean [newLength]; + Action [] newAction = new Action [newLength]; + int [] [] newTable = new int [newLength] [numInput]; + + System.arraycopy(isFinal,0,newFinal,0,numStates); + System.arraycopy(isPushback,0,newPushback,0,numStates); + System.arraycopy(isLookEnd,0,newLookEnd,0,numStates); + System.arraycopy(action,0,newAction,0,numStates); + System.arraycopy(table,0,newTable,0,oldLength); + + int i,j; + + for (i = oldLength; i < newLength; i++) { + for (j = 0; j < numInput; j++) { + newTable[i][j] = NO_TARGET; + } + } + + isFinal = newFinal; + isPushback = newPushback; + isLookEnd = newLookEnd; + action = newAction; + table = newTable; + } + + + public void setAction(int state, Action stateAction) { + action[state] = stateAction; + if (stateAction != null) { + isLookEnd[state] = stateAction.isLookAction(); + usedActions.put(stateAction,stateAction); + } + } + + public void setFinal(int state, boolean isFinalState) { + isFinal[state] = isFinalState; + } + + public void setPushback(int state, boolean isPushbackState) { + isPushback[state] = isPushbackState; + } + + + public void addTransition(int start, char input, int dest) { + int max = Math.max(start,dest)+1; + ensureStateCapacity(max); + if (max > numStates) numStates = max; + + // Out.debug("Adding DFA transition ("+start+", "+(int)input+", "+dest+")"); + + table[start][input] = dest; + } + + + + public String toString() { + StringBuffer result = new StringBuffer(); + + for (int i=0; i < numStates; i++) { + result.append("State "); + if ( isFinal[i] ) result.append("[FINAL] "); // (action "+action[i].priority+")] "); + if ( isPushback[i] ) result.append("[PUSH] "); + result.append(i+":"+Out.NL); + + for (char j=0; j < numInput; j++) { + if ( table[i][j] >= 0 ) + result.append(" with "+(int)j+" in "+table[i][j]+Out.NL); + } + } + + return result.toString(); + } + + + public void writeDot(File file) { + try { + PrintWriter writer = new PrintWriter(new FileWriter(file)); + writer.println(dotFormat()); + writer.close(); + } + catch (IOException e) { + Out.error(ErrorMessages.FILE_WRITE, file); + throw new GeneratorException(); + } + } + + + public String dotFormat() { + StringBuffer result = new StringBuffer(); + + result.append("digraph DFA {"+Out.NL); + result.append("rankdir = LR"+Out.NL); + + for (int i=0; i < numStates; i++) { + if ( isFinal[i] || isPushback[i] ) result.append(i); + if ( isFinal[i] ) result.append(" [shape = doublecircle]"); + if ( isPushback[i] ) result.append(" [shape = box]"); + if ( isFinal[i] || isPushback[i] ) result.append(Out.NL); + } + + for (int i=0; i < numStates; i++) { + for (int input = 0; input < numInput; input++) { + if ( table[i][input] >= 0 ) { + result.append(i+" -> "+table[i][input]); + result.append(" [label=\"["+input+"]\"]"+Out.NL); + // result.append(" [label=\"["+classes.toString(input)+"]\"]\n"); + } + } + } + + result.append("}"+Out.NL); + + return result.toString(); + } + + + // check if all actions can actually be matched in this DFA + public void checkActions(LexScan scanner, LexParse parser) { + EOFActions eofActions = parser.getEOFActions(); + Enumeration l = scanner.actions.elements(); + + while (l.hasMoreElements()) { + Object next = l.nextElement(); + if ( !next.equals(usedActions.get(next)) && !eofActions.isEOFAction(next) ) + Out.warning(scanner.file, ErrorMessages.NEVER_MATCH, ((Action) next).priority-1, -1); + } + } + + + /** + * Implementation of Hopcroft's O(n log n) minimization algorithm, follows + * description by D. Gries. + * + * Time: O(n log n) + * Space: O(c n), size < 4*(5*c*n + 13*n + 3*c) byte + */ + public void minimize() { + Out.print(numStates+" states before minimization, "); + + if (numStates == 0) { + Out.error(ErrorMessages.ZERO_STATES); + throw new GeneratorException(); + } + + if (Options.no_minimize) { + Out.println("minimization skipped."); + return; + } + + // the algorithm needs the DFA to be total, so we add an error state 0, + // and translate the rest of the states by +1 + final int n = numStates+1; + + // block information: + // [0..n-1] stores which block a state belongs to, + // [n..2*n-1] stores how many elements each block has + int [] block = new int[2*n]; + + // implements a doubly linked list of states (these are the actual blocks) + int [] b_forward = new int[2*n]; + int [] b_backward = new int[2*n]; + + // the last of the blocks currently in use (in [n..2*n-1]) + // (end of list marker, points to the last used block) + int lastBlock = n; // at first we start with one empty block + final int b0 = n; // the first block + + // the circular doubly linked list L of pairs (B_i, c) + // (B_i, c) in L iff l_forward[(B_i-n)*numInput+c] > 0 // numeric value of block 0 = n! + int [] l_forward = new int[n*numInput+1]; + int [] l_backward = new int[n*numInput+1]; + int anchorL = n*numInput; // list anchor + + // inverse of the transition table + // if t = inv_delta[s][c] then { inv_delta_set[t], inv_delta_set[t+1], .. inv_delta_set[k] } + // is the set of states, with inv_delta_set[k] = -1 and inv_delta_set[j] >= 0 for t <= j < k + int [] [] inv_delta = new int[n][numInput]; + int [] inv_delta_set = new int [2*n*numInput]; + + // twin stores two things: + // twin[0]..twin[numSplit-1] is the list of blocks that have been split + // twin[B_i] is the twin of block B_i + int [] twin = new int[2*n]; + int numSplit; + + // SD[B_i] is the the number of states s in B_i with delta(s,a) in B_j + // if SD[B_i] == block[B_i], there is no need to split + int [] SD = new int[2*n]; // [only SD[n..2*n-1] is used] + + + // for fixed (B_j,a), the D[0]..D[numD-1] are the inv_delta(B_j,a) + int [] D = new int[n]; + int numD; + + + // initialize inverse of transition table + int lastDelta = 0; + int [] inv_lists = new int[n]; // holds a set of lists of states + int [] inv_list_last = new int[n]; // the last element + for (int c = 0; c < numInput; c++) { + // clear "head" and "last element" pointers + for (int s = 0; s < n; s++) { + inv_list_last[s] = -1; + inv_delta[s][c] = -1; + } + + // the error state has a transition for each character into itself + inv_delta[0][c] = 0; + inv_list_last[0] = 0; + + // accumulate states of inverse delta into lists (inv_delta serves as head of list) + for (int s = 1; s < n; s++) { + int t = table[s-1][c]+1; + + if (inv_list_last[t] == -1) { // if there are no elements in the list yet + inv_delta[t][c] = s; // mark t as first and last element + inv_list_last[t] = s; + } + else { + inv_lists[inv_list_last[t]] = s; // link t into chain + inv_list_last[t] = s; // and mark as last element + } + } + + // now move them to inv_delta_set in sequential order, + // and update inv_delta accordingly + for (int s = 0; s < n; s++) { + int i = inv_delta[s][c]; inv_delta[s][c] = lastDelta; + int j = inv_list_last[s]; + boolean go_on = (i != -1); + while (go_on) { + go_on = (i != j); + inv_delta_set[lastDelta++] = i; + i = inv_lists[i]; + } + inv_delta_set[lastDelta++] = -1; + } + } // of initialize inv_delta + + // printInvDelta(inv_delta, inv_delta_set); + + // initialize blocks + + // make b0 = {0} where 0 = the additional error state + b_forward[b0] = 0; + b_backward[b0] = 0; + b_forward[0] = b0; + b_backward[0] = b0; + block[0] = b0; + block[b0] = 1; + + for (int s = 1; s < n; s++) { + // System.out.println("Checking state ["+(s-1)+"]"); + // search the blocks if it fits in somewhere + // (fit in = same pushback behavior, same finalness, same lookahead behavior, same action) + int b = b0+1; // no state can be equivalent to the error state + boolean found = false; + while (!found && b <= lastBlock) { + // get some state out of the current block + int t = b_forward[b]; + // System.out.println(" picking state ["+(t-1)+"]"); + + // check, if s could be equivalent with t + found = (isPushback[s-1] == isPushback[t-1]) && (isLookEnd[s-1] == isLookEnd[t-1]); + if (found) { + if (isFinal[s-1]) { + found = isFinal[t-1] && action[s-1].isEquiv(action[t-1]); + } + else { + found = !isFinal[t-1]; + } + + if (found) { // found -> add state s to block b + // System.out.println("Found! Adding to block "+(b-b0)); + // update block information + block[s] = b; + block[b]++; + + // chain in the new element + int last = b_backward[b]; + b_forward[last] = s; + b_forward[s] = b; + b_backward[b] = s; + b_backward[s] = last; + } + } + + b++; + } + + if (!found) { // fits in nowhere -> create new block + // System.out.println("not found, lastBlock = "+lastBlock); + + // update block information + block[s] = b; + block[b]++; + + // chain in the new element + b_forward[b] = s; + b_forward[s] = b; + b_backward[b] = s; + b_backward[s] = b; + + lastBlock++; + } + } // of initialize blocks + + // printBlocks(block,b_forward,b_backward,lastBlock); + + // initialize worklist L + // first, find the largest block B_max, then, all other (B_i,c) go into the list + int B_max = b0; + int B_i; + for (B_i = b0+1; B_i <= lastBlock; B_i++) + if (block[B_max] < block[B_i]) B_max = B_i; + + // L = empty + l_forward[anchorL] = anchorL; + l_backward[anchorL] = anchorL; + + // set up the first list element + if (B_max == b0) B_i = b0+1; else B_i = b0; // there must be at least two blocks + + int index = (B_i-b0)*numInput; // (B_i, 0) + while (index < (B_i+1-b0)*numInput) { + int last = l_backward[anchorL]; + l_forward[last] = index; + l_forward[index] = anchorL; + l_backward[index] = last; + l_backward[anchorL] = index; + index++; + } + + // now do the rest of L + while (B_i <= lastBlock) { + if (B_i != B_max) { + index = (B_i-b0)*numInput; + while (index < (B_i+1-b0)*numInput) { + int last = l_backward[anchorL]; + l_forward[last] = index; + l_forward[index] = anchorL; + l_backward[index] = last; + l_backward[anchorL] = index; + index++; + } + } + B_i++; + } + // end of setup L + + // start of "real" algorithm + // int step = 0; + // System.out.println("max_steps = "+(n*numInput)); + // while L not empty + while (l_forward[anchorL] != anchorL) { + // System.out.println("step : "+(step++)); + // printL(l_forward, l_backward, anchorL); + + // pick and delete (B_j, a) in L: + + // pick + int B_j_a = l_forward[anchorL]; + // delete + l_forward[anchorL] = l_forward[B_j_a]; + l_backward[l_forward[anchorL]] = anchorL; + l_forward[B_j_a] = 0; + // take B_j_a = (B_j-b0)*numInput+c apart into (B_j, a) + int B_j = b0 + B_j_a / numInput; + int a = B_j_a % numInput; + + // printL(l_forward, l_backward, anchorL); + + // System.out.println("picked ("+B_j+","+a+")"); + // printL(l_forward, l_backward, anchorL); + + // determine splittings of all blocks wrt (B_j, a) + // i.e. D = inv_delta(B_j,a) + numD = 0; + int s = b_forward[B_j]; + while (s != B_j) { + // System.out.println("splitting wrt. state "+s); + int t = inv_delta[s][a]; + // System.out.println("inv_delta chunk "+t); + while (inv_delta_set[t] != -1) { + // System.out.println("D+= state "+inv_delta_set[t]); + D[numD++] = inv_delta_set[t++]; + } + s = b_forward[s]; + } + + // clear the twin list + numSplit = 0; + + // System.out.println("splitting blocks according to D"); + + // clear SD and twins (only those B_i that occur in D) + for (int indexD = 0; indexD < numD; indexD++) { // for each s in D + s = D[indexD]; + B_i = block[s]; + SD[B_i] = -1; + twin[B_i] = 0; + } + + // count how many states of each B_i occuring in D go with a into B_j + // Actually we only check, if *all* t in B_i go with a into B_j. + // In this case SD[B_i] == block[B_i] will hold. + for (int indexD = 0; indexD < numD; indexD++) { // for each s in D + s = D[indexD]; + B_i = block[s]; + + // only count, if we haven't checked this block already + if (SD[B_i] < 0) { + SD[B_i] = 0; + int t = b_forward[B_i]; + while (t != B_i && (t != 0 || block[0] == B_j) && + (t == 0 || block[table[t-1][a]+1] == B_j)) { + SD[B_i]++; + t = b_forward[t]; + } + } + } + + // split each block according to D + for (int indexD = 0; indexD < numD; indexD++) { // for each s in D + s = D[indexD]; + B_i = block[s]; + + // System.out.println("checking if block "+(B_i-b0)+" must be split because of state "+s); + + if (SD[B_i] != block[B_i]) { + // System.out.println("state "+(s-1)+" must be moved"); + int B_k = twin[B_i]; + if (B_k == 0) { + // no twin for B_i yet -> generate new block B_k, make it B_i's twin + B_k = ++lastBlock; + // System.out.println("creating block "+(B_k-n)); + // printBlocks(block,b_forward,b_backward,lastBlock-1); + b_forward[B_k] = B_k; + b_backward[B_k] = B_k; + + twin[B_i] = B_k; + + // mark B_i as split + twin[numSplit++] = B_i; + } + // move s from B_i to B_k + + // remove s from B_i + b_forward[b_backward[s]] = b_forward[s]; + b_backward[b_forward[s]] = b_backward[s]; + + // add s to B_k + int last = b_backward[B_k]; + b_forward[last] = s; + b_forward[s] = B_k; + b_backward[s] = last; + b_backward[B_k] = s; + + block[s] = B_k; + block[B_k]++; + block[B_i]--; + + SD[B_i]--; // there is now one state less in B_i that goes with a into B_j + // printBlocks(block, b_forward, b_backward, lastBlock); + // System.out.println("finished move"); + } + } // of block splitting + + // printBlocks(block, b_forward, b_backward, lastBlock); + + // System.out.println("updating L"); + + // update L + for (int indexTwin = 0; indexTwin < numSplit; indexTwin++) { + B_i = twin[indexTwin]; + int B_k = twin[B_i]; + for (int c = 0; c < numInput; c++) { + int B_i_c = (B_i-b0)*numInput+c; + int B_k_c = (B_k-b0)*numInput+c; + if (l_forward[B_i_c] > 0) { + // (B_i,c) already in L --> put (B_k,c) in L + int last = l_backward[anchorL]; + l_backward[anchorL] = B_k_c; + l_forward[last] = B_k_c; + l_backward[B_k_c] = last; + l_forward[B_k_c] = anchorL; + } + else { + // put the smaller block in L + if (block[B_i] <= block[B_k]) { + int last = l_backward[anchorL]; + l_backward[anchorL] = B_i_c; + l_forward[last] = B_i_c; + l_backward[B_i_c] = last; + l_forward[B_i_c] = anchorL; + } + else { + int last = l_backward[anchorL]; + l_backward[anchorL] = B_k_c; + l_forward[last] = B_k_c; + l_backward[B_k_c] = last; + l_forward[B_k_c] = anchorL; + } + } + } + } + } + + // System.out.println("Result"); + // printBlocks(block,b_forward,b_backward,lastBlock); + + /* + System.out.println("Old minimization:"); + boolean [] [] equiv = old_minimize(); + + boolean error = false; + for (int i = 1; i < equiv.length; i++) { + for (int j = 0; j < equiv[i].length; j++) { + if (equiv[i][j] != (block[i+1] == block[j+1])) { + System.out.println("error: equiv["+i+"]["+j+"] = "+equiv[i][j]+ + ", block["+i+"] = "+block[i+1]+", block["+j+"] = "+block[j]); + error = true; + } + } + } + + if (error) System.exit(1); + System.out.println("check"); + */ + + // transform the transition table + + // trans[i] is the state j that will replace state i, i.e. + // states i and j are equivalent + int trans [] = new int [numStates]; + + // kill[i] is true iff state i is redundant and can be removed + boolean kill [] = new boolean [numStates]; + + // move[i] is the amount line i has to be moved in the transition table + // (because states j < i have been removed) + int move [] = new int [numStates]; + + // fill arrays trans[] and kill[] (in O(n)) + for (int b = b0+1; b <= lastBlock; b++) { // b0 contains the error state + // get the state with smallest value in current block + int s = b_forward[b]; + int min_s = s; // there are no empty blocks! + for (; s != b; s = b_forward[s]) + if (min_s > s) min_s = s; + // now fill trans[] and kill[] for this block + // (and translate states back to partial DFA) + min_s--; + for (s = b_forward[b]-1; s != b-1; s = b_forward[s+1]-1) { + trans[s] = min_s; + kill[s] = s != min_s; + } + } + + // fill array move[] (in O(n)) + int amount = 0; + for (int i = 0; i < numStates; i++) { + if ( kill[i] ) + amount++; + else + move[i] = amount; + } + + int i,j; + // j is the index in the new transition table + // the transition table is transformed in place (in O(c n)) + for (i = 0, j = 0; i < numStates; i++) { + + // we only copy lines that have not been removed + if ( !kill[i] ) { + + // translate the target states + for (int c = 0; c < numInput; c++) { + if ( table[i][c] >= 0 ) { + table[j][c] = trans[ table[i][c] ]; + table[j][c]-= move[ table[j][c] ]; + } + else { + table[j][c] = table[i][c]; + } + } + + isFinal[j] = isFinal[i]; + isPushback[j] = isPushback[i]; + isLookEnd[j] = isLookEnd[i]; + action[j] = action[i]; + + j++; + } + } + + numStates = j; + + // translate lexical states + for (i = 0; i < lexState.length; i++) { + lexState[i] = trans[ lexState[i] ]; + lexState[i]-= move[ lexState[i] ]; + } + + Out.println(numStates+" states in minimized DFA"); + } + + public String toString(int [] a) { + String r = "{"; + int i; + for (i = 0; i < a.length-1; i++) r += a[i]+","; + return r+a[i]+"}"; + } + + public void printBlocks(int [] b, int [] b_f, int [] b_b, int last) { + Out.dump("block : "+toString(b)); + Out.dump("b_forward : "+toString(b_f)); + Out.dump("b_backward: "+toString(b_b)); + Out.dump("lastBlock : "+last); + final int n = numStates+1; + for (int i = n; i <= last; i ++) { + Out.dump("Block "+(i-n)+" (size "+b[i]+"):"); + String line = "{"; + int s = b_f[i]; + while (s != i) { + line = line+(s-1); + int t = s; + s = b_f[s]; + if (s != i) { + line = line+","; + if (b[s] != i) Out.dump("consistency error for state "+(s-1)+" (block "+b[s]+")"); + } + if (b_b[s] != t) Out.dump("consistency error for b_back in state "+(s-1)+" (back = "+b_b[s]+", should be = "+t+")"); + } + Out.dump(line+"}"); + } + } + + public void printL(int [] l_f, int [] l_b, int anchor) { + String l = "L = {"; + int bc = l_f[anchor]; + while (bc != anchor) { + int b = bc / numInput; + int c = bc % numInput; + l+= "("+b+","+c+")"; + int old_bc = bc; + bc = l_f[bc]; + if (bc != anchor) l+= ","; + if (l_b[bc] != old_bc) Out.dump("consistency error for ("+b+","+c+")"); + } + Out.dump(l+"}"); + } + + + public boolean [] [] old_minimize() { + + int i,j; + char c; + + Out.print(numStates+" states before minimization, "); + + if (numStates == 0) { + Out.error(ErrorMessages.ZERO_STATES); + throw new GeneratorException(); + } + + if (Options.no_minimize) { + Out.println("minimization skipped."); + return null; + } + + // notequiv[i][j] == true <=> state i and state j are equivalent + boolean [] [] equiv = new boolean [numStates] []; + + // list[i][j] contains all pairs of states that have to be marked "not equivalent" + // if states i and j are recognized to be not equivalent + StatePairList [] [] list = new StatePairList [numStates] []; + + // construct a triangular matrix equiv[i][j] with j < i + // and mark pairs (final state, not final state) as not equivalent + for (i = 1; i < numStates; i++) { + list[i] = new StatePairList[i]; + equiv[i] = new boolean [i]; + for (j = 0; j < i; j++) { + // i and j are equivalent, iff : + // i and j are both final and their actions are equivalent and have same pushback behaviour or + // i and j are both not final + + if ( isFinal[i] && isFinal[j] && (isPushback[i] == isPushback[j]) && (isLookEnd[i] == isLookEnd[j]) ) + equiv[i][j] = action[i].isEquiv(action[j]); + else + equiv[i][j] = !isFinal[j] && !isFinal[i] && (isPushback[i] == isPushback[j]) && (isLookEnd[i] == isLookEnd[j]); + } + } + + + for (i = 1; i < numStates; i++) { + + Out.debug("Testing state "+i); + + for (j = 0; j < i; j++) { + + if ( equiv[i][j] ) { + + for (c = 0; c < numInput; c++) { + + if (equiv[i][j]) { + + int p = table[i][c]; + int q = table[j][c]; + if (p < q) { + int t = p; + p = q; + q = t; + } + if ( p >= 0 || q >= 0 ) { + // Out.debug("Testing input '"+c+"' for ("+i+","+j+")"); + // Out.debug("Target states are ("+p+","+q+")"); + if ( p!=q && (p == -1 || q == -1 || !equiv[p][q]) ) { + equiv[i][j] = false; + if (list[i][j] != null) list[i][j].markAll(list,equiv); + } + // printTable(equiv); + } // if (p >= 0) .. + } // if (equiv[i][j] + } // for (char c = 0; c < numInput .. + + // if i and j are still marked equivalent.. + + if ( equiv[i][j] ) { + + // Out.debug("("+i+","+j+") are still marked equivalent"); + + for (c = 0; c < numInput; c++) { + + int p = table[i][c]; + int q = table[j][c]; + if (p < q) { + int t = p; + p = q; + q = t; + } + + if (p != q && p >= 0 && q >= 0) { + if ( list[p][q] == null ) { + list[p][q] = new StatePairList(); + } + list[p][q].addPair(i,j); + } + } + } + else { + // Out.debug("("+i+","+j+") are not equivalent"); + } + + } // of first if (equiv[i][j]) + } // of for j + } // of for i + // } + + // printTable(equiv); + + return equiv; + } + + + public void printInvDelta(int [] [] inv_delta, int [] inv_delta_set) { + Out.dump("Inverse of transition table: "); + for (int s = 0; s < numStates+1; s++) { + Out.dump("State ["+(s-1)+"]"); + for (int c = 0; c < numInput; c++) { + String line = "With <"+c+"> in {"; + int t = inv_delta[s][c]; + while (inv_delta_set[t] != -1) { + line += inv_delta_set[t++]-1; + if (inv_delta_set[t] != -1) line += ","; + } + if (inv_delta_set[inv_delta[s][c]] != -1) + Out.dump(line+"}"); + } + } + } + + public void printTable(boolean [] [] equiv) { + + Out.dump("Equivalence table is : "); + for (int i = 1; i < numStates; i++) { + String line = i+" :"; + for (int j = 0; j < i; j++) { + if (equiv[i][j]) + line+= " E"; + else + line+= " x"; + } + Out.dump(line); + } + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/EOFActions.java b/tools/lexer/jflex-1.4/src/JFlex/EOFActions.java new file mode 100644 index 000000000000..76242fb3a9a9 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/EOFActions.java @@ -0,0 +1,96 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + + +/** + * A simple table to store EOF actions for each lexical state. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +public class EOFActions { + + /** maps lexical states to actions */ + private Hashtable /* Integer -> Action */ actions = new Hashtable(); + private Action defaultAction; + private int numLexStates; + + public void setNumLexStates(int num) { + numLexStates = num; + } + + public void add(Vector stateList, Action action) { + + if (stateList != null && stateList.size() > 0) { + Enumeration states = stateList.elements(); + + while (states.hasMoreElements()) + add( (Integer) states.nextElement(), action ); + } + else { + defaultAction = action.getHigherPriority(defaultAction); + + for (int i = 0; i < numLexStates; i++) { + Integer state = new Integer(i); + if ( actions.get(state) != null ) { + Action oldAction = (Action) actions.get(state); + actions.put(state, oldAction.getHigherPriority(action)); + } + } + } + } + + public void add(Integer state, Action action) { + if ( actions.get(state) == null ) + actions.put(state, action); + else { + Action oldAction = (Action) actions.get(state); + actions.put(state, oldAction.getHigherPriority(action)); + } + } + + public boolean isEOFAction(Object a) { + if (a == defaultAction) return true; + + Enumeration e = actions.elements(); + while ( e.hasMoreElements() ) + if (a == e.nextElement()) return true; + + return false; + } + + public Action getAction(int state) { + return (Action) actions.get(new Integer(state)); + } + + public Action getDefault() { + return defaultAction; + } + + public int numActions() { + return actions.size(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Emitter.java b/tools/lexer/jflex-1.4/src/JFlex/Emitter.java new file mode 100644 index 000000000000..eba3be2052b1 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Emitter.java @@ -0,0 +1,1616 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.io.*; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Enumeration; +import java.util.Hashtable; + +/** + * This class manages the actual code generation, putting + * the scanner together, filling in skeleton sections etc. + * + * Table compression, String packing etc. is also done here. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.26 $, $Date: 2004/11/07 03:12:46 $ + */ +final public class Emitter { + + // bit masks for state attributes + static final private int FINAL = 1; + static final private int PUSHBACK = 2; + static final private int LOOKEND = 4; + static final private int NOLOOK = 8; + + static final private String date = (new SimpleDateFormat()).format(new Date()); + + private File inputFile; + + private PrintWriter out; + private Skeleton skel; + private LexScan scanner; + private LexParse parser; + private DFA dfa; + + // for switch statement: + // table[i][j] is the set of input characters that leads from state i to state j + private CharSet table[][]; + + private boolean isTransition[]; + + // noTarget[i] is the set of input characters that have no target state in state i + private CharSet noTarget[]; + + // for row killing: + private int numRows; + private int [] rowMap; + private boolean [] rowKilled; + + // for col killing: + private int numCols; + private int [] colMap; + private boolean [] colKilled; + + + /** maps actions to their switch label */ + private Hashtable actionTable = new Hashtable(); + + private CharClassInterval [] intervalls; + + private String visibility = "public"; + + public Emitter(File inputFile, LexParse parser, DFA dfa) throws IOException { + + String name = parser.scanner.className+".java"; + + File outputFile = normalize(name, inputFile); + + Out.println("Writing code to \""+outputFile+"\""); + + this.out = new PrintWriter(new BufferedWriter(new FileWriter(outputFile))); + this.parser = parser; + this.scanner = parser.scanner; + this.visibility = scanner.visibility; + this.inputFile = inputFile; + this.dfa = dfa; + this.skel = new Skeleton(out); + } + + + /** + * Constructs a file in Options.getDir() or in the same directory as + * another file. Makes a backup if the file already exists. + * + * @param name the name (without path) of the file + * @param path the path where to construct the file + * @param input fallback location if path = null + * (expected to be a file in the directory to write to) + */ + public static File normalize(String name, File input) { + File outputFile; + + if ( Options.getDir() == null ) + if ( input == null || input.getParent() == null ) + outputFile = new File(name); + else + outputFile = new File(input.getParent(), name); + else + outputFile = new File(Options.getDir(), name); + + if ( outputFile.exists() && !Options.no_backup ) { + File backup = new File( outputFile.toString()+"~" ); + + if ( backup.exists() ) backup.delete(); + + if ( outputFile.renameTo( backup ) ) + Out.println("Old file \""+outputFile+"\" saved as \""+backup+"\""); + else + Out.println("Couldn't save old file \""+outputFile+"\", overwriting!"); + } + + return outputFile; + } + + private void println() { + out.println(); + } + + private void println(String line) { + out.println(line); + } + + private void println(int i) { + out.println(i); + } + + private void print(String line) { + out.print(line); + } + + private void print(int i) { + out.print(i); + } + + private void print(int i, int tab) { + int exp; + + if (i < 0) + exp = 1; + else + exp = 10; + + while (tab-- > 1) { + if (Math.abs(i) < exp) print(" "); + exp*= 10; + } + + print(i); + } + + private void emitScanError() { + print(" private void zzScanError(int errorCode)"); + + if (scanner.scanErrorException != null) + print(" throws "+scanner.scanErrorException); + + println(" {"); + + skel.emitNext(); + + if (scanner.scanErrorException == null) + println(" throw new Error(message);"); + else + println(" throw new "+scanner.scanErrorException+"(message);"); + + skel.emitNext(); + + print(" "+visibility+" void yypushback(int number) "); + + if (scanner.scanErrorException == null) + println(" {"); + else + println(" throws "+scanner.scanErrorException+" {"); + } + + private void emitMain() { + if ( !(scanner.standalone || scanner.debugOption || scanner.cupDebug) ) return; + + if ( scanner.cupDebug ) { + println(" /**"); + println(" * Converts an int token code into the name of the"); + println(" * token by reflection on the cup symbol class/interface "+scanner.cupSymbol); + println(" *"); + println(" * This code was contributed by Karl Meissner "); + println(" */"); + println(" private String getTokenName(int token) {"); + println(" try {"); + println(" java.lang.reflect.Field [] classFields = " + scanner.cupSymbol + ".class.getFields();"); + println(" for (int i = 0; i < classFields.length; i++) {"); + println(" if (classFields[i].getInt(null) == token) {"); + println(" return classFields[i].getName();"); + println(" }"); + println(" }"); + println(" } catch (Exception e) {"); + println(" e.printStackTrace(System.err);"); + println(" }"); + println(""); + println(" return \"UNKNOWN TOKEN\";"); + println(" }"); + println(""); + println(" /**"); + println(" * Same as "+scanner.functionName+" but also prints the token to standard out"); + println(" * for debugging."); + println(" *"); + println(" * This code was contributed by Karl Meissner "); + println(" */"); + + print(" "+visibility+" "); + if ( scanner.tokenType == null ) { + if ( scanner.isInteger ) + print( "int" ); + else + if ( scanner.isIntWrap ) + print( "Integer" ); + else + print( "Yytoken" ); + } + else + print( scanner.tokenType ); + + print(" debug_"); + + print(scanner.functionName); + + print("() throws java.io.IOException"); + + if ( scanner.lexThrow != null ) { + print(", "); + print(scanner.lexThrow); + } + + if ( scanner.scanErrorException != null ) { + print(", "); + print(scanner.scanErrorException); + } + + println(" {"); + + println(" java_cup.runtime.Symbol s = "+scanner.functionName+"();"); + print(" System.out.println( "); + if (scanner.lineCount) print("\"line:\" + (yyline+1) + "); + if (scanner.columnCount) print("\" col:\" + (yycolumn+1) + "); + println("\" --\"+ yytext() + \"--\" + getTokenName(s.sym) + \"--\");"); + println(" return s;"); + println(" }"); + println(""); + } + + if ( scanner.standalone ) { + println(" /**"); + println(" * Runs the scanner on input files."); + println(" *"); + println(" * This is a standalone scanner, it will print any unmatched"); + println(" * text to System.out unchanged."); + println(" *"); + println(" * @param argv the command line, contains the filenames to run"); + println(" * the scanner on."); + println(" */"); + } + else { + println(" /**"); + println(" * Runs the scanner on input files."); + println(" *"); + println(" * This main method is the debugging routine for the scanner."); + println(" * It prints debugging information about each returned token to"); + println(" * System.out until the end of file is reached, or an error occured."); + println(" *"); + println(" * @param argv the command line, contains the filenames to run"); + println(" * the scanner on."); + println(" */"); + } + + println(" public static void main(String argv[]) {"); + println(" if (argv.length == 0) {"); + println(" System.out.println(\"Usage : java "+scanner.className+" \");"); + println(" }"); + println(" else {"); + println(" for (int i = 0; i < argv.length; i++) {"); + println(" "+scanner.className+" scanner = null;"); + println(" try {"); + println(" scanner = new "+scanner.className+"( new java.io.FileReader(argv[i]) );"); + + if ( scanner.standalone ) { + println(" while ( !scanner.zzAtEOF ) scanner."+scanner.functionName+"();"); + } + else if (scanner.cupDebug ) { + println(" while ( !scanner.zzAtEOF ) scanner.debug_"+scanner.functionName+"();"); + } + else { + println(" do {"); + println(" System.out.println(scanner."+scanner.functionName+"());"); + println(" } while (!scanner.zzAtEOF);"); + println(""); + } + + println(" }"); + println(" catch (java.io.FileNotFoundException e) {"); + println(" System.out.println(\"File not found : \\\"\"+argv[i]+\"\\\"\");"); + println(" }"); + println(" catch (java.io.IOException e) {"); + println(" System.out.println(\"IO error scanning file \\\"\"+argv[i]+\"\\\"\");"); + println(" System.out.println(e);"); + println(" }"); + println(" catch (Exception e) {"); + println(" System.out.println(\"Unexpected exception:\");"); + println(" e.printStackTrace();"); + println(" }"); + println(" }"); + println(" }"); + println(" }"); + println(""); + } + + private void emitNoMatch() { + println(" zzScanError(ZZ_NO_MATCH);"); + } + + private String zzBufferLAccess(String idx) { + if (Options.sliceAndCharAt) { + return "zzBufferArrayL != null ? zzBufferArrayL[" + idx + "]:zzBufferL.charAt("+idx+")"; + } + if (Options.char_at) { + return "zzBufferL.charAt("+idx+")"; + } + return "zzBufferL[" + idx + "]"; + } + + private void emitNextInput() { + println(" if (zzCurrentPosL < zzEndReadL)"); + println(" zzInput = " + zzBufferLAccess("zzCurrentPosL++") + ";"); + println(" else if (zzAtEOF) {"); + println(" zzInput = YYEOF;"); + println(" break zzForAction;"); + println(" }"); + println(" else {"); + println(" // store back cached positions"); + println(" zzCurrentPos = zzCurrentPosL;"); + println(" zzMarkedPos = zzMarkedPosL;"); + if ( scanner.lookAheadUsed ) + println(" zzPushbackPos = zzPushbackPosL;"); + println(" boolean eof = zzRefill();"); + println(" // get translated positions and possibly new buffer"); + println(" zzCurrentPosL = zzCurrentPos;"); + println(" zzMarkedPosL = zzMarkedPos;"); + println(" zzBufferL = zzBuffer;"); + println(" zzEndReadL = zzEndRead;"); + if ( scanner.lookAheadUsed ) + println(" zzPushbackPosL = zzPushbackPos;"); + println(" if (eof) {"); + println(" zzInput = YYEOF;"); + println(" break zzForAction;"); + println(" }"); + println(" else {"); + println(" zzInput = " + zzBufferLAccess("zzCurrentPosL++") + ";"); + println(" }"); + println(" }"); + } + + private void emitHeader() { + println("/* The following code was generated by JFlex "+Main.version+" on "+date+" */"); + println(""); + } + + private void emitUserCode() { + if ( scanner.userCode.length() > 0 ) + println(scanner.userCode.toString()); + } + + private void emitClassName() { + if (!endsWithJavadoc(scanner.userCode)) { + String path = inputFile.toString(); + // slashify path (avoid backslash u sequence = unicode escape) + if (File.separatorChar != '/') { + path = path.replace(File.separatorChar, '/'); + } + + println("/**"); + println(" * This class is a scanner generated by "); + println(" * JFlex "+Main.version); + println(" * on "+date+" from the specification file"); + println(" * "+path+""); + println(" */"); + } + + if ( scanner.isPublic ) print("public "); + + if ( scanner.isAbstract) print("abstract "); + + if ( scanner.isFinal ) print("final "); + + print("class "); + print(scanner.className); + + if ( scanner.isExtending != null ) { + print(" extends "); + print(scanner.isExtending); + } + + if ( scanner.isImplementing != null ) { + print(" implements "); + print(scanner.isImplementing); + } + + println(" {"); + } + + /** + * Try to find out if user code ends with a javadoc comment + * + * @param buffer the user code + * @return true if it ends with a javadoc comment + */ + public static boolean endsWithJavadoc(StringBuffer usercode) { + String s = usercode.toString().trim(); + + if (!s.endsWith("*/")) return false; + + // find beginning of javadoc comment + int i = s.lastIndexOf("/**"); + if (i < 0) return false; + + // javadoc comment shouldn't contain a comment end + return s.substring(i,s.length()-2).indexOf("*/") < 0; + } + + + private void emitLexicalStates() { + Enumeration stateNames = scanner.states.names(); + + while ( stateNames.hasMoreElements() ) { + String name = (String) stateNames.nextElement(); + + int num = scanner.states.getNumber(name).intValue(); + + if (scanner.bolUsed) + println(" "+visibility+" static final int "+name+" = "+2*num+";"); + else + println(" "+visibility+" static final int "+name+" = "+dfa.lexState[2*num]+";"); + } + + if (scanner.bolUsed) { + println(""); + println(" /**"); + println(" * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l"); + println(" * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l"); + println(" * at the beginning of a line"); + println(" * l is of the form l = 2*k, k a non negative integer"); + println(" */"); + println(" private static final int ZZ_LEXSTATE[] = { "); + + int i, j = 0; + print(" "); + + for (i = 0; i < dfa.lexState.length-1; i++) { + print( dfa.lexState[i], 2 ); + + print(", "); + + if (++j >= 16) { + println(); + print(" "); + j = 0; + } + } + + println( dfa.lexState[i] ); + println(" };"); + + } + } + + private void emitDynamicInit() { + int count = 0; + int value = dfa.table[0][0]; + + println(" /** "); + println(" * The transition table of the DFA"); + println(" */"); + + CountEmitter e = new CountEmitter("Trans"); + e.setValTranslation(+1); // allow vals in [-1, 0xFFFE] + e.emitInit(); + + for (int i = 0; i < dfa.numStates; i++) { + if ( !rowKilled[i] ) { + for (int c = 0; c < dfa.numInput; c++) { + if ( !colKilled[c] ) { + if (dfa.table[i][c] == value) { + count++; + } + else { + e.emit(count, value); + + count = 1; + value = dfa.table[i][c]; + } + } + } + } + } + + e.emit(count, value); + e.emitUnpack(); + + println(e.toString()); + } + + + private void emitCharMapInitFunction() { + + CharClasses cl = parser.getCharClasses(); + + if ( cl.getMaxCharCode() < 256 ) return; + + println(""); + println(" /** "); + println(" * Unpacks the compressed character translation table."); + println(" *"); + println(" * @param packed the packed character translation table"); + println(" * @return the unpacked character translation table"); + println(" */"); + println(" private static char [] zzUnpackCMap(String packed) {"); + println(" char [] map = new char[0x10000];"); + println(" int i = 0; /* index in packed string */"); + println(" int j = 0; /* index in unpacked array */"); + println(" while (i < "+2*intervalls.length+") {"); + println(" int count = packed.charAt(i++);"); + println(" char value = packed.charAt(i++);"); + println(" do map[j++] = value; while (--count > 0);"); + println(" }"); + println(" return map;"); + println(" }"); + } + + private void emitZZTrans() { + + int i,c; + int n = 0; + + println(" /** "); + println(" * The transition table of the DFA"); + println(" */"); + println(" private static final int ZZ_TRANS [] = {"); //XXX + + print(" "); + for (i = 0; i < dfa.numStates; i++) { + + if ( !rowKilled[i] ) { + for (c = 0; c < dfa.numInput; c++) { + if ( !colKilled[c] ) { + if (n >= 10) { + println(); + print(" "); + n = 0; + } + print( dfa.table[i][c] ); + if (i != dfa.numStates-1 || c != dfa.numInput-1) + print( ", "); + n++; + } + } + } + } + + println(); + println(" };"); + } + + private void emitCharMapArrayUnPacked() { + + CharClasses cl = parser.getCharClasses(); + intervalls = cl.getIntervalls(); + + println(""); + println(" /** "); + println(" * Translates characters to character classes"); + println(" */"); + println(" private static final char [] ZZ_CMAP = {"); + + int n = 0; // numbers of entries in current line + print(" "); + + int max = cl.getMaxCharCode(); + int i = 0; + while ( i < intervalls.length && intervalls[i].start <= max ) { + + int end = Math.min(intervalls[i].end, max); + for (int c = intervalls[i].start; c <= end; c++) { + + print(colMap[intervalls[i].charClass], 2); + + if (c < max) { + print(", "); + if ( ++n >= 16 ) { + println(); + print(" "); + n = 0; + } + } + } + + i++; + } + + println(); + println(" };"); + println(); + } + + private void emitCharMapArray() { + CharClasses cl = parser.getCharClasses(); + + if ( cl.getMaxCharCode() < 256 ) { + emitCharMapArrayUnPacked(); + return; + } + + // ignores cl.getMaxCharCode(), emits all intervalls instead + + intervalls = cl.getIntervalls(); + + println(""); + println(" /** "); + println(" * Translates characters to character classes"); + println(" */"); + println(" private static final String ZZ_CMAP_PACKED = "); + + int n = 0; // numbers of entries in current line + print(" \""); + + int i = 0; + while ( i < intervalls.length-1 ) { + int count = intervalls[i].end-intervalls[i].start+1; + int value = colMap[intervalls[i].charClass]; + + printUC(count); + printUC(value); + + if ( ++n >= 10 ) { + println("\"+"); + print(" \""); + n = 0; + } + + i++; + } + + printUC(intervalls[i].end-intervalls[i].start+1); + printUC(colMap[intervalls[i].charClass]); + + println("\";"); + println(); + + println(" /** "); + println(" * Translates characters to character classes"); + println(" */"); + println(" private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);"); + println(); + } + + + /** + * Print number as octal/unicode escaped string character. + * + * @param c the value to print + * @prec 0 <= c <= 0xFFFF + */ + private void printUC(int c) { + if (c > 255) { + out.print("\\u"); + if (c < 0x1000) out.print("0"); + out.print(Integer.toHexString(c)); + } + else { + out.print("\\"); + out.print(Integer.toOctalString(c)); + } + } + + + private void emitRowMapArray() { + println(""); + println(" /** "); + println(" * Translates a state to a row index in the transition table"); + println(" */"); + + HiLowEmitter e = new HiLowEmitter("RowMap"); + e.emitInit(); + for (int i = 0; i < dfa.numStates; i++) { + e.emit(rowMap[i]*numCols); + } + e.emitUnpack(); + println(e.toString()); + } + + + private void emitAttributes() { + println(" /**"); + println(" * ZZ_ATTRIBUTE[aState] contains the attributes of state aState"); + println(" */"); + + CountEmitter e = new CountEmitter("Attribute"); + e.emitInit(); + + int count = 1; + int value = 0; + if ( dfa.isFinal[0] ) value = FINAL; + if ( dfa.isPushback[0] ) value|= PUSHBACK; + if ( dfa.isLookEnd[0] ) value|= LOOKEND; + if ( !isTransition[0] ) value|= NOLOOK; + + for (int i = 1; i < dfa.numStates; i++) { + int attribute = 0; + if ( dfa.isFinal[i] ) attribute = FINAL; + if ( dfa.isPushback[i] ) attribute|= PUSHBACK; + if ( dfa.isLookEnd[i] ) attribute|= LOOKEND; + if ( !isTransition[i] ) attribute|= NOLOOK; + + if (value == attribute) { + count++; + } + else { + e.emit(count, value); + count = 1; + value = attribute; + } + } + + e.emit(count, value); + e.emitUnpack(); + + println(e.toString()); + } + + + private void emitClassCode() { + if ( scanner.eofCode != null ) { + println(" /** denotes if the user-EOF-code has already been executed */"); + println(" private boolean zzEOFDone;"); + println(""); + } + + if ( scanner.classCode != null ) { + println(" /* user code: */"); + println(scanner.classCode); + } + } + + private void emitConstructorDecl() { + + print(" "); + + if ( scanner.isPublic ) print("public "); + print( scanner.className ); + print("(java.io.Reader in)"); + + if ( scanner.initThrow != null ) { + print(" throws "); + print( scanner.initThrow ); + } + + println(" {"); + + if ( scanner.initCode != null ) { + print(" "); + print( scanner.initCode ); + } + + println(" this.zzReader = in;"); + + println(" }"); + println(); + + + println(" /**"); + println(" * Creates a new scanner."); + println(" * There is also java.io.Reader version of this constructor."); + println(" *"); + println(" * @param in the java.io.Inputstream to read input from."); + println(" */"); + + print(" "); + if ( scanner.isPublic ) print("public "); + print( scanner.className ); + print("(java.io.InputStream in)"); + + if ( scanner.initThrow != null ) { + print(" throws "); + print( scanner.initThrow ); + } + + println(" {"); + println(" this(new java.io.InputStreamReader(in));"); + println(" }"); + } + + + private void emitDoEOF() { + if ( scanner.eofCode == null ) return; + + println(" /**"); + println(" * Contains user EOF-code, which will be executed exactly once,"); + println(" * when the end of file is reached"); + println(" */"); + + print(" private void zzDoEOF()"); + + if ( scanner.eofThrow != null ) { + print(" throws "); + print(scanner.eofThrow); + } + + println(" {"); + + println(" if (!zzEOFDone) {"); + println(" zzEOFDone = true;"); + println(" "+scanner.eofCode ); + println(" }"); + println(" }"); + println(""); + println(""); + } + + private void emitLexFunctHeader() { + + if (scanner.cupCompatible) { + // force public, because we have to implement java_cup.runtime.Symbol + print(" public "); + } + else { + print(" "+visibility+" "); + } + + if ( scanner.tokenType == null ) { + if ( scanner.isInteger ) + print( "int" ); + else + if ( scanner.isIntWrap ) + print( "Integer" ); + else + print( "Yytoken" ); + } + else + print( scanner.tokenType ); + + print(" "); + + print(scanner.functionName); + + print("() throws java.io.IOException"); + + if ( scanner.lexThrow != null ) { + print(", "); + print(scanner.lexThrow); + } + + if ( scanner.scanErrorException != null ) { + print(", "); + print(scanner.scanErrorException); + } + + println(" {"); + + skel.emitNext(); + + if ( scanner.useRowMap ) { + println(" int [] zzTransL = ZZ_TRANS;"); + println(" int [] zzRowMapL = ZZ_ROWMAP;"); + println(" int [] zzAttrL = ZZ_ATTRIBUTE;"); + + } + + if ( scanner.lookAheadUsed ) { + println(" int zzPushbackPosL = zzPushbackPos = -1;"); + println(" boolean zzWasPushback;"); + } + + skel.emitNext(); + + if ( scanner.charCount ) { + println(" yychar+= zzMarkedPosL-zzStartRead;"); + println(""); + } + + if ( scanner.lineCount || scanner.columnCount ) { + println(" boolean zzR = false;"); + println(" for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL;"); + println(" zzCurrentPosL++) {"); + println(" switch (" + zzBufferLAccess("zzCurrentPosL") + ") {"); + println(" case '\\u000B':"); + println(" case '\\u000C':"); + println(" case '\\u0085':"); + println(" case '\\u2028':"); + println(" case '\\u2029':"); + if ( scanner.lineCount ) + println(" yyline++;"); + if ( scanner.columnCount ) + println(" yycolumn = 0;"); + println(" zzR = false;"); + println(" break;"); + println(" case '\\r':"); + if ( scanner.lineCount ) + println(" yyline++;"); + if ( scanner.columnCount ) + println(" yycolumn = 0;"); + println(" zzR = true;"); + println(" break;"); + println(" case '\\n':"); + println(" if (zzR)"); + println(" zzR = false;"); + println(" else {"); + if ( scanner.lineCount ) + println(" yyline++;"); + if ( scanner.columnCount ) + println(" yycolumn = 0;"); + println(" }"); + println(" break;"); + println(" default:"); + println(" zzR = false;"); + if ( scanner.columnCount ) + println(" yycolumn++;"); + println(" }"); + println(" }"); + println(); + + if ( scanner.lineCount ) { + println(" if (zzR) {"); + println(" // peek one character ahead if it is \\n (if we have counted one line too much)"); + println(" boolean zzPeek;"); + println(" if (zzMarkedPosL < zzEndReadL)"); + println(" zzPeek = " + zzBufferLAccess("zzMarkedPosL") + " == '\\n';"); + println(" else if (zzAtEOF)"); + println(" zzPeek = false;"); + println(" else {"); + println(" boolean eof = zzRefill();"); + println(" zzEndReadL = zzEndRead;"); + println(" zzMarkedPosL = zzMarkedPos;"); + println(" zzBufferL = zzBuffer;"); + println(" if (eof) "); + println(" zzPeek = false;"); + println(" else "); + println(" zzPeek = " + zzBufferLAccess("zzMarkedPosL") + " == '\\n';"); + println(" }"); + println(" if (zzPeek) yyline--;"); + println(" }"); + } + } + + if ( scanner.bolUsed ) { + // zzMarkedPos > zzStartRead <=> last match was not empty + // if match was empty, last value of zzAtBOL can be used + // zzStartRead is always >= 0 + println(" if (zzMarkedPosL > zzStartRead) {"); + println(" switch (" + zzBufferLAccess("zzMarkedPosL-1") + ") {"); + println(" case '\\n':"); + println(" case '\\u000B':"); + println(" case '\\u000C':"); + println(" case '\\u0085':"); + println(" case '\\u2028':"); + println(" case '\\u2029':"); + println(" zzAtBOL = true;"); + println(" break;"); + println(" case '\\r': "); + println(" if (zzMarkedPosL < zzEndReadL)"); + println(" zzAtBOL = " + zzBufferLAccess("zzMarkedPosL") + " != '\\n';"); + println(" else if (zzAtEOF)"); + println(" zzAtBOL = false;"); + println(" else {"); + println(" boolean eof = zzRefill();"); + println(" zzMarkedPosL = zzMarkedPos;"); + println(" zzEndReadL = zzEndRead;"); + println(" zzBufferL = zzBuffer;"); + println(" if (eof) "); + println(" zzAtBOL = false;"); + println(" else "); + println(" zzAtBOL = " + zzBufferLAccess("zzMarkedPosL") + " != '\\n';"); + println(" }"); + println(" break;"); + println(" default:"); + println(" zzAtBOL = false;"); + println(" }"); + println(" }"); + } + + skel.emitNext(); + + if (scanner.bolUsed) { + println(" if (zzAtBOL)"); + println(" zzState = ZZ_LEXSTATE[zzLexicalState+1];"); + println(" else"); + println(" zzState = ZZ_LEXSTATE[zzLexicalState];"); + println(); + } + else { + println(" zzState = zzLexicalState;"); + println(); + } + + if (scanner.lookAheadUsed) + println(" zzWasPushback = false;"); + + skel.emitNext(); + } + + + private void emitGetRowMapNext() { + println(" int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];"); + println(" if (zzNext == "+DFA.NO_TARGET+") break zzForAction;"); + println(" zzState = zzNext;"); + println(); + + println(" int zzAttributes = zzAttrL[zzState];"); + + if ( scanner.lookAheadUsed ) { + println(" if ( (zzAttributes & "+PUSHBACK+") == "+PUSHBACK+" )"); + println(" zzPushbackPosL = zzCurrentPosL;"); + println(); + } + + println(" if ( (zzAttributes & "+FINAL+") == "+FINAL+" ) {"); + if ( scanner.lookAheadUsed ) + println(" zzWasPushback = (zzAttributes & "+LOOKEND+") == "+LOOKEND+";"); + + skel.emitNext(); + + println(" if ( (zzAttributes & "+NOLOOK+") == "+NOLOOK+" ) break zzForAction;"); + + skel.emitNext(); + } + + private void emitTransitionTable() { + transformTransitionTable(); + + println(" zzInput = zzCMapL[zzInput];"); + println(); + + if ( scanner.lookAheadUsed ) + println(" boolean zzPushback = false;"); + + println(" boolean zzIsFinal = false;"); + println(" boolean zzNoLookAhead = false;"); + println(); + + println(" zzForNext: { switch (zzState) {"); + + for (int state = 0; state < dfa.numStates; state++) + if (isTransition[state]) emitState(state); + + println(" default:"); + println(" // if this is ever reached, there is a serious bug in JFlex"); + println(" zzScanError(ZZ_UNKNOWN_ERROR);"); + println(" break;"); + println(" } }"); + println(); + + println(" if ( zzIsFinal ) {"); + + if ( scanner.lookAheadUsed ) + println(" zzWasPushback = zzPushback;"); + + skel.emitNext(); + + println(" if ( zzNoLookAhead ) break zzForAction;"); + + skel.emitNext(); + } + + + /** + * Escapes all " ' \ tabs and newlines + */ + private String escapify(String s) { + StringBuffer result = new StringBuffer(s.length()*2); + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '\'': result.append("\\\'"); break; + case '\"': result.append("\\\""); break; + case '\\': result.append("\\\\"); break; + case '\t': result.append("\\t"); break; + case '\r': if (i+1 == s.length() || s.charAt(i+1) != '\n') result.append("\"+ZZ_NL+\""); + break; + case '\n': result.append("\"+ZZ_NL+\""); break; + default: result.append(c); + } + } + + return result.toString(); + } + + public void emitActionTable() { + int lastAction = 1; + int count = 0; + int value = 0; + + println(" /** "); + println(" * Translates DFA states to action switch labels."); + println(" */"); + CountEmitter e = new CountEmitter("Action"); + e.emitInit(); + + for (int i = 0; i < dfa.numStates; i++) { + int newVal; + if ( dfa.isFinal[i] ) { + Action action = dfa.action[i]; + Integer stored = (Integer) actionTable.get(action); + if ( stored == null ) { + stored = new Integer(lastAction++); + actionTable.put(action, stored); + } + newVal = stored.intValue(); + } + else { + newVal = 0; + } + + if (value == newVal) { + count++; + } + else { + if (count > 0) e.emit(count,value); + count = 1; + value = newVal; + } + } + + if (count > 0) e.emit(count,value); + + e.emitUnpack(); + println(e.toString()); + } + + private void emitActions() { + println(" switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {"); + + int i = actionTable.size()+1; + Enumeration actions = actionTable.keys(); + while ( actions.hasMoreElements() ) { + Action action = (Action) actions.nextElement(); + int label = ((Integer) actionTable.get(action)).intValue(); + + println(" case "+label+": "); + + if ( scanner.debugOption ) { + print(" System.out.println("); + if ( scanner.lineCount ) + print("\"line: \"+(yyline+1)+\" \"+"); + if ( scanner.columnCount ) + print("\"col: \"+(yycolumn+1)+\" \"+"); + println("\"match: --\"+yytext()+\"--\");"); + print(" System.out.println(\"action ["+action.priority+"] { "); + print(escapify(action.content)); + println(" }\");"); + } + + println(" { "+action.content); + println(" }"); + println(" case "+(i++)+": break;"); + } + } + + private void emitEOFVal() { + EOFActions eofActions = parser.getEOFActions(); + + if ( scanner.eofCode != null ) + println(" zzDoEOF();"); + + if ( eofActions.numActions() > 0 ) { + println(" switch (zzLexicalState) {"); + + Enumeration stateNames = scanner.states.names(); + + // record lex states already emitted: + Hashtable used = new Hashtable(); + + // pick a start value for break case labels. + // must be larger than any value of a lex state: + int last = dfa.numStates; + + while ( stateNames.hasMoreElements() ) { + String name = (String) stateNames.nextElement(); + int num = scanner.states.getNumber(name).intValue(); + Action action = eofActions.getAction(num); + + // only emit code if the lex state is not redundant, so + // that case labels don't overlap + // (redundant = points to the same dfa state as another one). + // applies only to scanners that don't use BOL, because + // in BOL scanners lex states get mapped at runtime, so + // case labels will always be unique. + boolean unused = true; + if (!scanner.bolUsed) { + Integer key = new Integer(dfa.lexState[2*num]); + unused = used.get(key) == null; + + if (!unused) + Out.warning("Lexical states <"+name+"> and <"+used.get(key)+"> are equivalent."); + else + used.put(key,name); + } + + if (action != null && unused) { + println(" case "+name+": {"); + if ( scanner.debugOption ) { + print(" System.out.println("); + if ( scanner.lineCount ) + print("\"line: \"+(yyline+1)+\" \"+"); + if ( scanner.columnCount ) + print("\"col: \"+(yycolumn+1)+\" \"+"); + println("\"match: <>\");"); + print(" System.out.println(\"action ["+action.priority+"] { "); + print(escapify(action.content)); + println(" }\");"); + } + println(" "+action.content); + println(" }"); + println(" case "+(++last)+": break;"); + } + } + + println(" default:"); + } + + Action defaultAction = eofActions.getDefault(); + + if (defaultAction != null) { + println(" {"); + if ( scanner.debugOption ) { + print(" System.out.println("); + if ( scanner.lineCount ) + print("\"line: \"+(yyline+1)+\" \"+"); + if ( scanner.columnCount ) + print("\"col: \"+(yycolumn+1)+\" \"+"); + println("\"match: <>\");"); + print(" System.out.println(\"action ["+defaultAction.priority+"] { "); + print(escapify(defaultAction.content)); + println(" }\");"); + } + println(" " + defaultAction.content); + println(" }"); + } + else if ( scanner.eofVal != null ) + println(" { " + scanner.eofVal + " }"); + else if ( scanner.isInteger ) + println(" return YYEOF;"); + else + println(" return null;"); + + if (eofActions.numActions() > 0) + println(" }"); + } + + private void emitState(int state) { + + println(" case "+state+":"); + println(" switch (zzInput) {"); + + int defaultTransition = getDefaultTransition(state); + + for (int next = 0; next < dfa.numStates; next++) { + + if ( next != defaultTransition && table[state][next] != null ) { + emitTransition(state, next); + } + } + + if ( defaultTransition != DFA.NO_TARGET && noTarget[state] != null ) { + emitTransition(state, DFA.NO_TARGET); + } + + emitDefaultTransition(state, defaultTransition); + + println(" }"); + println(""); + } + + private void emitTransition(int state, int nextState) { + + CharSetEnumerator chars; + + if (nextState != DFA.NO_TARGET) + chars = table[state][nextState].characters(); + else + chars = noTarget[state].characters(); + + print(" case "); + print((int)chars.nextElement()); + print(": "); + + while ( chars.hasMoreElements() ) { + println(); + print(" case "); + print((int)chars.nextElement()); + print(": "); + } + + if ( nextState != DFA.NO_TARGET ) { + if ( dfa.isFinal[nextState] ) + print("zzIsFinal = true; "); + + if ( dfa.isPushback[nextState] ) + print("zzPushbackPosL = zzCurrentPosL; "); + + if ( dfa.isLookEnd[nextState] ) + print("zzPushback = true; "); + + if ( !isTransition[nextState] ) + print("zzNoLookAhead = true; "); + + if ( nextState == state ) + println("break zzForNext;"); + else + println("zzState = "+nextState+"; break zzForNext;"); + } + else + println("break zzForAction;"); + } + + private void emitDefaultTransition(int state, int nextState) { + print(" default: "); + + if ( nextState != DFA.NO_TARGET ) { + if ( dfa.isFinal[nextState] ) + print("zzIsFinal = true; "); + + if ( dfa.isPushback[nextState] ) + print("zzPushbackPosL = zzCurrentPosL; "); + + if ( dfa.isLookEnd[nextState] ) + print("zzPushback = true; "); + + if ( !isTransition[nextState] ) + print("zzNoLookAhead = true; "); + + if ( nextState == state ) + println("break zzForNext;"); + else + println("zzState = "+nextState+"; break zzForNext;"); + } + else + println( "break zzForAction;" ); + } + + private void emitPushback() { + println(" if (zzWasPushback)"); + println(" zzMarkedPos = zzPushbackPosL;"); + } + + private int getDefaultTransition(int state) { + int max = 0; + + for (int i = 0; i < dfa.numStates; i++) { + if ( table[state][max] == null ) + max = i; + else + if ( table[state][i] != null && table[state][max].size() < table[state][i].size() ) + max = i; + } + + if ( table[state][max] == null ) return DFA.NO_TARGET; + if ( noTarget[state] == null ) return max; + + if ( table[state][max].size() < noTarget[state].size() ) + max = DFA.NO_TARGET; + + return max; + } + + // for switch statement: + private void transformTransitionTable() { + + int numInput = parser.getCharClasses().getNumClasses()+1; + + int i; + char j; + + table = new CharSet[dfa.numStates][dfa.numStates]; + noTarget = new CharSet[dfa.numStates]; + + for (i = 0; i < dfa.numStates; i++) + for (j = 0; j < dfa.numInput; j++) { + + int nextState = dfa.table[i][j]; + + if ( nextState == DFA.NO_TARGET ) { + if ( noTarget[i] == null ) + noTarget[i] = new CharSet(numInput, colMap[j]); + else + noTarget[i].add(colMap[j]); + } + else { + if ( table[i][nextState] == null ) + table[i][nextState] = new CharSet(numInput, colMap[j]); + else + table[i][nextState].add(colMap[j]); + } + } + } + + private void findActionStates() { + isTransition = new boolean [dfa.numStates]; + + for (int i = 0; i < dfa.numStates; i++) { + char j = 0; + while ( !isTransition[i] && j < dfa.numInput ) + isTransition[i] = dfa.table[i][j++] != DFA.NO_TARGET; + } + } + + + private void reduceColumns() { + colMap = new int [dfa.numInput]; + colKilled = new boolean [dfa.numInput]; + + int i,j,k; + int translate = 0; + boolean equal; + + numCols = dfa.numInput; + + for (i = 0; i < dfa.numInput; i++) { + + colMap[i] = i-translate; + + for (j = 0; j < i; j++) { + + // test for equality: + k = -1; + equal = true; + while (equal && ++k < dfa.numStates) + equal = dfa.table[k][i] == dfa.table[k][j]; + + if (equal) { + translate++; + colMap[i] = colMap[j]; + colKilled[i] = true; + numCols--; + break; + } // if + } // for j + } // for i + } + + private void reduceRows() { + rowMap = new int [dfa.numStates]; + rowKilled = new boolean [dfa.numStates]; + + int i,j,k; + int translate = 0; + boolean equal; + + numRows = dfa.numStates; + + // i is the state to add to the new table + for (i = 0; i < dfa.numStates; i++) { + + rowMap[i] = i-translate; + + // check if state i can be removed (i.e. already + // exists in entries 0..i-1) + for (j = 0; j < i; j++) { + + // test for equality: + k = -1; + equal = true; + while (equal && ++k < dfa.numInput) + equal = dfa.table[i][k] == dfa.table[j][k]; + + if (equal) { + translate++; + rowMap[i] = rowMap[j]; + rowKilled[i] = true; + numRows--; + break; + } // if + } // for j + } // for i + + } + + + /** + * Set up EOF code sectioin according to scanner.eofcode + */ + private void setupEOFCode() { + if (scanner.eofclose) { + scanner.eofCode = LexScan.conc(scanner.eofCode, " yyclose();"); + scanner.eofThrow = LexScan.concExc(scanner.eofThrow, "java.io.IOException"); + } + } + + + /** + * Main Emitter method. + */ + public void emit() { + + setupEOFCode(); + + if (scanner.functionName == null) + scanner.functionName = "yylex"; + + reduceColumns(); + findActionStates(); + + emitHeader(); + emitUserCode(); + emitClassName(); + + skel.emitNext(); + + println(" private static final int ZZ_BUFFERSIZE = "+scanner.bufferSize+";"); + + if (scanner.debugOption) { + println(" private static final String ZZ_NL = System.getProperty(\"line.separator\");"); + } + + skel.emitNext(); + + emitLexicalStates(); + + emitCharMapArray(); + + emitActionTable(); + + if (scanner.useRowMap) { + reduceRows(); + + emitRowMapArray(); + + if (scanner.packed) + emitDynamicInit(); + else + emitZZTrans(); + } + + skel.emitNext(); + + if (scanner.useRowMap) + emitAttributes(); + + skel.emitNext(); + + emitClassCode(); + + skel.emitNext(); + + emitConstructorDecl(); + + emitCharMapInitFunction(); + + skel.emitNext(); + + emitScanError(); + + skel.emitNext(); + + emitDoEOF(); + + skel.emitNext(); + + emitLexFunctHeader(); + + emitNextInput(); + + if (scanner.useRowMap) + emitGetRowMapNext(); + else + emitTransitionTable(); + + if (scanner.lookAheadUsed) + emitPushback(); + + skel.emitNext(); + + emitActions(); + + skel.emitNext(); + + emitEOFVal(); + + skel.emitNext(); + + emitNoMatch(); + + skel.emitNext(); + + emitMain(); + + skel.emitNext(); + + out.close(); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/ErrorMessages.java b/tools/lexer/jflex-1.4/src/JFlex/ErrorMessages.java new file mode 100644 index 000000000000..11da2770865c --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/ErrorMessages.java @@ -0,0 +1,140 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software); you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY); without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program); if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + + +/** + * Central class for all kinds of JFlex messages. + * + * [Is not yet used exclusively, but should] + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.8 $, $Date: 2004/11/06 23:03:30 $ + */ +public class ErrorMessages { + private String key; + + private static final ResourceBundle RESOURCE_BUNDLE = + ResourceBundle.getBundle("JFlex.Messages"); + + private ErrorMessages(String key) { + this.key = key; + } + + public static String get(ErrorMessages msg) { + try { + return RESOURCE_BUNDLE.getString(msg.key); + } catch (MissingResourceException e) { + return '!' + msg.key + '!'; + } + } + + public static String get(ErrorMessages msg, String data) { + Object [] args = { data }; + return MessageFormat.format(get(msg),args); + } + + public static String get(ErrorMessages msg, String data1, String data2) { + Object [] args = { data1, data2 }; + return MessageFormat.format(get(msg),args); + } + + public static String get(ErrorMessages msg, int data) { + Object [] args = { new Integer(data) }; + return MessageFormat.format(get(msg),args); + } + + // typesafe enumeration (generated, do not edit) + public static ErrorMessages UNTERMINATED_STR = new ErrorMessages("UNTERMINATED_STR"); + public static ErrorMessages EOF_WO_ACTION = new ErrorMessages("EOF_WO_ACTION"); + public static ErrorMessages EOF_SINGLERULE = new ErrorMessages("EOF_SINGLERULE"); + public static ErrorMessages UNKNOWN_OPTION = new ErrorMessages("UNKNOWN_OPTION"); + public static ErrorMessages UNEXPECTED_CHAR = new ErrorMessages("UNEXPECTED_CHAR"); + public static ErrorMessages UNEXPECTED_NL = new ErrorMessages("UNEXPECTED_NL"); + public static ErrorMessages LEXSTATE_UNDECL = new ErrorMessages("LEXSTATE_UNDECL"); + public static ErrorMessages STATE_IDENT_EXP = new ErrorMessages("STATE_IDENT_EXP"); + public static ErrorMessages REPEAT_ZERO = new ErrorMessages("REPEAT_ZERO"); + public static ErrorMessages REPEAT_GREATER = new ErrorMessages("REPEAT_GREATER"); + public static ErrorMessages REGEXP_EXPECTED = new ErrorMessages("REGEXP_EXPECTED"); + public static ErrorMessages MACRO_UNDECL = new ErrorMessages("MACRO_UNDECL"); + public static ErrorMessages CHARSET_2_SMALL = new ErrorMessages("CHARSET_2_SMALL"); + public static ErrorMessages CS2SMALL_STRING = new ErrorMessages("CS2SMALL_STRING"); + public static ErrorMessages CS2SMALL_CHAR = new ErrorMessages("CS2SMALL_CHAR"); + public static ErrorMessages CHARCLASS_MACRO = new ErrorMessages("CHARCLASS_MACRO"); + public static ErrorMessages UNKNOWN_SYNTAX = new ErrorMessages("UNKNOWN_SYNTAX"); + public static ErrorMessages SYNTAX_ERROR = new ErrorMessages("SYNTAX_ERROR"); + public static ErrorMessages NOT_AT_BOL = new ErrorMessages("NOT_AT_BOL"); + public static ErrorMessages NO_MATCHING_BR = new ErrorMessages("NO_MATCHING_BR"); + public static ErrorMessages EOF_IN_ACTION = new ErrorMessages("EOF_IN_ACTION"); + public static ErrorMessages EOF_IN_COMMENT = new ErrorMessages("EOF_IN_COMMENT"); + public static ErrorMessages EOF_IN_STRING = new ErrorMessages("EOF_IN_STRING"); + public static ErrorMessages EOF_IN_MACROS = new ErrorMessages("EOF_IN_MACROS"); + public static ErrorMessages EOF_IN_STATES = new ErrorMessages("EOF_IN_STATES"); + public static ErrorMessages EOF_IN_REGEXP = new ErrorMessages("EOF_IN_REGEXP"); + public static ErrorMessages UNEXPECTED_EOF = new ErrorMessages("UNEXPECTED_EOF"); + public static ErrorMessages NO_LEX_SPEC = new ErrorMessages("NO_LEX_SPEC"); + public static ErrorMessages NO_LAST_ACTION = new ErrorMessages("NO_LAST_ACTION"); + public static ErrorMessages LOOKAHEAD_ERROR = new ErrorMessages("LOOKAHEAD_ERROR"); + public static ErrorMessages NO_DIRECTORY = new ErrorMessages("NO_DIRECTORY"); + public static ErrorMessages NO_SKEL_FILE = new ErrorMessages("NO_SKEL_FILE"); + public static ErrorMessages WRONG_SKELETON = new ErrorMessages("WRONG_SKELETON"); + public static ErrorMessages OUT_OF_MEMORY = new ErrorMessages("OUT_OF_MEMORY"); + public static ErrorMessages QUIL_INITTHROW = new ErrorMessages("QUIL_INITTHROW"); + public static ErrorMessages QUIL_EOFTHROW = new ErrorMessages("QUIL_EOFTHROW"); + public static ErrorMessages QUIL_YYLEXTHROW = new ErrorMessages("QUIL_YYLEXTHROW"); + public static ErrorMessages ZERO_STATES = new ErrorMessages("ZERO_STATES"); + public static ErrorMessages NO_BUFFER_SIZE = new ErrorMessages("NO_BUFFER_SIZE"); + public static ErrorMessages NOT_READABLE = new ErrorMessages("NOT_READABLE"); + public static ErrorMessages FILE_CYCLE = new ErrorMessages("FILE_CYCLE"); + public static ErrorMessages FILE_WRITE = new ErrorMessages("FILE_WRITE"); + public static ErrorMessages QUIL_SCANERROR = new ErrorMessages("QUIL_SCANERROR"); + public static ErrorMessages NEVER_MATCH = new ErrorMessages("NEVER_MATCH"); + public static ErrorMessages QUIL_THROW = new ErrorMessages("QUIL_THROW"); + public static ErrorMessages EOL_IN_CHARCLASS = new ErrorMessages("EOL_IN_CHARCLASS"); + public static ErrorMessages QUIL_CUPSYM = new ErrorMessages("QUIL_CUPSYM"); + public static ErrorMessages CUPSYM_AFTER_CUP = new ErrorMessages("CUPSYM_AFTER_CUP"); + public static ErrorMessages ALREADY_RUNNING = new ErrorMessages("ALREADY_RUNNING"); + public static ErrorMessages CANNOT_READ_SKEL = new ErrorMessages("CANNOT_READ_SKEL"); + public static ErrorMessages READING_SKEL = new ErrorMessages("READING_SKEL"); + public static ErrorMessages SKEL_IO_ERROR = new ErrorMessages("SKEL_IO_ERROR"); + public static ErrorMessages SKEL_IO_ERROR_DEFAULT = new ErrorMessages("SKEL_IO_ERROR_DEFAULT"); + public static ErrorMessages READING = new ErrorMessages("READING"); + public static ErrorMessages CANNOT_OPEN = new ErrorMessages("CANNOT_OPEN"); + public static ErrorMessages NFA_IS = new ErrorMessages("NFA_IS"); + public static ErrorMessages NFA_STATES = new ErrorMessages("NFA_STATES"); + public static ErrorMessages DFA_TOOK = new ErrorMessages("DFA_TOOK"); + public static ErrorMessages DFA_IS = new ErrorMessages("DFA_IS"); + public static ErrorMessages MIN_TOOK = new ErrorMessages("MIN_TOOK"); + public static ErrorMessages MIN_DFA_IS = new ErrorMessages("MIN_DFA_IS"); + public static ErrorMessages WRITE_TOOK = new ErrorMessages("WRITE_TOOK"); + public static ErrorMessages TOTAL_TIME = new ErrorMessages("TOTAL_TIME"); + public static ErrorMessages IO_ERROR = new ErrorMessages("IO_ERROR"); + public static ErrorMessages THIS_IS_JFLEX = new ErrorMessages("THIS_IS_JFLEX"); + public static ErrorMessages UNKNOWN_COMMANDLINE = new ErrorMessages("UNKNOWN_COMMANDLINE"); + public static ErrorMessages MACRO_CYCLE = new ErrorMessages("MACRO_CYCLE"); + public static ErrorMessages MACRO_DEF_MISSING = new ErrorMessages("MACRO_DEF_MISSING"); + public static ErrorMessages PARSING_TOOK = new ErrorMessages("PARSING_TOOK"); + public static ErrorMessages NFA_TOOK = new ErrorMessages("NFA_TOOK"); +} \ No newline at end of file diff --git a/tools/lexer/jflex-1.4/src/JFlex/GeneratorException.java b/tools/lexer/jflex-1.4/src/JFlex/GeneratorException.java new file mode 100644 index 000000000000..b4a59e688f85 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/GeneratorException.java @@ -0,0 +1,36 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Thrown when code generation has to be aborted. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +public class GeneratorException extends RuntimeException { + + public GeneratorException() { + super("Generation aborted"); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/HiLowEmitter.java b/tools/lexer/jflex-1.4/src/JFlex/HiLowEmitter.java new file mode 100644 index 000000000000..450cc2fc241a --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/HiLowEmitter.java @@ -0,0 +1,88 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * jflex * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +/** + * HiLowEmitter + * + * @author Gerwin Klein + * @version $Revision: 1.5 $, $Date: 2004/04/12 10:07:48 $ + */ +public class HiLowEmitter extends PackEmitter { + + /** number of entries in expanded array */ + private int numEntries; + + /** + * Create new emitter for values in [0, 0xFFFFFFFF] using hi/low encoding. + * + * @param name the name of the generated array + */ + public HiLowEmitter(String name) { + super(name); + } + + /** + * Emits hi/low pair unpacking code for the generated array. + * + * @see JFlex.PackEmitter#emitUnPack() + */ + public void emitUnpack() { + // close last string chunk: + println("\";"); + nl(); + println(" private static int [] zzUnpack"+name+"() {"); + println(" int [] result = new int["+numEntries+"];"); + println(" int offset = 0;"); + + for (int i = 0; i < chunks; i++) { + println(" offset = zzUnpack"+name+"("+constName()+"_PACKED_"+i+", offset, result);"); + } + + println(" return result;"); + println(" }"); + + nl(); + println(" private static int zzUnpack"+name+"(String packed, int offset, int [] result) {"); + println(" int i = 0; /* index in packed string */"); + println(" int j = offset; /* index in unpacked array */"); + println(" int l = packed.length();"); + println(" while (i < l) {"); + println(" int high = packed.charAt(i++) << 16;"); + println(" result[j++] = high | packed.charAt(i++);"); + println(" }"); + println(" return j;"); + println(" }"); + } + + /** + * Emit one value using two characters. + * + * @param val the value to emit + * @prec 0 <= val <= 0xFFFFFFFF + */ + public void emit(int val) { + numEntries+= 1; + breaks(); + emitUC(val >> 16); + emitUC(val & 0xFFFF); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/IntCharSet.java b/tools/lexer/jflex-1.4/src/JFlex/IntCharSet.java new file mode 100644 index 000000000000..d05200602cfc --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/IntCharSet.java @@ -0,0 +1,411 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.Vector; + + +/** + * CharSet implemented with intervalls + * + * [fixme: optimizations possible] + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.9 $, $Date: 2004/11/07 00:12:48 $ + */ +public final class IntCharSet { + + private final static boolean DEBUG = false; + + /* invariant: all intervals are disjoint, ordered */ + private Vector intervalls; + private int pos; + + public IntCharSet() { + this.intervalls = new Vector(); + } + + public IntCharSet(char c) { + this(new Interval(c,c)); + } + + public IntCharSet(Interval intervall) { + this(); + intervalls.addElement(intervall); + } + + public IntCharSet(Vector /* Interval */ chars) { + int size = chars.size(); + + this.intervalls = new Vector(size); + + for (int i = 0; i < size; i++) + add( (Interval) chars.elementAt(i) ); + } + + + + + /** + * returns the index of the intervall that contains + * the character c, -1 if there is no such intevall + * + * @prec: true + * @post: -1 <= return < intervalls.size() && + * (return > -1 --> intervalls[return].contains(c)) + * + * @param c the character + * @return the index of the enclosing interval, -1 if no such interval + */ + private int indexOf(char c) { + int start = 0; + int end = intervalls.size()-1; + + while (start <= end) { + int check = (start+end) / 2; + Interval i = (Interval) intervalls.elementAt(check); + + if (start == end) + return i.contains(c) ? start : -1; + + if (c < i.start) { + end = check-1; + continue; + } + + if (c > i.end) { + start = check+1; + continue; + } + + return check; + } + + return -1; + } + + public IntCharSet add(IntCharSet set) { + for (int i = 0; i < set.intervalls.size(); i++) + add( (Interval) set.intervalls.elementAt(i) ); + return this; + } + + public void add(Interval intervall) { + + int size = intervalls.size(); + + for (int i = 0; i < size; i++) { + Interval elem = (Interval) intervalls.elementAt(i); + + if ( elem.end+1 < intervall.start ) continue; + + if ( elem.contains(intervall) ) return; + + if ( elem.start > intervall.end+1 ) { + intervalls.insertElementAt(new Interval(intervall), i); + return; + } + + if (intervall.start < elem.start) + elem.start = intervall.start; + + if (intervall.end <= elem.end) + return; + + elem.end = intervall.end; + + i++; + // delete all x with x.contains( intervall.end ) + while (i < size) { + Interval x = (Interval) intervalls.elementAt(i); + if (x.start > elem.end+1) return; + + elem.end = x.end; + intervalls.removeElementAt(i); + size--; + } + return; + } + + intervalls.addElement(new Interval(intervall)); + } + + public void add(char c) { + int size = intervalls.size(); + + for (int i = 0; i < size; i++) { + Interval elem = (Interval) intervalls.elementAt(i); + if (elem.end+1 < c) continue; + + if (elem.contains(c)) return; // already there, nothing to do + + // assert(elem.end+1 >= c && (elem.start > c || elem.end < c)); + + if (elem.start > c+1) { + intervalls.insertElementAt(new Interval(c,c), i); + return; + } + + // assert(elem.end+1 >= c && elem.start <= c+1 && (elem.start > c || elem.end < c)); + + if (c+1 == elem.start) { + elem.start = c; + return; + } + + // assert(elem.end+1 == c); + elem.end = c; + + // merge with next interval if it contains c + if (i+1 >= size) return; + Interval x = (Interval) intervalls.elementAt(i+1); + if (x.start <= c+1) { + elem.end = x.end; + intervalls.removeElementAt(i+1); + } + return; + } + + // end reached but nothing found -> append at end + intervalls.addElement(new Interval(c,c)); + } + + + public boolean contains(char singleChar) { + return indexOf(singleChar) >= 0; + } + + + /** + * o instanceof Interval + */ + public boolean equals(Object o) { + IntCharSet set = (IntCharSet) o; + if ( intervalls.size() != set.intervalls.size() ) return false; + + for (int i = 0; i < intervalls.size(); i++) { + if ( !intervalls.elementAt(i).equals( set.intervalls.elementAt(i)) ) + return false; + } + + return true; + } + + private char min(char a, char b) { + return a <= b ? a : b; + } + + private char max(char a, char b) { + return a >= b ? a : b; + } + + /* intersection */ + public IntCharSet and(IntCharSet set) { + if (DEBUG) { + Out.dump("intersection"); + Out.dump("this : "+this); + Out.dump("other : "+set); + } + + IntCharSet result = new IntCharSet(); + + int i = 0; // index in this.intervalls + int j = 0; // index in set.intervalls + + int size = intervalls.size(); + int setSize = set.intervalls.size(); + + while (i < size && j < setSize) { + Interval x = (Interval) this.intervalls.elementAt(i); + Interval y = (Interval) set.intervalls.elementAt(j); + + if (x.end < y.start) { + i++; + continue; + } + + if (y.end < x.start) { + j++; + continue; + } + + result.intervalls.addElement( + new Interval( + max(x.start, y.start), + min(x.end, y.end) + ) + ); + + if (x.end >= y.end) j++; + if (y.end >= x.end) i++; + } + + if (DEBUG) { + Out.dump("result: "+result); + } + + return result; + } + + /* complement */ + /* prec: this.contains(set), set != null */ + public void sub(IntCharSet set) { + if (DEBUG) { + Out.dump("complement"); + Out.dump("this : "+this); + Out.dump("other : "+set); + } + + int i = 0; // index in this.intervalls + int j = 0; // index in set.intervalls + + int setSize = set.intervalls.size(); + + while (i < intervalls.size() && j < setSize) { + Interval x = (Interval) this.intervalls.elementAt(i); + Interval y = (Interval) set.intervalls.elementAt(j); + + if (DEBUG) { + Out.dump("this : "+this); + Out.dump("this ["+i+"] : "+x); + Out.dump("other ["+j+"] : "+y); + } + + if (x.end < y.start) { + i++; + continue; + } + + if (y.end < x.start) { + j++; + continue; + } + + // x.end >= y.start && y.end >= x.start -> + // x.end <= y.end && x.start >= y.start (prec) + + if ( x.start == y.start && x.end == y.end ) { + intervalls.removeElementAt(i); + j++; + continue; + } + + // x.end <= y.end && x.start >= y.start && + // (x.end < y.end || x.start > y.start) -> + // x.start < x.end + + if ( x.start == y.start ) { + x.start = (char) (y.end+1); + j++; + continue; + } + + if ( x.end == y.end ) { + x.end = (char) (y.start-1); + i++; + j++; + continue; + } + + intervalls.insertElementAt(new Interval(x.start, (char) (y.start-1)), i); + x.start = (char) (y.end+1); + + i++; + j++; + } + + if (DEBUG) { + Out.dump("result: "+this); + } + } + + public boolean containsElements() { + return intervalls.size() > 0; + } + + public int numIntervalls() { + return intervalls.size(); + } + + // beware: depends on caller protocol, single user only + public Interval getNext() { + if (pos == intervalls.size()) pos = 0; + return (Interval) intervalls.elementAt(pos++); + } + + /** + * Create a caseless version of this charset. + *

+ * The caseless version contains all characters of this char set, + * and additionally all lower/upper/title case variants of the + * characters in this set. + * + * @return a caseless copy of this set + */ + public IntCharSet getCaseless() { + IntCharSet n = copy(); + + int size = intervalls.size(); + for (int i=0; i < size; i++) { + Interval elem = (Interval) intervalls.elementAt(i); + for (char c = elem.start; c <= elem.end; c++) { + n.add(Character.toLowerCase(c)); + n.add(Character.toUpperCase(c)); + n.add(Character.toTitleCase(c)); + } + } + + return n; + } + + + /** + * Make a string representation of this char set. + * + * @return a string representing this char set. + */ + public String toString() { + StringBuffer result = new StringBuffer("{ "); + + for (int i = 0; i < intervalls.size(); i++) + result.append( intervalls.elementAt(i) ); + + result.append(" }"); + + return result.toString(); + } + + + /** + * Return a (deep) copy of this char set + * + * @return the copy + */ + public IntCharSet copy() { + IntCharSet result = new IntCharSet(); + int size = intervalls.size(); + for (int i=0; i < size; i++) { + Interval iv = ((Interval) intervalls.elementAt(i)).copy(); + result.intervalls.addElement(iv); + } + return result; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/IntPair.java b/tools/lexer/jflex-1.4/src/JFlex/IntPair.java new file mode 100644 index 000000000000..012eda6960e2 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/IntPair.java @@ -0,0 +1,57 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Simple pair of integers. + * + * Used in NFA to represent a partial NFA by its start and end state. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +final class IntPair { + + int start; + int end; + + IntPair(int start, int end) { + this.start = start; + this.end = end; + } + + public int hashCode() { + return end + (start << 8); + } + + public boolean equals(Object o) { + if ( o instanceof IntPair ) { + IntPair p = (IntPair) o; + return start == p.start && end == p.end; + } + return false; + } + + public String toString() { + return "("+start+","+end+")"; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Interval.java b/tools/lexer/jflex-1.4/src/JFlex/Interval.java new file mode 100644 index 000000000000..64d30a283335 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Interval.java @@ -0,0 +1,163 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * An intervall of characters with basic operations. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:30 $ + */ +public final class Interval { + + /* start and end of the intervall */ + public char start, end; + + + /** + * Constuct a new intervall from start to end. + * + * @param start first character the intervall should contain + * @param end last character the intervall should contain + */ + public Interval(char start, char end) { + this.start = start; + this.end = end; + } + + + /** + * Copy constructor + */ + public Interval(Interval other) { + this.start = other.start; + this.end = other.end; + } + + + /** + * Return true iff point is contained in this intervall. + * + * @param point the character to check + */ + public boolean contains(char point) { + return start <= point && end >= point; + } + + + /** + * Return true iff this intervall completely contains the + * other one. + * + * @param other the other intervall + */ + public boolean contains(Interval other) { + return this.start <= other.start && this.end >= other.end; + } + + + /** + * Return true if o is an intervall + * with the same borders. + * + * @param o the object to check equality with + */ + public boolean equals(Object o) { + if ( o == this ) return true; + if ( !(o instanceof Interval) ) return false; + + Interval other = (Interval) o; + return other.start == this.start && other.end == this.end; + } + + + /** + * Set a new last character + * + * @param end the new last character of this intervall + */ + public void setEnd(char end) { + this.end = end; + } + + + /** + * Set a new first character + * + * @param start the new first character of this intervall + */ + public void setStart(char start) { + this.start = start; + } + + + /** + * Check wether a character is printable. + * + * @param c the character to check + */ + private static boolean isPrintable(char c) { + // fixme: should make unicode test here + return c > 31 && c < 127; + } + + + /** + * Get a String representation of this intervall. + * + * @return a string "[start-end]" or + * "[start]" (if there is only one character in + * the intervall) where start and + * end are either a number (the character code) + * or something of the from 'a'. + */ + public String toString() { + StringBuffer result = new StringBuffer("["); + + if ( isPrintable(start) ) + result.append("'"+start+"'"); + else + result.append( (int) start ); + + if (start != end) { + result.append("-"); + + if ( isPrintable(end) ) + result.append("'"+end+"'"); + else + result.append( (int) end ); + } + + result.append("]"); + return result.toString(); + } + + + /** + * Make a copy of this interval. + * + * @return the copy + */ + public Interval copy() { + return new Interval(start,end); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/LexParse.cup b/tools/lexer/jflex-1.4/src/JFlex/LexParse.cup new file mode 100644 index 000000000000..408ed0553914 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/LexParse.cup @@ -0,0 +1,632 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.*; + +/* customizing code */ + +action code {: + + LexScan scanner; + CharClasses charClasses = new CharClasses(127); + RegExps regExps = new RegExps(); + Macros macros = new Macros(); + Integer stateNumber; + Timer t = new Timer(); + EOFActions eofActions = new EOFActions(); + + void fatalError(ErrorMessages message, int line, int col) { + syntaxError(message, line, col); + throw new GeneratorException(); + } + + void fatalError(ErrorMessages message) { + fatalError(message, scanner.currentLine(), -1); + throw new GeneratorException(); + } + + void syntaxError(ErrorMessages message) { + Out.error(scanner.file, message, scanner.currentLine(), -1); + } + + void syntaxError(ErrorMessages message, int line) { + Out.error(scanner.file, message, line, -1); + } + + void syntaxError(ErrorMessages message, int line, int col) { + Out.error(scanner.file, message, line, col); + } + + + private boolean check(int type, char c) { + switch (type) { + case sym.JLETTERCLASS: + return Character.isJavaIdentifierStart(c); + + case sym.JLETTERDIGITCLASS: + return Character.isJavaIdentifierPart(c); + + case sym.LETTERCLASS: + return Character.isLetter(c); + + case sym.DIGITCLASS: + return Character.isDigit(c); + + case sym.UPPERCLASS: + return Character.isUpperCase(c); + + case sym.LOWERCLASS: + return Character.isLowerCase(c); + + default: return false; + } + } + + private Vector makePreClass(int type) { + + Vector result = new Vector(); + + char c = 0; + char start = 0; + char last = charClasses.getMaxCharCode(); + + boolean prev, current; + + prev = check(type,'\u0000'); + + for (c = 1; c < last; c++) { + + current = check(type,c); + + if (!prev && current) start = c; + if (prev && !current) { + result.addElement(new Interval(start, (char)(c-1))); + } + + prev = current; + } + + // the last iteration is moved out of the loop to + // avoid an endless loop if last == maxCharCode and + // last+1 == 0 + current = check(type,c); + + if (!prev && current) result.addElement(new Interval(c,c)); + if (prev && current) result.addElement(new Interval(start, c)); + if (prev && !current) result.addElement(new Interval(start, (char)(c-1))); + + return result; + } + + private RegExp makeRepeat(RegExp r, int n1, int n2, int line, int col) { + + if (n1 <= 0 && n2 <= 0) { + syntaxError(ErrorMessages.REPEAT_ZERO, line, col); + return null; + } + + if (n1 > n2) { + syntaxError(ErrorMessages.REPEAT_GREATER, line, col); + return null; + } + + int i; + RegExp result; + + if (n1 > 0) { + result = r; + n1--; n2--; // we need one concatenation less than the number of expressions to match + } + else { + result = new RegExp1(sym.QUESTION,r); + n2--; + } + + for (i = 0; i < n1; i++) + result = new RegExp2(sym.CONCAT, result, r); + + n2-= n1; + for (i = 0; i < n2; i++) + result = new RegExp2(sym.CONCAT, result, new RegExp1(sym.QUESTION,r)); + + return result; + } + + private RegExp makeNL() { + Vector list = new Vector(); + list.addElement(new Interval('\n','\r')); + list.addElement(new Interval('\u0085','\u0085')); + list.addElement(new Interval('\u2028','\u2029')); + + // assumption: line feeds are caseless + charClasses.makeClass(list, false); + charClasses.makeClass('\n', false); + charClasses.makeClass('\r', false); + + RegExp1 c = new RegExp1(sym.CCLASS, list); + Character n = new Character('\n'); + Character r = new Character('\r'); + + return new RegExp2(sym.BAR, + c, + new RegExp2(sym.CONCAT, + new RegExp1(sym.CHAR, r), + new RegExp1(sym.CHAR, n))); + } + +:}; + +parser code {: + public LexScan scanner; + + public LexParse(LexScan scanner) { + super(scanner); + this.scanner = scanner; + } + + public CharClasses getCharClasses() { + return action_obj.charClasses; + } + + public EOFActions getEOFActions() { + return action_obj.eofActions; + } + + public void report_error(String message, Object info) { + if ( info instanceof java_cup.runtime.Symbol ) { + java_cup.runtime.Symbol s = (java_cup.runtime.Symbol) info; + + if (s.sym == sym.EOF) + Out.error(ErrorMessages.UNEXPECTED_EOF); + else + Out.error(scanner.file, ErrorMessages.SYNTAX_ERROR, s.left, s.right); + } + else + Out.error(ErrorMessages.UNKNOWN_SYNTAX); + } + + public void report_fatal_error(String message, Object info) { + // report_error(message, info); + throw new GeneratorException(); + } + +:}; + +init with {: + action_obj.scanner = this.scanner; +:}; + +/* token declarations */ + +terminal OPENBRACKET, CLOSEBRACKET, HAT, DOLLAR, OPENCLASS, + CLOSECLASS, DASH, DELIMITER, EQUALS, COMMA, LESSTHAN, + MORETHAN, LBRACE, RBRACE, FULL, UNICODE, REGEXPEND; + +terminal JLETTERCLASS, JLETTERDIGITCLASS, LETTERCLASS, DIGITCLASS, + UPPERCLASS, LOWERCLASS, EOFRULE, NOACTION, LOOKAHEAD; + +terminal Action ACTION; +terminal String IDENT, USERCODE; +terminal Integer REPEAT; + +/* tokens used in RegExp parse tree */ +terminal STAR, PLUS, BAR, QUESTION, POINT, BANG, TILDE; + +terminal Character CHAR; +terminal String STRING, MACROUSE; + +/* symbols *only* used in the parse tree (not in the grammar) */ +terminal CCLASS, CCLASSNOT, CONCAT; +terminal STRING_I, CHAR_I; /* case insensitive strings/chars */ + + +non terminal macros, macro; +non terminal Integer rule; +non terminal NFA specification; +non terminal RegExp series, concs, nregexp, regexp, charclass, lookaheadOPT; +non terminal Interval classcontentelem; +non terminal Vector states, statesOPT, classcontent, preclass, rules; +non terminal Boolean hatOPT; +non terminal Action actions; + + +/* grammar specification */ +start with specification; + +specification ::= USERCODE + /* delimiter is checked in lexer */ + macros + DELIMITER + rules + {: + scanner.t.stop(); + + Out.checkErrors(); + + Out.time(ErrorMessages.PARSING_TOOK, t); + + macros.expand(); + Enumeration unused = macros.unused(); + while ( unused.hasMoreElements() ) { + Out.warning("Macro \""+unused.nextElement()+"\" has been declared but never used."); + } + + SemCheck.check(regExps, macros, charClasses.getMaxCharCode(), scanner.file); + + regExps.checkActions(); + + if (Options.dump) charClasses.dump(); + + Out.print("Constructing NFA : "); + + t.start(); + int num = regExps.getNum(); + + RESULT = new NFA(charClasses.getNumClasses(), + scanner, regExps, macros, charClasses); + + eofActions.setNumLexStates(scanner.states.number()); + + for (int i = 0; i < num; i++) { + if (regExps.isEOF(i)) + eofActions.add( regExps.getStates(i), regExps.getAction(i) ); + else + RESULT.addRegExp(i); + } + + if (scanner.standalone) RESULT.addStandaloneRule(); + t.stop(); + + Out.time(""); + Out.time(ErrorMessages.NFA_TOOK, t); + + :} + | /* emtpy spec. error */ + {: + fatalError(ErrorMessages.NO_LEX_SPEC); + :} + ; + +macros ::= /* empty, most switches & state declarations are parsed in lexer */ + | macros macro + | error; + +macro ::= FULL + {: charClasses.setMaxCharCode(255); :} + | UNICODE + {: charClasses.setMaxCharCode(0xFFFF); :} + | IDENT:name EQUALS series:definition REGEXPEND + {: macros.insert(name, definition); :} + | IDENT EQUALS:e + {: syntaxError(ErrorMessages.REGEXP_EXPECTED, eleft, eright); :} + ; + + +rules ::= rules:rlist rule:r + {: rlist.addElement(r); RESULT = rlist; :} + | rules:rlist1 LESSTHAN states:states MORETHAN LBRACE rules:rlist2 RBRACE + {: + Enumeration rs = rlist2.elements(); + while ( rs.hasMoreElements() ) { + Integer elem = (Integer) rs.nextElement(); + regExps.addStates( elem.intValue(), states ); + rlist1.addElement( elem ); + } + RESULT = rlist1; + :} + | LESSTHAN states:states MORETHAN LBRACE rules:rlist RBRACE + {: + Enumeration rs = rlist.elements(); + while ( rs.hasMoreElements() ) { + Integer elem = (Integer) rs.nextElement(); + regExps.addStates( elem.intValue(), states ); + } + RESULT = rlist; + :} + | rule:r + {: RESULT = new Vector(); RESULT.addElement(r); :} + ; + +rule ::= statesOPT:s hatOPT:bol series:r lookaheadOPT:l actions:a + {: RESULT = new Integer(regExps.insert(rleft, s, r, a, bol, l)); :} + | statesOPT:s EOFRULE ACTION:a + {: RESULT = new Integer(regExps.insert(s, a)); :} + | error + ; + +lookaheadOPT ::= DOLLAR + {: RESULT = makeNL(); :} + | LOOKAHEAD series:r + {: RESULT = r; :} + | /* empty */ + {: RESULT = null; :} + | LOOKAHEAD series:s DOLLAR + {: RESULT = new RegExp2(sym.CONCAT, s, makeNL()); :} + ; + +actions ::= REGEXPEND ACTION:a + {: RESULT = a; :} + | NOACTION + {: RESULT = null; :} + ; + + +statesOPT ::= LESSTHAN states:list MORETHAN + {: RESULT = list; :} + | /* empty */ + {: RESULT = new Vector(); :} + ; + +states ::= IDENT:id COMMA states:list + {: + stateNumber = scanner.states.getNumber( id ); + if ( stateNumber != null ) + list.addElement( stateNumber ); + else { + throw new ScannerException(scanner.file, ErrorMessages.LEXSTATE_UNDECL, + idleft, idright); + } + RESULT = list; + :} + | IDENT:id + {: + Vector list = new Vector(); + stateNumber = scanner.states.getNumber( id ); + if ( stateNumber != null ) + list.addElement( stateNumber ); + else { + throw new ScannerException(scanner.file, ErrorMessages.LEXSTATE_UNDECL, + idleft, idright); + } + RESULT = list; + :} + | IDENT COMMA:c + {: syntaxError(ErrorMessages.REGEXP_EXPECTED, cleft, cright+1); :} + ; + +hatOPT ::= HAT + {: // assumption: there is no upper case for \n + charClasses.makeClass('\n', false); + RESULT = new Boolean(true); :} + | /* empty */ + {: RESULT = new Boolean(false); :} + ; + +series ::= series:r1 BAR concs:r2 + {: RESULT = new RegExp2(sym.BAR, r1, r2); :} + | concs:r + {: RESULT = r; :} + | BAR:b + {: syntaxError(ErrorMessages.REGEXP_EXPECTED, bleft, bright); :} + ; + +concs ::= concs:r1 nregexp:r2 + {: RESULT = new RegExp2(sym.CONCAT, r1, r2); :} + | nregexp:r + {: RESULT = r; :} + ; + +nregexp ::= regexp:r + {: RESULT = r; :} + | BANG nregexp:r + {: RESULT = new RegExp1(sym.BANG, r); :} + | TILDE nregexp:r + {: RESULT = new RegExp1(sym.TILDE, r); :} + ; + +regexp ::= regexp:r STAR + {: RESULT = new RegExp1(sym.STAR, r); :} + | regexp:r PLUS + {: RESULT = new RegExp1(sym.PLUS, r); :} + | regexp:r QUESTION + {: RESULT = new RegExp1(sym.QUESTION, r); :} + | regexp:r REPEAT:n RBRACE:b + {: RESULT = makeRepeat(r, n.intValue(), n.intValue(), bleft, bright); :} + | regexp:r REPEAT:n1 REPEAT:n2 RBRACE + {: RESULT = makeRepeat(r, n1.intValue(), n2.intValue(), n1left, n2right); :} + | OPENBRACKET series:r CLOSEBRACKET + {: RESULT = r; :} + | MACROUSE:ident + {: + if ( !scanner.macroDefinition ) { + if ( ! macros.markUsed(ident) ) + throw new ScannerException(scanner.file, ErrorMessages.MACRO_UNDECL, + identleft, identright); + } + RESULT = new RegExp1(sym.MACROUSE, ident); + :} + | charclass:c + {: RESULT = c; :} + | preclass:list + {: + try { + // assumption [correct?]: preclasses are already closed under case + charClasses.makeClass(list, false); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, listleft); + } + RESULT = new RegExp1(sym.CCLASS, list); + :} + | STRING:str + {: + try { + if ( scanner.caseless ) { + charClasses.makeClass(str, true); + RESULT = new RegExp1(sym.STRING_I, str); + } + else { + charClasses.makeClass(str, false); + RESULT = new RegExp1(sym.STRING, str); + } + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CS2SMALL_STRING, strleft, strright); + } + + :} + | POINT + {: + Vector any = new Vector(); + any.addElement(new Interval('\n','\n')); + // assumption: there is no upper case for \n + charClasses.makeClass('\n', false); + RESULT = new RegExp1(sym.CCLASSNOT, any); + :} + | CHAR:c + {: + try { + if ( scanner.caseless ) { + charClasses.makeClass(c.charValue(), true); + RESULT = new RegExp1(sym.CHAR_I, c); + } + else { + charClasses.makeClass(c.charValue(), false); + RESULT = new RegExp1(sym.CHAR, c); + } + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CS2SMALL_CHAR, cleft, cright); + } + :} + ; + +charclass ::= OPENCLASS CLOSECLASS + {: + RESULT = new RegExp1(sym.CCLASS,null); + :} + | OPENCLASS classcontent:list CLOSECLASS:close + {: + try { + charClasses.makeClass(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + :} + | OPENCLASS HAT CLOSECLASS:close + {: + Vector list = new Vector(); + list.addElement(new Interval((char)0,CharClasses.maxChar)); + try { + charClasses.makeClass(list, false); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + :} + | OPENCLASS HAT classcontent:list CLOSECLASS:close + {: + try { + charClasses.makeClassNot(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASSNOT,list); + :} + | OPENCLASS DASH classcontent:list CLOSECLASS:close + {: + try { + list.addElement(new Interval('-','-')); + charClasses.makeClass(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + :} + | OPENCLASS HAT DASH classcontent:list CLOSECLASS:close + {: + try { + list.addElement(new Interval('-','-')); + charClasses.makeClassNot(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASSNOT,list); + :} + ; + +classcontent ::= classcontent:list classcontentelem:elem + {: + list.addElement(elem); + RESULT = list; + :} + | classcontentelem:elem + {: + Vector list = new Vector(); + list.addElement(elem); + RESULT = list; + :} + | classcontent:list preclass:plist + {: + for (Enumeration e = plist.elements(); e.hasMoreElements();) + list.addElement(e.nextElement()); + RESULT = list; + :} + | preclass:list + {: RESULT = list; :} + | classcontent:list STRING:s + {: + for (int i = 0; i < s.length(); i++) + list.addElement(new Interval(s.charAt(i),s.charAt(i))); + RESULT = list; + :} + | STRING:s + {: + RESULT = new Vector(); + for (int i = 0; i < s.length(); i++) + RESULT.addElement(new Interval(s.charAt(i),s.charAt(i))); + :} + | classcontent:list MACROUSE:ident + {: + syntaxError(ErrorMessages.CHARCLASS_MACRO, identleft, identright); + :} + | MACROUSE:ident + {: + syntaxError(ErrorMessages.CHARCLASS_MACRO, identleft, identright); + :} + ; + +classcontentelem ::= CHAR:c1 DASH CHAR:c2 + {: RESULT = new Interval(c1.charValue(), c2.charValue()); :} + | CHAR:c + {: RESULT = new Interval(c.charValue(), c.charValue()); :} + ; + +preclass ::= JLETTERCLASS + {: RESULT = makePreClass(sym.JLETTERCLASS); :} + | JLETTERDIGITCLASS + {: RESULT = makePreClass(sym.JLETTERDIGITCLASS); :} + | LETTERCLASS + {: RESULT = makePreClass(sym.LETTERCLASS); :} + | DIGITCLASS + {: RESULT = makePreClass(sym.DIGITCLASS); :} + | UPPERCLASS + {: RESULT = makePreClass(sym.UPPERCLASS); :} + | LOWERCLASS + {: RESULT = makePreClass(sym.LOWERCLASS); :} + ; diff --git a/tools/lexer/jflex-1.4/src/JFlex/LexParse.java b/tools/lexer/jflex-1.4/src/JFlex/LexParse.java new file mode 100644 index 000000000000..8694d238001a --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/LexParse.java @@ -0,0 +1,1711 @@ + +//---------------------------------------------------- +// The following code was generated by CUP v0.10k +// Sun Nov 07 14:07:52 GMT+10:00 2004 +//---------------------------------------------------- + +package JFlex; + +import java.util.Enumeration; +import java.util.Timer; +import java.util.Vector; + +/** CUP v0.10k generated parser. + * @version Sun Nov 07 14:07:52 GMT+10:00 2004 + */ +public class LexParse extends java_cup.runtime.lr_parser { + + /** Default constructor. */ + public LexParse() {super();} + + /** Constructor which sets the default scanner. */ + public LexParse(java_cup.runtime.Scanner s) {super(s);} + + /** Production table. */ + protected static final short _production_table[][] = + unpackFromStrings(new String[] { + "\000\110\000\002\002\004\000\002\006\006\000\002\006" + + "\002\000\002\003\002\000\002\003\004\000\002\003\003" + + "\000\002\004\003\000\002\004\003\000\002\004\006\000" + + "\002\004\004\000\002\022\004\000\002\022\011\000\002" + + "\022\010\000\002\022\003\000\002\005\007\000\002\005" + + "\005\000\002\005\003\000\002\014\003\000\002\014\004" + + "\000\002\014\002\000\002\014\005\000\002\024\004\000" + + "\002\024\003\000\002\017\005\000\002\017\002\000\002" + + "\016\005\000\002\016\003\000\002\016\004\000\002\023" + + "\003\000\002\023\002\000\002\007\005\000\002\007\003" + + "\000\002\007\003\000\002\010\004\000\002\010\003\000" + + "\002\011\003\000\002\011\004\000\002\011\004\000\002" + + "\012\004\000\002\012\004\000\002\012\004\000\002\012" + + "\005\000\002\012\006\000\002\012\005\000\002\012\003" + + "\000\002\012\003\000\002\012\003\000\002\012\003\000" + + "\002\012\003\000\002\012\003\000\002\013\004\000\002" + + "\013\005\000\002\013\005\000\002\013\006\000\002\013" + + "\006\000\002\013\007\000\002\020\004\000\002\020\003" + + "\000\002\020\004\000\002\020\003\000\002\020\004\000" + + "\002\020\003\000\002\020\004\000\002\020\003\000\002" + + "\015\005\000\002\015\003\000\002\021\003\000\002\021" + + "\003\000\002\021\003\000\002\021\003\000\002\021\003" + + "\000\002\021\003" }); + + /** Access to production table. */ + public short[][] production_table() {return _production_table;} + + /** Parse-action table. */ + protected static final short[][] _action_table = + unpackFromStrings(new String[] { + "\000\152\000\006\002\uffff\040\004\001\002\000\014\003" + + "\007\013\ufffe\022\ufffe\023\ufffe\037\ufffe\001\002\000\004" + + "\002\006\001\002\000\004\002\001\001\002\000\012\013" + + "\ufffc\022\ufffc\023\ufffc\037\ufffc\001\002\000\012\013\011" + + "\022\015\023\014\037\013\001\002\000\050\003\113\004" + + "\uffe9\006\uffe9\010\uffe9\016\115\025\uffe9\026\uffe9\027\uffe9" + + "\030\uffe9\031\uffe9\032\uffe9\033\uffe9\044\uffe9\046\uffe9\047" + + "\uffe9\050\uffe9\051\uffe9\052\uffe9\053\uffe9\001\002\000\012" + + "\013\ufffd\022\ufffd\023\ufffd\037\ufffd\001\002\000\004\014" + + "\016\001\002\000\012\013\ufffa\022\ufffa\023\ufffa\037\ufffa" + + "\001\002\000\012\013\ufffb\022\ufffb\023\ufffb\037\ufffb\001" + + "\002\000\050\004\033\010\043\013\ufff8\022\ufff8\023\ufff8" + + "\025\023\026\030\027\017\030\041\031\034\032\031\037" + + "\ufff8\044\040\046\021\047\036\050\022\051\020\052\027" + + "\053\024\001\002\000\064\004\uffbd\005\uffbd\007\uffbd\010" + + "\uffbd\011\uffbd\024\uffbd\025\uffbd\026\uffbd\027\uffbd\030\uffbd" + + "\031\uffbd\032\uffbd\034\uffbd\035\uffbd\041\uffbd\042\uffbd\043" + + "\uffbd\044\uffbd\045\uffbd\046\uffbd\047\uffbd\050\uffbd\051\uffbd" + + "\052\uffbd\053\uffbd\001\002\000\062\004\uffd0\005\uffd0\007" + + "\uffd0\010\uffd0\024\uffd0\025\uffd0\026\uffd0\027\uffd0\030\uffd0" + + "\031\uffd0\032\uffd0\034\uffd0\035\uffd0\041\uffd0\042\uffd0\043" + + "\uffd0\044\uffd0\045\uffd0\046\uffd0\047\uffd0\050\uffd0\051\uffd0" + + "\052\uffd0\053\uffd0\001\002\000\062\004\uffd1\005\uffd1\007" + + "\uffd1\010\uffd1\024\uffd1\025\uffd1\026\uffd1\027\uffd1\030\uffd1" + + "\031\uffd1\032\uffd1\034\uffd1\035\uffd1\041\uffd1\042\uffd1\043" + + "\uffd1\044\uffd1\045\uffd1\046\uffd1\047\uffd1\050\uffd1\051\uffd1" + + "\052\uffd1\053\uffd1\001\002\000\036\004\033\010\043\025" + + "\023\026\030\027\017\030\041\031\034\032\031\046\021" + + "\047\036\050\022\051\020\052\027\053\024\001\002\000" + + "\064\004\uffbf\005\uffbf\007\uffbf\010\uffbf\011\uffbf\024\uffbf" + + "\025\uffbf\026\uffbf\027\uffbf\030\uffbf\031\uffbf\032\uffbf\034" + + "\uffbf\035\uffbf\041\uffbf\042\uffbf\043\uffbf\044\uffbf\045\uffbf" + + "\046\uffbf\047\uffbf\050\uffbf\051\uffbf\052\uffbf\053\uffbf\001" + + "\002\000\062\004\uffd5\005\uffd5\007\uffd5\010\uffd5\024\uffd5" + + "\025\uffd5\026\uffd5\027\uffd5\030\uffd5\031\uffd5\032\uffd5\034" + + "\uffd5\035\uffd5\041\uffd5\042\uffd5\043\uffd5\044\uffd5\045\uffd5" + + "\046\uffd5\047\uffd5\050\uffd5\051\uffd5\052\uffd5\053\uffd5\001" + + "\002\000\006\024\111\044\105\001\002\000\062\004\uffd3" + + "\005\uffd3\007\uffd3\010\uffd3\024\uffd3\025\uffd3\026\uffd3\027" + + "\uffd3\030\uffd3\031\uffd3\032\uffd3\034\uffd3\035\uffd3\041\uffd3" + + "\042\uffd3\043\uffd3\044\uffd3\045\uffd3\046\uffd3\047\uffd3\050" + + "\uffd3\051\uffd3\052\uffd3\053\uffd3\001\002\000\062\004\uffd2" + + "\005\uffd2\007\uffd2\010\uffd2\024\uffd2\025\uffd2\026\uffd2\027" + + "\uffd2\030\uffd2\031\uffd2\032\uffd2\034\uffd2\035\uffd2\041\uffd2" + + "\042\uffd2\043\uffd2\044\uffd2\045\uffd2\046\uffd2\047\uffd2\050" + + "\uffd2\051\uffd2\052\uffd2\053\uffd2\001\002\000\064\004\uffbe" + + "\005\uffbe\007\uffbe\010\uffbe\011\uffbe\024\uffbe\025\uffbe\026" + + "\uffbe\027\uffbe\030\uffbe\031\uffbe\032\uffbe\034\uffbe\035\uffbe" + + "\041\uffbe\042\uffbe\043\uffbe\044\uffbe\045\uffbe\046\uffbe\047" + + "\uffbe\050\uffbe\051\uffbe\052\uffbe\053\uffbe\001\002\000\064" + + "\004\uffba\005\uffba\007\uffba\010\uffba\011\uffba\024\uffba\025" + + "\uffba\026\uffba\027\uffba\030\uffba\031\uffba\032\uffba\034\uffba" + + "\035\uffba\041\uffba\042\uffba\043\uffba\044\uffba\045\uffba\046" + + "\uffba\047\uffba\050\uffba\051\uffba\052\uffba\053\uffba\001\002" + + "\000\052\004\033\005\uffe2\007\uffe2\010\043\024\uffe2\025" + + "\023\026\030\027\017\030\041\031\034\032\031\034\uffe2" + + "\035\uffe2\044\uffe2\046\021\047\036\050\022\051\020\052" + + "\027\053\024\001\002\000\040\004\033\010\043\025\023" + + "\026\030\027\017\030\041\031\034\032\031\044\040\046" + + "\021\047\036\050\022\051\020\052\027\053\024\001\002" + + "\000\064\004\uffbb\005\uffbb\007\uffbb\010\uffbb\011\uffbb\024" + + "\uffbb\025\uffbb\026\uffbb\027\uffbb\030\uffbb\031\uffbb\032\uffbb" + + "\034\uffbb\035\uffbb\041\uffbb\042\uffbb\043\uffbb\044\uffbb\045" + + "\uffbb\046\uffbb\047\uffbb\050\uffbb\051\uffbb\052\uffbb\053\uffbb" + + "\001\002\000\062\004\uffd4\005\uffd4\007\uffd4\010\uffd4\024" + + "\uffd4\025\uffd4\026\uffd4\027\uffd4\030\uffd4\031\uffd4\032\uffd4" + + "\034\uffd4\035\uffd4\041\uffd4\042\uffd4\043\uffd4\044\uffd4\045" + + "\uffd4\046\uffd4\047\uffd4\050\uffd4\051\uffd4\052\uffd4\053\uffd4" + + "\001\002\000\036\004\033\010\043\025\023\026\030\027" + + "\017\030\041\031\034\032\031\046\021\047\036\050\022" + + "\051\020\052\027\053\024\001\002\000\052\004\uffdf\005" + + "\uffdf\007\uffdf\010\uffdf\024\uffdf\025\uffdf\026\uffdf\027\uffdf" + + "\030\uffdf\031\uffdf\032\uffdf\034\uffdf\035\uffdf\044\uffdf\046" + + "\uffdf\047\uffdf\050\uffdf\051\uffdf\052\uffdf\053\uffdf\001\002" + + "\000\016\005\uffe1\007\uffe1\024\uffe1\034\uffe1\035\uffe1\044" + + "\uffe1\001\002\000\064\004\uffbc\005\uffbc\007\uffbc\010\uffbc" + + "\011\uffbc\024\uffbc\025\uffbc\026\uffbc\027\uffbc\030\uffbc\031" + + "\uffbc\032\uffbc\034\uffbc\035\uffbc\041\uffbc\042\uffbc\043\uffbc" + + "\044\uffbc\045\uffbc\046\uffbc\047\uffbc\050\uffbc\051\uffbc\052" + + "\uffbc\053\uffbc\001\002\000\062\004\uffde\005\uffde\007\uffde" + + "\010\uffde\024\uffde\025\uffde\026\uffde\027\uffde\030\uffde\031" + + "\uffde\032\uffde\034\uffde\035\uffde\041\076\042\074\043\075" + + "\044\uffde\045\077\046\uffde\047\uffde\050\uffde\051\uffde\052" + + "\uffde\053\uffde\001\002\000\032\006\047\011\050\012\046" + + "\025\023\026\030\027\017\030\041\031\034\032\031\051" + + "\054\052\051\053\053\001\002\000\026\011\uffc6\025\uffc6" + + "\026\uffc6\027\uffc6\030\uffc6\031\uffc6\032\uffc6\051\uffc6\052" + + "\uffc6\053\uffc6\001\002\000\026\011\uffc8\025\uffc8\026\uffc8" + + "\027\uffc8\030\uffc8\031\uffc8\032\uffc8\051\uffc8\052\uffc8\053" + + "\uffc8\001\002\000\024\025\023\026\030\027\017\030\041" + + "\031\034\032\031\051\054\052\051\053\053\001\002\000" + + "\030\011\065\012\064\025\023\026\030\027\017\030\041" + + "\031\034\032\031\051\054\052\051\053\053\001\002\000" + + "\062\004\uffcf\005\uffcf\007\uffcf\010\uffcf\024\uffcf\025\uffcf" + + "\026\uffcf\027\uffcf\030\uffcf\031\uffcf\032\uffcf\034\uffcf\035" + + "\uffcf\041\uffcf\042\uffcf\043\uffcf\044\uffcf\045\uffcf\046\uffcf" + + "\047\uffcf\050\uffcf\051\uffcf\052\uffcf\053\uffcf\001\002\000" + + "\026\011\uffc4\025\uffc4\026\uffc4\027\uffc4\030\uffc4\031\uffc4" + + "\032\uffc4\051\uffc4\052\uffc4\053\uffc4\001\002\000\026\011" + + "\061\025\023\026\030\027\017\030\041\031\034\032\031" + + "\051\054\052\062\053\063\001\002\000\026\011\uffc2\025" + + "\uffc2\026\uffc2\027\uffc2\030\uffc2\031\uffc2\032\uffc2\051\uffc2" + + "\052\uffc2\053\uffc2\001\002\000\030\011\uffc0\012\055\025" + + "\uffc0\026\uffc0\027\uffc0\030\uffc0\031\uffc0\032\uffc0\051\uffc0" + + "\052\uffc0\053\uffc0\001\002\000\004\051\056\001\002\000" + + "\026\011\uffc1\025\uffc1\026\uffc1\027\uffc1\030\uffc1\031\uffc1" + + "\032\uffc1\051\uffc1\052\uffc1\053\uffc1\001\002\000\026\011" + + "\uffc7\025\uffc7\026\uffc7\027\uffc7\030\uffc7\031\uffc7\032\uffc7" + + "\051\uffc7\052\uffc7\053\uffc7\001\002\000\026\011\uffc9\025" + + "\uffc9\026\uffc9\027\uffc9\030\uffc9\031\uffc9\032\uffc9\051\uffc9" + + "\052\uffc9\053\uffc9\001\002\000\062\004\uffce\005\uffce\007" + + "\uffce\010\uffce\024\uffce\025\uffce\026\uffce\027\uffce\030\uffce" + + "\031\uffce\032\uffce\034\uffce\035\uffce\041\uffce\042\uffce\043" + + "\uffce\044\uffce\045\uffce\046\uffce\047\uffce\050\uffce\051\uffce" + + "\052\uffce\053\uffce\001\002\000\026\011\uffc5\025\uffc5\026" + + "\uffc5\027\uffc5\030\uffc5\031\uffc5\032\uffc5\051\uffc5\052\uffc5" + + "\053\uffc5\001\002\000\026\011\uffc3\025\uffc3\026\uffc3\027" + + "\uffc3\030\uffc3\031\uffc3\032\uffc3\051\uffc3\052\uffc3\053\uffc3" + + "\001\002\000\024\025\023\026\030\027\017\030\041\031" + + "\034\032\031\051\054\052\051\053\053\001\002\000\062" + + "\004\uffcd\005\uffcd\007\uffcd\010\uffcd\024\uffcd\025\uffcd\026" + + "\uffcd\027\uffcd\030\uffcd\031\uffcd\032\uffcd\034\uffcd\035\uffcd" + + "\041\uffcd\042\uffcd\043\uffcd\044\uffcd\045\uffcd\046\uffcd\047" + + "\uffcd\050\uffcd\051\uffcd\052\uffcd\053\uffcd\001\002\000\026" + + "\011\067\025\023\026\030\027\017\030\041\031\034\032" + + "\031\051\054\052\062\053\063\001\002\000\062\004\uffcc" + + "\005\uffcc\007\uffcc\010\uffcc\024\uffcc\025\uffcc\026\uffcc\027" + + "\uffcc\030\uffcc\031\uffcc\032\uffcc\034\uffcc\035\uffcc\041\uffcc" + + "\042\uffcc\043\uffcc\044\uffcc\045\uffcc\046\uffcc\047\uffcc\050" + + "\uffcc\051\uffcc\052\uffcc\053\uffcc\001\002\000\026\011\071" + + "\025\023\026\030\027\017\030\041\031\034\032\031\051" + + "\054\052\062\053\063\001\002\000\062\004\uffca\005\uffca" + + "\007\uffca\010\uffca\024\uffca\025\uffca\026\uffca\027\uffca\030" + + "\uffca\031\uffca\032\uffca\034\uffca\035\uffca\041\uffca\042\uffca" + + "\043\uffca\044\uffca\045\uffca\046\uffca\047\uffca\050\uffca\051" + + "\uffca\052\uffca\053\uffca\001\002\000\026\011\073\025\023" + + "\026\030\027\017\030\041\031\034\032\031\051\054\052" + + "\062\053\063\001\002\000\062\004\uffcb\005\uffcb\007\uffcb" + + "\010\uffcb\024\uffcb\025\uffcb\026\uffcb\027\uffcb\030\uffcb\031" + + "\uffcb\032\uffcb\034\uffcb\035\uffcb\041\uffcb\042\uffcb\043\uffcb" + + "\044\uffcb\045\uffcb\046\uffcb\047\uffcb\050\uffcb\051\uffcb\052" + + "\uffcb\053\uffcb\001\002\000\062\004\uffdb\005\uffdb\007\uffdb" + + "\010\uffdb\024\uffdb\025\uffdb\026\uffdb\027\uffdb\030\uffdb\031" + + "\uffdb\032\uffdb\034\uffdb\035\uffdb\041\uffdb\042\uffdb\043\uffdb" + + "\044\uffdb\045\uffdb\046\uffdb\047\uffdb\050\uffdb\051\uffdb\052" + + "\uffdb\053\uffdb\001\002\000\062\004\uffda\005\uffda\007\uffda" + + "\010\uffda\024\uffda\025\uffda\026\uffda\027\uffda\030\uffda\031" + + "\uffda\032\uffda\034\uffda\035\uffda\041\uffda\042\uffda\043\uffda" + + "\044\uffda\045\uffda\046\uffda\047\uffda\050\uffda\051\uffda\052" + + "\uffda\053\uffda\001\002\000\006\021\100\041\101\001\002" + + "\000\062\004\uffd9\005\uffd9\007\uffd9\010\uffd9\024\uffd9\025" + + "\uffd9\026\uffd9\027\uffd9\030\uffd9\031\uffd9\032\uffd9\034\uffd9" + + "\035\uffd9\041\uffd9\042\uffd9\043\uffd9\044\uffd9\045\uffd9\046" + + "\uffd9\047\uffd9\050\uffd9\051\uffd9\052\uffd9\053\uffd9\001\002" + + "\000\062\004\uffd8\005\uffd8\007\uffd8\010\uffd8\024\uffd8\025" + + "\uffd8\026\uffd8\027\uffd8\030\uffd8\031\uffd8\032\uffd8\034\uffd8" + + "\035\uffd8\041\uffd8\042\uffd8\043\uffd8\044\uffd8\045\uffd8\046" + + "\uffd8\047\uffd8\050\uffd8\051\uffd8\052\uffd8\053\uffd8\001\002" + + "\000\004\021\102\001\002\000\062\004\uffd7\005\uffd7\007" + + "\uffd7\010\uffd7\024\uffd7\025\uffd7\026\uffd7\027\uffd7\030\uffd7" + + "\031\uffd7\032\uffd7\034\uffd7\035\uffd7\041\uffd7\042\uffd7\043" + + "\uffd7\044\uffd7\045\uffd7\046\uffd7\047\uffd7\050\uffd7\051\uffd7" + + "\052\uffd7\053\uffd7\001\002\000\052\004\uffdd\005\uffdd\007" + + "\uffdd\010\uffdd\024\uffdd\025\uffdd\026\uffdd\027\uffdd\030\uffdd" + + "\031\uffdd\032\uffdd\034\uffdd\035\uffdd\044\uffdd\046\uffdd\047" + + "\uffdd\050\uffdd\051\uffdd\052\uffdd\053\uffdd\001\002\000\006" + + "\005\106\044\105\001\002\000\036\004\033\010\043\025" + + "\023\026\030\027\017\030\041\031\034\032\031\046\021" + + "\047\036\050\022\051\020\052\027\053\024\001\002\000" + + "\062\004\uffd6\005\uffd6\007\uffd6\010\uffd6\024\uffd6\025\uffd6" + + "\026\uffd6\027\uffd6\030\uffd6\031\uffd6\032\uffd6\034\uffd6\035" + + "\uffd6\041\uffd6\042\uffd6\043\uffd6\044\uffd6\045\uffd6\046\uffd6" + + "\047\uffd6\050\uffd6\051\uffd6\052\uffd6\053\uffd6\001\002\000" + + "\052\004\033\005\uffe3\007\uffe3\010\043\024\uffe3\025\023" + + "\026\030\027\017\030\041\031\034\032\031\034\uffe3\035" + + "\uffe3\044\uffe3\046\021\047\036\050\022\051\020\052\027" + + "\053\024\001\002\000\052\004\uffe0\005\uffe0\007\uffe0\010" + + "\uffe0\024\uffe0\025\uffe0\026\uffe0\027\uffe0\030\uffe0\031\uffe0" + + "\032\uffe0\034\uffe0\035\uffe0\044\uffe0\046\uffe0\047\uffe0\050" + + "\uffe0\051\uffe0\052\uffe0\053\uffe0\001\002\000\012\013\ufff9" + + "\022\ufff9\023\ufff9\037\ufff9\001\002\000\052\004\uffdc\005" + + "\uffdc\007\uffdc\010\uffdc\024\uffdc\025\uffdc\026\uffdc\027\uffdc" + + "\030\uffdc\031\uffdc\032\uffdc\034\uffdc\035\uffdc\044\uffdc\046" + + "\uffdc\047\uffdc\050\uffdc\051\uffdc\052\uffdc\053\uffdc\001\002" + + "\000\054\002\ufff1\003\ufff1\004\ufff1\006\ufff1\010\ufff1\016" + + "\ufff1\021\ufff1\025\ufff1\026\ufff1\027\ufff1\030\ufff1\031\ufff1" + + "\032\ufff1\033\ufff1\044\ufff1\046\ufff1\047\ufff1\050\ufff1\051" + + "\ufff1\052\ufff1\053\ufff1\001\002\000\044\004\uffe4\006\141" + + "\010\uffe4\025\uffe4\026\uffe4\027\uffe4\030\uffe4\031\uffe4\032" + + "\uffe4\033\137\044\uffe4\046\uffe4\047\uffe4\050\uffe4\051\uffe4" + + "\052\uffe4\053\uffe4\001\002\000\004\037\123\001\002\000" + + "\054\002\ufff4\003\ufff4\004\ufff4\006\ufff4\010\ufff4\016\ufff4" + + "\021\ufff4\025\ufff4\026\ufff4\027\ufff4\030\ufff4\031\ufff4\032" + + "\ufff4\033\ufff4\044\ufff4\046\ufff4\047\ufff4\050\ufff4\051\ufff4" + + "\052\ufff4\053\ufff4\001\002\000\052\002\000\003\113\004" + + "\uffe9\006\uffe9\010\uffe9\016\120\025\uffe9\026\uffe9\027\uffe9" + + "\030\uffe9\031\uffe9\032\uffe9\033\uffe9\044\uffe9\046\uffe9\047" + + "\uffe9\050\uffe9\051\uffe9\052\uffe9\053\uffe9\001\002\000\004" + + "\037\123\001\002\000\054\002\ufff7\003\ufff7\004\ufff7\006" + + "\ufff7\010\ufff7\016\ufff7\021\ufff7\025\ufff7\026\ufff7\027\ufff7" + + "\030\ufff7\031\ufff7\032\ufff7\033\ufff7\044\ufff7\046\ufff7\047" + + "\ufff7\050\ufff7\051\ufff7\052\ufff7\053\ufff7\001\002\000\004" + + "\017\126\001\002\000\006\015\124\017\uffe7\001\002\000" + + "\006\017\uffe6\037\123\001\002\000\004\017\uffe8\001\002" + + "\000\046\004\uffea\006\uffea\010\uffea\020\127\025\uffea\026" + + "\uffea\027\uffea\030\uffea\031\uffea\032\uffea\033\uffea\044\uffea" + + "\046\uffea\047\uffea\050\uffea\051\uffea\052\uffea\053\uffea\001" + + "\002\000\050\003\113\004\uffe9\006\uffe9\010\uffe9\016\115" + + "\025\uffe9\026\uffe9\027\uffe9\030\uffe9\031\uffe9\032\uffe9\033" + + "\uffe9\044\uffe9\046\uffe9\047\uffe9\050\uffe9\051\uffe9\052\uffe9" + + "\053\uffe9\001\002\000\052\003\113\004\uffe9\006\uffe9\010" + + "\uffe9\016\120\021\131\025\uffe9\026\uffe9\027\uffe9\030\uffe9" + + "\031\uffe9\032\uffe9\033\uffe9\044\uffe9\046\uffe9\047\uffe9\050" + + "\uffe9\051\uffe9\052\uffe9\053\uffe9\001\002\000\054\002\ufff6" + + "\003\ufff6\004\ufff6\006\ufff6\010\ufff6\016\ufff6\021\ufff6\025" + + "\ufff6\026\ufff6\027\ufff6\030\ufff6\031\ufff6\032\ufff6\033\ufff6" + + "\044\ufff6\046\ufff6\047\ufff6\050\ufff6\051\ufff6\052\ufff6\053" + + "\ufff6\001\002\000\004\017\133\001\002\000\046\004\uffea" + + "\006\uffea\010\uffea\020\134\025\uffea\026\uffea\027\uffea\030" + + "\uffea\031\uffea\032\uffea\033\uffea\044\uffea\046\uffea\047\uffea" + + "\050\uffea\051\uffea\052\uffea\053\uffea\001\002\000\050\003" + + "\113\004\uffe9\006\uffe9\010\uffe9\016\115\025\uffe9\026\uffe9" + + "\027\uffe9\030\uffe9\031\uffe9\032\uffe9\033\uffe9\044\uffe9\046" + + "\uffe9\047\uffe9\050\uffe9\051\uffe9\052\uffe9\053\uffe9\001\002" + + "\000\052\003\113\004\uffe9\006\uffe9\010\uffe9\016\120\021" + + "\136\025\uffe9\026\uffe9\027\uffe9\030\uffe9\031\uffe9\032\uffe9" + + "\033\uffe9\044\uffe9\046\uffe9\047\uffe9\050\uffe9\051\uffe9\052" + + "\uffe9\053\uffe9\001\002\000\054\002\ufff5\003\ufff5\004\ufff5" + + "\006\ufff5\010\ufff5\016\ufff5\021\ufff5\025\ufff5\026\ufff5\027" + + "\ufff5\030\ufff5\031\ufff5\032\ufff5\033\ufff5\044\ufff5\046\ufff5" + + "\047\ufff5\050\ufff5\051\ufff5\052\ufff5\053\ufff5\001\002\000" + + "\004\036\154\001\002\000\040\004\033\010\043\025\023" + + "\026\030\027\017\030\041\031\034\032\031\044\040\046" + + "\021\047\036\050\022\051\020\052\027\053\024\001\002" + + "\000\040\004\uffe5\010\uffe5\025\uffe5\026\uffe5\027\uffe5\030" + + "\uffe5\031\uffe5\032\uffe5\044\uffe5\046\uffe5\047\uffe5\050\uffe5" + + "\051\uffe5\052\uffe5\053\uffe5\001\002\000\014\007\145\024" + + "\uffee\034\uffee\035\143\044\105\001\002\000\040\004\033" + + "\010\043\025\023\026\030\027\017\030\041\031\034\032" + + "\031\044\040\046\021\047\036\050\022\051\020\052\027" + + "\053\024\001\002\000\006\024\147\034\146\001\002\000" + + "\006\024\ufff0\034\ufff0\001\002\000\054\002\uffeb\003\uffeb" + + "\004\uffeb\006\uffeb\010\uffeb\016\uffeb\021\uffeb\025\uffeb\026" + + "\uffeb\027\uffeb\030\uffeb\031\uffeb\032\uffeb\033\uffeb\044\uffeb" + + "\046\uffeb\047\uffeb\050\uffeb\051\uffeb\052\uffeb\053\uffeb\001" + + "\002\000\004\036\151\001\002\000\054\002\ufff3\003\ufff3" + + "\004\ufff3\006\ufff3\010\ufff3\016\ufff3\021\ufff3\025\ufff3\026" + + "\ufff3\027\ufff3\030\ufff3\031\ufff3\032\ufff3\033\ufff3\044\ufff3" + + "\046\ufff3\047\ufff3\050\ufff3\051\ufff3\052\ufff3\053\ufff3\001" + + "\002\000\054\002\uffec\003\uffec\004\uffec\006\uffec\010\uffec" + + "\016\uffec\021\uffec\025\uffec\026\uffec\027\uffec\030\uffec\031" + + "\uffec\032\uffec\033\uffec\044\uffec\046\uffec\047\uffec\050\uffec" + + "\051\uffec\052\uffec\053\uffec\001\002\000\012\007\153\024" + + "\uffef\034\uffef\044\105\001\002\000\006\024\uffed\034\uffed" + + "\001\002\000\054\002\ufff2\003\ufff2\004\ufff2\006\ufff2\010" + + "\ufff2\016\ufff2\021\ufff2\025\ufff2\026\ufff2\027\ufff2\030\ufff2" + + "\031\ufff2\032\ufff2\033\ufff2\044\ufff2\046\ufff2\047\ufff2\050" + + "\ufff2\051\ufff2\052\ufff2\053\ufff2\001\002" }); + + /** Access to parse-action table. */ + public short[][] action_table() {return _action_table;} + + /** reduce_goto table. */ + protected static final short[][] _reduce_table = + unpackFromStrings(new String[] { + "\000\152\000\004\006\004\001\001\000\004\003\007\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\004\004\011\001\001\000\010\005\115\017\113\022" + + "\116\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\016\007\024\010\031\011" + + "\036\012\041\013\034\021\025\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\012\011\111\012" + + "\041\013\034\021\025\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\012\011\107" + + "\012\041\013\034\021\025\001\001\000\016\007\103\010" + + "\031\011\036\012\041\013\034\021\025\001\001\000\002" + + "\001\001\000\002\001\001\000\012\011\102\012\041\013" + + "\034\021\025\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\010\015\044\020" + + "\051\021\043\001\001\000\002\001\001\000\002\001\001" + + "\000\010\015\044\020\071\021\043\001\001\000\010\015" + + "\044\020\065\021\043\001\001\000\002\001\001\000\002" + + "\001\001\000\006\015\057\021\056\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\010\015\044\020\067" + + "\021\043\001\001\000\002\001\001\000\006\015\057\021" + + "\056\001\001\000\002\001\001\000\006\015\057\021\056" + + "\001\001\000\002\001\001\000\006\015\057\021\056\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\014\010\106\011\036\012\041\013\034\021" + + "\025\001\001\000\002\001\001\000\012\011\107\012\041" + + "\013\034\021\025\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\004\023\137" + + "\001\001\000\004\016\131\001\001\000\002\001\001\000" + + "\006\005\120\017\113\001\001\000\004\016\121\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\004\016\124\001\001\000\002\001\001\000\002\001\001" + + "\000\010\005\115\017\113\022\127\001\001\000\006\005" + + "\120\017\113\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\010\005\115\017\113\022\134\001" + + "\001\000\006\005\120\017\113\001\001\000\002\001\001" + + "\000\002\001\001\000\016\007\141\010\031\011\036\012" + + "\041\013\034\021\025\001\001\000\002\001\001\000\004" + + "\014\143\001\001\000\016\007\151\010\031\011\036\012" + + "\041\013\034\021\025\001\001\000\004\024\147\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001" }); + + /** Access to reduce_goto table. */ + public short[][] reduce_table() {return _reduce_table;} + + /** Instance of action encapsulation class. */ + protected CUP$LexParse$actions action_obj; + + /** Action encapsulation object initializer. */ + protected void init_actions() + { + action_obj = new CUP$LexParse$actions(this); + } + + /** Invoke a user supplied parse action. */ + public java_cup.runtime.Symbol do_action( + int act_num, + java_cup.runtime.lr_parser parser, + java.util.Stack stack, + int top) + throws java.lang.Exception + { + /* call code in generated class */ + return action_obj.CUP$LexParse$do_action(act_num, parser, stack, top); + } + + /** Indicates start state. */ + public int start_state() {return 0;} + /** Indicates start production. */ + public int start_production() {return 0;} + + /** EOF Symbol index. */ + public int EOF_sym() {return 0;} + + /** error Symbol index. */ + public int error_sym() {return 1;} + + + /** User initialization code. */ + public void user_init() throws java.lang.Exception + { + + action_obj.scanner = this.scanner; + + } + + + public LexScan scanner; + + public LexParse(LexScan scanner) { + super(scanner); + this.scanner = scanner; + } + + public CharClasses getCharClasses() { + return action_obj.charClasses; + } + + public EOFActions getEOFActions() { + return action_obj.eofActions; + } + + public void report_error(String message, Object info) { + if ( info instanceof java_cup.runtime.Symbol ) { + java_cup.runtime.Symbol s = (java_cup.runtime.Symbol) info; + + if (s.sym == sym.EOF) + Out.error(ErrorMessages.UNEXPECTED_EOF); + else + Out.error(scanner.file, ErrorMessages.SYNTAX_ERROR, s.left, s.right); + } + else + Out.error(ErrorMessages.UNKNOWN_SYNTAX); + } + + public void report_fatal_error(String message, Object info) { + // report_error(message, info); + throw new GeneratorException(); + } + + +} + +/** Cup generated class to encapsulate user supplied action code.*/ +class CUP$LexParse$actions { + + + + LexScan scanner; + CharClasses charClasses = new CharClasses(127); + RegExps regExps = new RegExps(); + Macros macros = new Macros(); + Integer stateNumber; + Timer t = new Timer(); + EOFActions eofActions = new EOFActions(); + + void fatalError(ErrorMessages message, int line, int col) { + syntaxError(message, line, col); + throw new GeneratorException(); + } + + void fatalError(ErrorMessages message) { + fatalError(message, scanner.currentLine(), -1); + throw new GeneratorException(); + } + + void syntaxError(ErrorMessages message) { + Out.error(scanner.file, message, scanner.currentLine(), -1); + } + + void syntaxError(ErrorMessages message, int line) { + Out.error(scanner.file, message, line, -1); + } + + void syntaxError(ErrorMessages message, int line, int col) { + Out.error(scanner.file, message, line, col); + } + + + private boolean check(int type, char c) { + switch (type) { + case sym.JLETTERCLASS: + return Character.isJavaIdentifierStart(c); + + case sym.JLETTERDIGITCLASS: + return Character.isJavaIdentifierPart(c); + + case sym.LETTERCLASS: + return Character.isLetter(c); + + case sym.DIGITCLASS: + return Character.isDigit(c); + + case sym.UPPERCLASS: + return Character.isUpperCase(c); + + case sym.LOWERCLASS: + return Character.isLowerCase(c); + + default: return false; + } + } + + private Vector makePreClass(int type) { + + Vector result = new Vector(); + + char c = 0; + char start = 0; + char last = charClasses.getMaxCharCode(); + + boolean prev, current; + + prev = check(type,'\u0000'); + + for (c = 1; c < last; c++) { + + current = check(type,c); + + if (!prev && current) start = c; + if (prev && !current) { + result.addElement(new Interval(start, (char)(c-1))); + } + + prev = current; + } + + // the last iteration is moved out of the loop to + // avoid an endless loop if last == maxCharCode and + // last+1 == 0 + current = check(type,c); + + if (!prev && current) result.addElement(new Interval(c,c)); + if (prev && current) result.addElement(new Interval(start, c)); + if (prev && !current) result.addElement(new Interval(start, (char)(c-1))); + + return result; + } + + private RegExp makeRepeat(RegExp r, int n1, int n2, int line, int col) { + + if (n1 <= 0 && n2 <= 0) { + syntaxError(ErrorMessages.REPEAT_ZERO, line, col); + return null; + } + + if (n1 > n2) { + syntaxError(ErrorMessages.REPEAT_GREATER, line, col); + return null; + } + + int i; + RegExp result; + + if (n1 > 0) { + result = r; + n1--; n2--; // we need one concatenation less than the number of expressions to match + } + else { + result = new RegExp1(sym.QUESTION,r); + n2--; + } + + for (i = 0; i < n1; i++) + result = new RegExp2(sym.CONCAT, result, r); + + n2-= n1; + for (i = 0; i < n2; i++) + result = new RegExp2(sym.CONCAT, result, new RegExp1(sym.QUESTION,r)); + + return result; + } + + private RegExp makeNL() { + Vector list = new Vector(); + list.addElement(new Interval('\n','\r')); + list.addElement(new Interval('\u0085','\u0085')); + list.addElement(new Interval('\u2028','\u2029')); + + // assumption: line feeds are caseless + charClasses.makeClass(list, false); + charClasses.makeClass('\n', false); + charClasses.makeClass('\r', false); + + RegExp1 c = new RegExp1(sym.CCLASS, list); + Character n = new Character('\n'); + Character r = new Character('\r'); + + return new RegExp2(sym.BAR, + c, + new RegExp2(sym.CONCAT, + new RegExp1(sym.CHAR, r), + new RegExp1(sym.CHAR, n))); + } + + + private final LexParse parser; + + /** Constructor */ + CUP$LexParse$actions(LexParse parser) { + this.parser = parser; + } + + /** Method with the actual generated action code. */ + public final java_cup.runtime.Symbol CUP$LexParse$do_action( + int CUP$LexParse$act_num, + java_cup.runtime.lr_parser CUP$LexParse$parser, + java.util.Stack CUP$LexParse$stack, + int CUP$LexParse$top) + throws java.lang.Exception + { + /* Symbol object for return from actions */ + java_cup.runtime.Symbol CUP$LexParse$result; + + /* select the action based on the action number */ + switch (CUP$LexParse$act_num) + { + /*. . . . . . . . . . . . . . . . . . . .*/ + case 71: // preclass ::= LOWERCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.LOWERCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 70: // preclass ::= UPPERCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.UPPERCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 69: // preclass ::= DIGITCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.DIGITCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 68: // preclass ::= LETTERCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.LETTERCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 67: // preclass ::= JLETTERDIGITCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.JLETTERDIGITCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 66: // preclass ::= JLETTERCLASS + { + Vector RESULT = null; + RESULT = makePreClass(sym.JLETTERCLASS); + CUP$LexParse$result = new java_cup.runtime.Symbol(15/*preclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 65: // classcontentelem ::= CHAR + { + Interval RESULT = null; + int cleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int cright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Character c = (Character)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new Interval(c.charValue(), c.charValue()); + CUP$LexParse$result = new java_cup.runtime.Symbol(11/*classcontentelem*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 64: // classcontentelem ::= CHAR DASH CHAR + { + Interval RESULT = null; + int c1left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int c1right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + Character c1 = (Character)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int c2left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int c2right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Character c2 = (Character)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new Interval(c1.charValue(), c2.charValue()); + CUP$LexParse$result = new java_cup.runtime.Symbol(11/*classcontentelem*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 63: // classcontent ::= MACROUSE + { + Vector RESULT = null; + int identleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int identright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String ident = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + syntaxError(ErrorMessages.CHARCLASS_MACRO, identleft, identright); + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 62: // classcontent ::= classcontent MACROUSE + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int identleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int identright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String ident = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + syntaxError(ErrorMessages.CHARCLASS_MACRO, identleft, identright); + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 61: // classcontent ::= STRING + { + Vector RESULT = null; + int sleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int sright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String s = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + RESULT = new Vector(); + for (int i = 0; i < s.length(); i++) + RESULT.addElement(new Interval(s.charAt(i),s.charAt(i))); + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 60: // classcontent ::= classcontent STRING + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int sleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int sright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String s = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + for (int i = 0; i < s.length(); i++) + list.addElement(new Interval(s.charAt(i),s.charAt(i))); + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 59: // classcontent ::= preclass + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = list; + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 58: // classcontent ::= classcontent preclass + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int plistleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int plistright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Vector plist = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + for (Enumeration e = plist.elements(); e.hasMoreElements();) + list.addElement(e.nextElement()); + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 57: // classcontent ::= classcontentelem + { + Vector RESULT = null; + int elemleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int elemright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Interval elem = (Interval)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + Vector list = new Vector(); + list.addElement(elem); + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 56: // classcontent ::= classcontent classcontentelem + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int elemleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int elemright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Interval elem = (Interval)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + list.addElement(elem); + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(14/*classcontent*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 55: // charclass ::= OPENCLASS HAT DASH classcontent CLOSECLASS + { + RegExp RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int closeleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int closeright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object close = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + list.addElement(new Interval('-','-')); + charClasses.makeClassNot(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASSNOT,list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 54: // charclass ::= OPENCLASS DASH classcontent CLOSECLASS + { + RegExp RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int closeleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int closeright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object close = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + list.addElement(new Interval('-','-')); + charClasses.makeClass(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 53: // charclass ::= OPENCLASS HAT classcontent CLOSECLASS + { + RegExp RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int closeleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int closeright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object close = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + charClasses.makeClassNot(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASSNOT,list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 52: // charclass ::= OPENCLASS HAT CLOSECLASS + { + RegExp RESULT = null; + int closeleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int closeright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object close = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + Vector list = new Vector(); + list.addElement(new Interval((char)0,CharClasses.maxChar)); + try { + charClasses.makeClass(list, false); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 51: // charclass ::= OPENCLASS classcontent CLOSECLASS + { + RegExp RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int closeleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int closeright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object close = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + charClasses.makeClass(list, Options.jlex && scanner.caseless); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, closeleft, closeright); + } + RESULT = new RegExp1(sym.CCLASS,list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 50: // charclass ::= OPENCLASS CLOSECLASS + { + RegExp RESULT = null; + + RESULT = new RegExp1(sym.CCLASS,null); + + CUP$LexParse$result = new java_cup.runtime.Symbol(9/*charclass*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 49: // regexp ::= CHAR + { + RegExp RESULT = null; + int cleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int cright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Character c = (Character)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + if ( scanner.caseless ) { + charClasses.makeClass(c.charValue(), true); + RESULT = new RegExp1(sym.CHAR_I, c); + } + else { + charClasses.makeClass(c.charValue(), false); + RESULT = new RegExp1(sym.CHAR, c); + } + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CS2SMALL_CHAR, cleft, cright); + } + + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 48: // regexp ::= POINT + { + RegExp RESULT = null; + + Vector any = new Vector(); + any.addElement(new Interval('\n','\n')); + // assumption: there is no upper case for \n + charClasses.makeClass('\n', false); + RESULT = new RegExp1(sym.CCLASSNOT, any); + + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 47: // regexp ::= STRING + { + RegExp RESULT = null; + int strleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int strright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String str = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + if ( scanner.caseless ) { + charClasses.makeClass(str, true); + RESULT = new RegExp1(sym.STRING_I, str); + } + else { + charClasses.makeClass(str, false); + RESULT = new RegExp1(sym.STRING, str); + } + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CS2SMALL_STRING, strleft, strright); + } + + + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 46: // regexp ::= preclass + { + RegExp RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + try { + // assumption [correct?]: preclasses are already closed under case + charClasses.makeClass(list, false); + } + catch (CharClassException e) { + syntaxError(ErrorMessages.CHARSET_2_SMALL, listleft); + } + RESULT = new RegExp1(sym.CCLASS, list); + + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 45: // regexp ::= charclass + { + RegExp RESULT = null; + int cleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int cright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp c = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = c; + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 44: // regexp ::= MACROUSE + { + RegExp RESULT = null; + int identleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int identright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String ident = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + if ( !scanner.macroDefinition ) { + if ( ! macros.markUsed(ident) ) + throw new ScannerException(scanner.file, ErrorMessages.MACRO_UNDECL, + identleft, identright); + } + RESULT = new RegExp1(sym.MACROUSE, ident); + + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 43: // regexp ::= OPENBRACKET series CLOSEBRACKET + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = r; + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 42: // regexp ::= regexp REPEAT REPEAT RBRACE + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).value; + int n1left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int n1right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + Integer n1 = (Integer)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int n2left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int n2right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Integer n2 = (Integer)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = makeRepeat(r, n1.intValue(), n2.intValue(), n1left, n2right); + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 41: // regexp ::= regexp REPEAT RBRACE + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int nleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int nright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Integer n = (Integer)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int bleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int bright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object b = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = makeRepeat(r, n.intValue(), n.intValue(), bleft, bright); + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 40: // regexp ::= regexp QUESTION + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = new RegExp1(sym.QUESTION, r); + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 39: // regexp ::= regexp PLUS + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = new RegExp1(sym.PLUS, r); + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 38: // regexp ::= regexp STAR + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = new RegExp1(sym.STAR, r); + CUP$LexParse$result = new java_cup.runtime.Symbol(8/*regexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 37: // nregexp ::= TILDE nregexp + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new RegExp1(sym.TILDE, r); + CUP$LexParse$result = new java_cup.runtime.Symbol(7/*nregexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 36: // nregexp ::= BANG nregexp + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new RegExp1(sym.BANG, r); + CUP$LexParse$result = new java_cup.runtime.Symbol(7/*nregexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 35: // nregexp ::= regexp + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = r; + CUP$LexParse$result = new java_cup.runtime.Symbol(7/*nregexp*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 34: // concs ::= nregexp + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = r; + CUP$LexParse$result = new java_cup.runtime.Symbol(6/*concs*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 33: // concs ::= concs nregexp + { + RegExp RESULT = null; + int r1left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int r1right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp r1 = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int r2left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int r2right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r2 = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new RegExp2(sym.CONCAT, r1, r2); + CUP$LexParse$result = new java_cup.runtime.Symbol(6/*concs*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 32: // series ::= BAR + { + RegExp RESULT = null; + int bleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int bright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object b = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + syntaxError(ErrorMessages.REGEXP_EXPECTED, bleft, bright); + CUP$LexParse$result = new java_cup.runtime.Symbol(5/*series*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 31: // series ::= concs + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = r; + CUP$LexParse$result = new java_cup.runtime.Symbol(5/*series*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 30: // series ::= series BAR concs + { + RegExp RESULT = null; + int r1left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int r1right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + RegExp r1 = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int r2left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int r2right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r2 = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new RegExp2(sym.BAR, r1, r2); + CUP$LexParse$result = new java_cup.runtime.Symbol(5/*series*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 29: // hatOPT ::= + { + Boolean RESULT = null; + RESULT = new Boolean(false); + CUP$LexParse$result = new java_cup.runtime.Symbol(17/*hatOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 28: // hatOPT ::= HAT + { + Boolean RESULT = null; + // assumption: there is no upper case for \n + charClasses.makeClass('\n', false); + RESULT = new Boolean(true); + CUP$LexParse$result = new java_cup.runtime.Symbol(17/*hatOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 27: // states ::= IDENT COMMA + { + Vector RESULT = null; + int cleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int cright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object c = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + syntaxError(ErrorMessages.REGEXP_EXPECTED, cleft, cright+1); + CUP$LexParse$result = new java_cup.runtime.Symbol(12/*states*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 26: // states ::= IDENT + { + Vector RESULT = null; + int idleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int idright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + String id = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + Vector list = new Vector(); + stateNumber = scanner.states.getNumber( id ); + if ( stateNumber != null ) + list.addElement( stateNumber ); + else { + throw new ScannerException(scanner.file, ErrorMessages.LEXSTATE_UNDECL, + idleft, idright); + } + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(12/*states*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 25: // states ::= IDENT COMMA states + { + Vector RESULT = null; + int idleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int idright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + String id = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + + stateNumber = scanner.states.getNumber( id ); + if ( stateNumber != null ) + list.addElement( stateNumber ); + else { + throw new ScannerException(scanner.file, ErrorMessages.LEXSTATE_UNDECL, + idleft, idright); + } + RESULT = list; + + CUP$LexParse$result = new java_cup.runtime.Symbol(12/*states*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 24: // statesOPT ::= + { + Vector RESULT = null; + RESULT = new Vector(); + CUP$LexParse$result = new java_cup.runtime.Symbol(13/*statesOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 23: // statesOPT ::= LESSTHAN states MORETHAN + { + Vector RESULT = null; + int listleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int listright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector list = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = list; + CUP$LexParse$result = new java_cup.runtime.Symbol(13/*statesOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 22: // actions ::= NOACTION + { + Action RESULT = null; + RESULT = null; + CUP$LexParse$result = new java_cup.runtime.Symbol(18/*actions*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 21: // actions ::= REGEXPEND ACTION + { + Action RESULT = null; + int aleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int aright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Action a = (Action)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = a; + CUP$LexParse$result = new java_cup.runtime.Symbol(18/*actions*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 20: // lookaheadOPT ::= LOOKAHEAD series DOLLAR + { + RegExp RESULT = null; + int sleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int sright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp s = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = new RegExp2(sym.CONCAT, s, makeNL()); + CUP$LexParse$result = new java_cup.runtime.Symbol(10/*lookaheadOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 19: // lookaheadOPT ::= + { + RegExp RESULT = null; + RESULT = null; + CUP$LexParse$result = new java_cup.runtime.Symbol(10/*lookaheadOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 18: // lookaheadOPT ::= LOOKAHEAD series + { + RegExp RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = r; + CUP$LexParse$result = new java_cup.runtime.Symbol(10/*lookaheadOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 17: // lookaheadOPT ::= DOLLAR + { + RegExp RESULT = null; + RESULT = makeNL(); + CUP$LexParse$result = new java_cup.runtime.Symbol(10/*lookaheadOPT*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 16: // rule ::= error + { + Integer RESULT = null; + + CUP$LexParse$result = new java_cup.runtime.Symbol(3/*rule*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 15: // rule ::= statesOPT EOFRULE ACTION + { + Integer RESULT = null; + int sleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int sright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + Vector s = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int aleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int aright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Action a = (Action)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new Integer(regExps.insert(s, a)); + CUP$LexParse$result = new java_cup.runtime.Symbol(3/*rule*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 14: // rule ::= statesOPT hatOPT series lookaheadOPT actions + { + Integer RESULT = null; + int sleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).left; + int sright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).right; + Vector s = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).value; + int bolleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left; + int bolright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).right; + Boolean bol = (Boolean)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).value; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).right; + RegExp r = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-2)).value; + int lleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int lright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp l = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int aleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int aright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Action a = (Action)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new Integer(regExps.insert(rleft, s, r, a, bol, l)); + CUP$LexParse$result = new java_cup.runtime.Symbol(3/*rule*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 13: // rules ::= rule + { + Vector RESULT = null; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Integer r = (Integer)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + RESULT = new Vector(); RESULT.addElement(r); + CUP$LexParse$result = new java_cup.runtime.Symbol(16/*rules*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 12: // rules ::= LESSTHAN states MORETHAN LBRACE rules RBRACE + { + Vector RESULT = null; + int statesleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).left; + int statesright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).right; + Vector states = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).value; + int rlistleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rlistright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector rlist = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + + Enumeration rs = rlist.elements(); + while ( rs.hasMoreElements() ) { + Integer elem = (Integer) rs.nextElement(); + regExps.addStates( elem.intValue(), states ); + } + RESULT = rlist; + + CUP$LexParse$result = new java_cup.runtime.Symbol(16/*rules*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-5)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 11: // rules ::= rules LESSTHAN states MORETHAN LBRACE rules RBRACE + { + Vector RESULT = null; + int rlist1left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-6)).left; + int rlist1right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-6)).right; + Vector rlist1 = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-6)).value; + int statesleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).left; + int statesright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).right; + Vector states = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-4)).value; + int rlist2left = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rlist2right = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector rlist2 = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + + Enumeration rs = rlist2.elements(); + while ( rs.hasMoreElements() ) { + Integer elem = (Integer) rs.nextElement(); + regExps.addStates( elem.intValue(), states ); + rlist1.addElement( elem ); + } + RESULT = rlist1; + + CUP$LexParse$result = new java_cup.runtime.Symbol(16/*rules*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-6)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 10: // rules ::= rules rule + { + Vector RESULT = null; + int rlistleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int rlistright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + Vector rlist = (Vector)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + int rleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int rright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Integer r = (Integer)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + rlist.addElement(r); RESULT = rlist; + CUP$LexParse$result = new java_cup.runtime.Symbol(16/*rules*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 9: // macro ::= IDENT EQUALS + { + Object RESULT = null; + int eleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left; + int eright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right; + Object e = (Object)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).value; + syntaxError(ErrorMessages.REGEXP_EXPECTED, eleft, eright); + CUP$LexParse$result = new java_cup.runtime.Symbol(2/*macro*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 8: // macro ::= IDENT EQUALS series REGEXPEND + { + Object RESULT = null; + int nameleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left; + int nameright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).right; + String name = (String)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).value; + int definitionleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int definitionright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + RegExp definition = (RegExp)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + macros.insert(name, definition); + CUP$LexParse$result = new java_cup.runtime.Symbol(2/*macro*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 7: // macro ::= UNICODE + { + Object RESULT = null; + charClasses.setMaxCharCode(0xFFFF); + CUP$LexParse$result = new java_cup.runtime.Symbol(2/*macro*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 6: // macro ::= FULL + { + Object RESULT = null; + charClasses.setMaxCharCode(255); + CUP$LexParse$result = new java_cup.runtime.Symbol(2/*macro*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 5: // macros ::= error + { + Object RESULT = null; + + CUP$LexParse$result = new java_cup.runtime.Symbol(1/*macros*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 4: // macros ::= macros macro + { + Object RESULT = null; + + CUP$LexParse$result = new java_cup.runtime.Symbol(1/*macros*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 3: // macros ::= + { + Object RESULT = null; + + CUP$LexParse$result = new java_cup.runtime.Symbol(1/*macros*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 2: // specification ::= + { + NFA RESULT = null; + + fatalError(ErrorMessages.NO_LEX_SPEC); + + CUP$LexParse$result = new java_cup.runtime.Symbol(4/*specification*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 1: // specification ::= USERCODE macros DELIMITER rules + { + NFA RESULT = null; + + scanner.t.stop(); + + Out.checkErrors(); + + Out.time(ErrorMessages.PARSING_TOOK, t); + + macros.expand(); + Enumeration unused = macros.unused(); + while ( unused.hasMoreElements() ) { + Out.warning("Macro \""+unused.nextElement()+"\" has been declared but never used."); + } + + SemCheck.check(regExps, macros, charClasses.getMaxCharCode(), scanner.file); + + regExps.checkActions(); + + if (Options.dump) charClasses.dump(); + + Out.print("Constructing NFA : "); + + t.start(); + int num = regExps.getNum(); + + RESULT = new NFA(charClasses.getNumClasses(), + scanner, regExps, macros, charClasses); + + eofActions.setNumLexStates(scanner.states.number()); + + for (int i = 0; i < num; i++) { + if (regExps.isEOF(i)) + eofActions.add( regExps.getStates(i), regExps.getAction(i) ); + else + RESULT.addRegExp(i); + } + + if (scanner.standalone) RESULT.addStandaloneRule(); + t.stop(); + + Out.time(""); + Out.time(ErrorMessages.NFA_TOOK, t); + + + CUP$LexParse$result = new java_cup.runtime.Symbol(4/*specification*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-3)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + return CUP$LexParse$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 0: // $START ::= specification EOF + { + Object RESULT = null; + int start_valleft = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left; + int start_valright = ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).right; + NFA start_val = (NFA)((java_cup.runtime.Symbol) CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).value; + RESULT = start_val; + CUP$LexParse$result = new java_cup.runtime.Symbol(0/*$START*/, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-1)).left, ((java_cup.runtime.Symbol)CUP$LexParse$stack.elementAt(CUP$LexParse$top-0)).right, RESULT); + } + /* ACCEPT */ + CUP$LexParse$parser.done_parsing(); + return CUP$LexParse$result; + + /* . . . . . .*/ + default: + throw new Exception( + "Invalid action number found in internal parse table"); + + } + } +} + diff --git a/tools/lexer/jflex-1.4/src/JFlex/LexScan.flex b/tools/lexer/jflex-1.4/src/JFlex/LexScan.flex new file mode 100644 index 000000000000..2a4157b517c5 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/LexScan.flex @@ -0,0 +1,569 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java_cup.runtime.Symbol; +import java.util.Vector; +import java.io.*; +import java.util.Stack; + +/** + * The lexer of JFlex. + * + * Generated by JFlex. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.8 $, $Date: 2004/11/07 03:09:30 $ + */ +%% + +%final +%public +%class LexScan +%implements sym, java_cup.runtime.Scanner +%function next_token + +%type Symbol +%unicode + +%column +%line + +%eofclose + +%state COMMENT, STATELIST, MACROS, REGEXPSTART +%state REGEXP, JAVA_CODE, STATES, STRING_CONTENT +%state CHARCLASS, COPY, REPEATEXP, EATWSPNL + +%cupdebug + +%{ + int balance = 0; + int commentbalance = 0; + int action_line = 0; + int bufferSize = 16384; + + File file; + Stack files = new Stack(); + + StringBuffer userCode = new StringBuffer(); + + String classCode; + String initCode; + String initThrow; + String eofCode; + String eofThrow; + String lexThrow; + String eofVal; + String scanErrorException; + String cupSymbol = "sym"; + + StringBuffer actionText = new StringBuffer(); + StringBuffer string = new StringBuffer(); + + boolean charCount; + boolean lineCount; + boolean columnCount; + boolean cupCompatible; + boolean cupDebug; + boolean isInteger; + boolean isIntWrap; + boolean isYYEOF; + boolean notUnix; + boolean isPublic; + boolean isFinal; + boolean isAbstract; + boolean lookAheadUsed; + boolean bolUsed; + boolean standalone; + boolean debugOption; + boolean useRowMap = Options.gen_method == Options.PACK || Options.gen_method == Options.TABLE; + boolean packed = Options.gen_method == Options.PACK; + boolean caseless; + boolean inclusive_states; + boolean eofclose; + + String isImplementing; + String isExtending; + String className = "Yylex"; + String functionName; + String tokenType; + String visibility = "public"; + + LexicalStates states = new LexicalStates(); + + Vector actions = new Vector(); + + private int nextState; + + boolean macroDefinition; + + Timer t = new Timer(); + + public int currentLine() { + return yyline; + } + + public void setFile(File file) { + this.file = file; + } + + private Symbol symbol(int type, Object value) { + return new Symbol(type, yyline, yycolumn, value); + } + + private Symbol symbol(int type) { + return new Symbol(type, yyline, yycolumn); + } + + // updates line and column count to the beginning of the first + // non whitespace character in yytext, but leaves yyline+yycolumn + // untouched + private Symbol symbol_countUpdate(int type, Object value) { + int lc = yyline; + int cc = yycolumn; + String text = yytext(); + + for (int i=0; i < text.length(); i++) { + char c = text.charAt(i); + + if (c != '\n' && c != '\r' && c != ' ' && c != '\t' ) + return new Symbol(type, lc, cc, value); + + if (c == '\n') { + lc++; + cc = 0; + } + else + cc++; + } + + return new Symbol(type, yyline, yycolumn, value); + } + + private String makeMacroIdent() { + String matched = yytext().trim(); + return matched.substring(1, matched.length()-1).trim(); + } + + public static String conc(Object a, Object b) { + if (a == null && b == null) return null; + if (a == null) return b.toString(); + if (b == null) return a.toString(); + + return a.toString()+b.toString(); + } + + public static String concExc(Object a, Object b) { + if (a == null && b == null) return null; + if (a == null) return b.toString(); + if (b == null) return a.toString(); + + return a.toString()+", "+b.toString(); + } +%} + +%init{ + states.insert("YYINITIAL", true); +%init} + + +Digit = [0-9] +HexDigit = [0-9a-fA-F] +OctDigit = [0-7] + +Number = {Digit}+ +HexNumber = \\ x {HexDigit} {2} +Unicode = \\ u {HexDigit} {1, 4} +OctNumber = \\ [0-3]? {OctDigit} {1, 2} + +// see http://www.unicode.org/unicode/reports/tr18/ +WSP = [ \t\b] +WSPNL = [\u2028\u2029\u000A\u000B\u000C\u000D\u0085\t\b\ ] +NL = [\u2028\u2029\u000A\u000B\u000C\u000D\u0085] | \u000D\u000A +NNL = [^\u2028\u2029\u000A\u000B\u000C\u000D\u0085] + +Ident = {IdentStart} {IdentPart}* +QualIdent = {Ident} ( {WSP}* "." {WSP}* {Ident} )* +QUIL = {QualIdent} ( {WSP}* "," {WSP}* {QualIdent} )* +Array = "[" {WSP}* "]" +ArrType = {QualIdent} ({WSP}* {Array})* + +IdentStart = [:jletter:] +IdentPart = [:jletterdigit:] + +JFlexCommentChar = [^*/]|"/"+[^*/]|"*"+[^*/] +JFlexComment = {JFlexCommentChar}* + +/* Java comments */ +JavaComment = {TraditionalComment}|{EndOfLineComment} +TraditionalComment = "/*"{CommentContent}\*+"/" +EndOfLineComment = "//".*{NL} + +CommentContent = ([^*]|\*+[^*/])* + +StringCharacter = [^\u2028\u2029\u000A\u000B\u000C\u000D\u0085\"\\] + +CharLiteral = \'([^\u2028\u2029\u000A\u000B\u000C\u000D\u0085\'\\]|{EscapeSequence})\' +StringLiteral = \"({StringCharacter}|{EscapeSequence})*\" + +EscapeSequence = \\[^\u2028\u2029\u000A\u000B\u000C\u000D\u0085]|\\+u{HexDigit}{4}|\\[0-3]?{OctDigit}{1,2} + +/* \\(b|t|n|f|r|\"|\'|\\|[0-3]?{OctDigit}{1,2}|u{HexDigit}{4}) */ + +JavaRest = [^\{\}\"\'/]|"/"[^*/] +JavaCode = ({JavaRest}|{StringLiteral}|{CharLiteral}|{JavaComment})+ + +%% + + { + "%%".*{NL}? { + t.start(); + yybegin(MACROS); + macroDefinition = true; + return symbol(USERCODE,userCode); + } + .*{NL} { userCode.append(yytext()); } + .* { return symbol(EOF); } +} + + ("%{"|"%init{"|"%initthrow{"|"%eof{"|"%eofthrow{"|"%yylexthrow{"|"%eofval{").*{NL} + { string.setLength(0); yybegin(COPY); } + { + "%}".*{NL} { classCode = conc(classCode,string); yybegin(MACROS); } + "%init}".*{NL} { initCode = conc(initCode,string); yybegin(MACROS); } + "%initthrow}".*{NL} { initThrow = concExc(initThrow,string); yybegin(MACROS); } + "%eof}".*{NL} { eofCode = conc(eofCode,string); yybegin(MACROS); } + "%eofthrow}".*{NL} { eofThrow = concExc(eofThrow,string); yybegin(MACROS); } + "%yylexthrow}".*{NL} { lexThrow = concExc(lexThrow,string); yybegin(MACROS); } + "%eofval}".*{NL} { eofVal = string.toString(); yybegin(MACROS); } + + .*{NL} { string.append(yytext()); } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); } +} + + + ^"%s" ("tate" "s"?)? {WSP}+ { inclusive_states = true; yybegin(STATELIST); } + ^"%x" ("state" "s"?)? {WSP}+ { inclusive_states = false; yybegin(STATELIST); } + { + {Ident} { states.insert(yytext(),inclusive_states); } + ([\ \t]*","[\ \t]*)|([\ \t]+) { } + {NL} { yybegin(MACROS); } + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); } +} + + { + "%char" { charCount = true; } + "%line" { lineCount = true; } + "%column" { columnCount = true; } + "%byaccj" { isInteger = true; + if (eofVal == null) + eofVal = "return 0;"; + eofclose = true; + } + "%cup" { cupCompatible = true; + isImplementing = concExc(isImplementing, "java_cup.runtime.Scanner"); + if (functionName == null) + functionName = "next_token"; + if (tokenType == null) + tokenType = "java_cup.runtime.Symbol"; + if (eofVal == null) + eofVal = "return new java_cup.runtime.Symbol("+cupSymbol+".EOF);"; + if (!Options.jlex) eofclose = true; + } + "%cupsym"{WSP}+{QualIdent} {WSP}* { cupSymbol = yytext().substring(8).trim(); + if (cupCompatible) Out.warning(ErrorMessages.CUPSYM_AFTER_CUP, yyline); } + "%cupsym"{WSP}+{NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_CUPSYM, yyline); } + "%cupdebug" { cupDebug = true; } + "%eofclose"({WSP}+"true")? { eofclose = true; } + "%eofclose"({WSP}+"false") { eofclose = false; } + "%class"{WSP}+{Ident} {WSP}* { className = yytext().substring(7).trim(); } + "%function"{WSP}+{Ident} {WSP}* { functionName = yytext().substring(10).trim(); } + "%type"{WSP}+{ArrType} {WSP}* { tokenType = yytext().substring(6).trim(); } + "%integer"|"%int" { isInteger = true; } + "%intwrap" { isIntWrap = true; } + "%yyeof" { isYYEOF = true; } + "%notunix" { notUnix = true; } + "%7bit" { } + "%full"|"%8bit" { return symbol(FULL); } + "%unicode"|"%16bit" { return symbol(UNICODE); } + "%caseless"|"%ignorecase" { caseless = true; } + "%implements"{WSP}+.* { isImplementing = concExc(isImplementing, yytext().substring(12).trim()); } + "%extends"{WSP}+{QualIdent}{WSP}* { isExtending = yytext().substring(9).trim(); } + "%public" { isPublic = true; } + "%apiprivate" { visibility = "private"; Skeleton.makePrivate(); } + "%final" { isFinal = true; } + "%abstract" { isAbstract = true; } + "%debug" { debugOption = true; } + "%standalone" { standalone = true; isInteger = true; } + "%switch" { packed = false; useRowMap = false; } + "%table" { packed = false; useRowMap = true; } + "%pack" { packed = true; useRowMap = true; } + "%include" {WSP}+ .* { File f = new File(yytext().substring(9).trim()); + if ( !f.canRead() ) + throw new ScannerException(file,ErrorMessages.NOT_READABLE, yyline); + // check for cycle + if (files.search(f) > 0) + throw new ScannerException(file,ErrorMessages.FILE_CYCLE, yyline); + try { + yypushStream( new FileReader(f) ); + files.push(file); + file = f; + Out.println("Including \""+file+"\""); + } + catch (FileNotFoundException e) { + throw new ScannerException(file,ErrorMessages.NOT_READABLE, yyline); + } + } + "%buffer" {WSP}+ {Number} {WSP}* { bufferSize = Integer.parseInt(yytext().substring(8).trim()); } + "%buffer" {WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.NO_BUFFER_SIZE, yyline); } + "%initthrow" {WSP}+ {QUIL} {WSP}* { initThrow = concExc(initThrow,yytext().substring(11).trim()); } + "%initthrow" {WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_INITTHROW, yyline); } + "%eofthrow" {WSP}+ {QUIL} {WSP}* { eofThrow = concExc(eofThrow,yytext().substring(10).trim()); } + "%eofthrow" {WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_EOFTHROW, yyline); } + "%yylexthrow"{WSP}+ {QUIL} {WSP}* { lexThrow = concExc(lexThrow,yytext().substring(12).trim()); } + "%throws" {WSP}+ {QUIL} {WSP}* { lexThrow = concExc(lexThrow,yytext().substring(8).trim()); } + "%yylexthrow"{WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_YYLEXTHROW, yyline); } + "%throws" {WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_THROW, yyline); } + "%scanerror" {WSP}+ {QualIdent} {WSP}* { scanErrorException = yytext().substring(11).trim(); } + "%scanerror" {WSP}+ {NNL}* { throw new ScannerException(file,ErrorMessages.QUIL_SCANERROR, yyline); } + + {Ident} { return symbol(IDENT, yytext()); } + "="{WSP}* { yybegin(REGEXP); return symbol(EQUALS); } + + "/*" { nextState = MACROS; yybegin(COMMENT); } + + {EndOfLineComment} { } + + /* no {NL} at the end of this expression, because + needs at least one {WSPNL} to start a regular expression! */ + ^"%%" {NNL}* { macroDefinition = false; yybegin(REGEXPSTART); return symbol(DELIMITER); } + "%"{Ident} { throw new ScannerException(file,ErrorMessages.UNKNOWN_OPTION, yyline, yycolumn); } + "%" { throw new ScannerException(file,ErrorMessages.UNKNOWN_OPTION, yyline, yycolumn); } + ^{WSP}+"%" { Out.warning(ErrorMessages.NOT_AT_BOL, yyline); yypushback(1); } + + {WSP}+ { } + {NL}+ { } + <> { if ( yymoreStreams() ) { + file = (File) files.pop(); + yypopStream(); + } + else + throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); + } +} + + { + {WSPNL}* "/*" { nextState = REGEXPSTART; yybegin(COMMENT); } + {WSPNL}+ { yybegin(REGEXP); } + {WSPNL}* "<" { yybegin(STATES); return symbol_countUpdate(LESSTHAN, null); } + {WSPNL}* "}" { return symbol_countUpdate(RBRACE, null); } + {WSPNL}* "//" {NNL}* { } + {WSPNL}* "<>" {WSPNL}* "{" + { actionText.setLength(0); yybegin(JAVA_CODE); + Symbol s = symbol_countUpdate(EOFRULE, null); + action_line = s.left+1; + return s; + } +} + + { + {Ident} { return symbol(IDENT, yytext()); } + "," { return symbol(COMMA); } + {WSPNL}+ { } + + // "{" will be caught in REGEXP + ">"{WSPNL}* { yybegin(REGEXP); return symbol(MORETHAN); } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_STATES); } +} + + + { + "<>" {WSPNL}+ "{" { actionText.setLength(0); yybegin(JAVA_CODE); action_line = yyline+1; return symbol(EOFRULE); } + "<>" { throw new ScannerException(file,ErrorMessages.EOF_WO_ACTION); } + + {WSPNL}*"|"{WSP}*$ { if (macroDefinition) { + yybegin(EATWSPNL); + return symbol(BAR); + } + else { + yybegin(REGEXPSTART); + return symbol(NOACTION); + } + } + + // stategroup + "{" { yybegin(REGEXPSTART); return symbol(LBRACE); } + + {WSPNL}*"|" { return symbol(BAR); } + + {WSPNL}*\" { string.setLength(0); nextState = REGEXP; yybegin(STRING_CONTENT); } + {WSPNL}*"!" { return symbol(BANG); } + {WSPNL}*"~" { return symbol(TILDE); } + {WSPNL}*"(" { return symbol(OPENBRACKET); } + {WSPNL}*")" { return symbol(CLOSEBRACKET); } + {WSPNL}*"*" { return symbol(STAR); } + {WSPNL}*"+" { return symbol(PLUS); } + {WSPNL}*"?" { return symbol(QUESTION); } + {WSPNL}*"$" { lookAheadUsed = true; return symbol(DOLLAR); } + {WSPNL}*"^" { bolUsed = true; return symbol(HAT); } + {WSPNL}*"." { return symbol(POINT); } + {WSPNL}*"[" { yybegin(CHARCLASS); return symbol(OPENCLASS); } + {WSPNL}*"/" { lookAheadUsed = true; return symbol(LOOKAHEAD); } + + {WSPNL}* "{" {WSP}* {Ident} {WSP}* "}" { return symbol_countUpdate(MACROUSE, makeMacroIdent()); } + {WSPNL}* "{" {WSP}* {Number} { yybegin(REPEATEXP); return symbol(REPEAT, new Integer(yytext().trim().substring(1).trim())); } + + {WSPNL}+ "{" { actionText.setLength(0); yybegin(JAVA_CODE); action_line = yyline+1; return symbol(REGEXPEND); } + {NL} { if (macroDefinition) { yybegin(MACROS); } return symbol(REGEXPEND); } + + {WSPNL}*"/*" { nextState = REGEXP; yybegin(COMMENT); } + + {WSPNL}*"//"{NNL}* { } + + {WSP}+ { } + + { + {WSPNL}*"[:jletter:]" { return symbol(JLETTERCLASS); } + {WSPNL}*"[:jletterdigit:]" { return symbol(JLETTERDIGITCLASS); } + {WSPNL}*"[:letter:]" { return symbol(LETTERCLASS); } + {WSPNL}*"[:digit:]" { return symbol(DIGITCLASS); } + {WSPNL}*"[:uppercase:]" { return symbol(UPPERCLASS); } + {WSPNL}*"[:lowercase:]" { return symbol(LOWERCLASS); } + } + + . { return symbol(CHAR, new Character(yytext().charAt(0))); } +} + + {WSPNL}+ { yybegin(REGEXP); } + + + { + "}" { yybegin(REGEXP); return symbol(RBRACE); } + "," {WSP}* {Number} { return symbol(REPEAT, new Integer(yytext().substring(1).trim())); } + {WSP}+ { } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_REGEXP); } +} + + { + "{"{Ident}"}" { return symbol(MACROUSE, yytext().substring(1,yytext().length()-1)); } + "[" { balance++; return symbol(OPENCLASS); } + "]" { if (balance > 0) balance--; else yybegin(REGEXP); return symbol(CLOSECLASS); } + "^" { return symbol(HAT); } + "-" { return symbol(DASH); } + + // this is a hack to keep JLex compatibilty with char class + // expressions like [+-] + "-]" { yypushback(1); yycolumn--; return symbol(CHAR, new Character(yytext().charAt(0))); } + + \" { string.setLength(0); nextState = CHARCLASS; yybegin(STRING_CONTENT); } + + . { return symbol(CHAR, new Character(yytext().charAt(0))); } + + \n { throw new ScannerException(file,ErrorMessages.EOL_IN_CHARCLASS,yyline,yycolumn); } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_REGEXP); } +} + + { + \" { yybegin(nextState); return symbol(STRING, string.toString()); } + \\\" { string.append('\"'); } + [^\"\\\u2028\u2029\u000A\u000B\u000C\u000D\u0085]+ { string.append(yytext()); } + + {NL} { throw new ScannerException(file,ErrorMessages.UNTERMINATED_STR, yyline, yycolumn); } + + {HexNumber} { string.append( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16)); } + {Unicode} { string.append( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16)); } + {OctNumber} { string.append( (char) Integer.parseInt(yytext().substring(1,yytext().length()), 8)); } + + \\b { string.append('\b'); } + \\n { string.append('\n'); } + \\t { string.append('\t'); } + \\f { string.append('\f'); } + \\r { string.append('\r'); } + + \\. { string.append(yytext().charAt(1)); } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_STRING); } +} + + + { + {HexNumber} { return symbol(CHAR, new Character( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16))); } + {Unicode} { return symbol(CHAR, new Character( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16))); } + {OctNumber} { return symbol(CHAR, new Character( (char) Integer.parseInt(yytext().substring(1,yytext().length()), 8))); } + + \\b { return symbol(CHAR,new Character('\b')); } + \\n { return symbol(CHAR,new Character('\n')); } + \\t { return symbol(CHAR,new Character('\t')); } + \\f { return symbol(CHAR,new Character('\f')); } + \\r { return symbol(CHAR,new Character('\r')); } + + \\. { return symbol(CHAR, new Character(yytext().charAt(1))); } +} + + + { + "{" { balance++; actionText.append('{'); } + "}" { if (balance > 0) { + balance--; + actionText.append('}'); + } + else { + yybegin(REGEXPSTART); + Action a = new Action(actionText.toString(), action_line); + actions.addElement(a); + return symbol(ACTION, a); + } + } + + {JavaCode} { actionText.append(yytext()); } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_ACTION, action_line-1); } +} + + { + + "/"+ "*" { commentbalance++; } + "*"+ "/" { if (commentbalance > 0) + commentbalance--; + else + yybegin(nextState); + } + + {JFlexComment} { /* ignore */ } + + <> { throw new ScannerException(file,ErrorMessages.EOF_IN_COMMENT); } +} + + +. { throw new ScannerException(file,ErrorMessages.UNEXPECTED_CHAR, yyline, yycolumn); } +\n { throw new ScannerException(file,ErrorMessages.UNEXPECTED_NL, yyline, yycolumn); } + +<> { if ( yymoreStreams() ) { + file = (File) files.pop(); + yypopStream(); + } + else + return symbol(EOF); } diff --git a/tools/lexer/jflex-1.4/src/JFlex/LexScan.java b/tools/lexer/jflex-1.4/src/JFlex/LexScan.java new file mode 100644 index 000000000000..796a58a2035f --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/LexScan.java @@ -0,0 +1,2849 @@ +/* The following code was generated by JFlex 1.4.1 on 11/7/04 2:07 PM */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java_cup.runtime.Symbol; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.Stack; +import java.util.Vector; + +/** + * The lexer of JFlex. + * + * Generated by JFlex. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.8 $, $Date: 2004/11/07 03:09:30 $ + */ + +public final class LexScan implements sym, java_cup.runtime.Scanner { + + /** 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 STRING_CONTENT = 16; + public static final int REGEXPSTART = 8; + public static final int MACROS = 6; + public static final int STATELIST = 4; + public static final int EATWSPNL = 24; + public static final int CHARCLASS = 18; + public static final int JAVA_CODE = 12; + public static final int REGEXP = 10; + public static final int YYINITIAL = 0; + public static final int REPEATEXP = 22; + public static final int COMMENT = 2; + public static final int STATES = 14; + public static final int COPY = 20; + + /** + * 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, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 + }; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\10\21\1\22\1\10\1\13\2\11\1\12\16\21\4\0\1\10\1\74"+ + "\1\26\1\0\1\102\1\31\1\0\1\27\1\76\1\77\1\24\1\100"+ + "\1\15\1\105\1\14\1\25\1\7\1\62\2\7\2\3\1\63\1\60"+ + "\1\61\1\1\1\104\1\0\1\66\1\65\1\72\1\101\1\0\4\2"+ + "\1\67\1\71\10\20\1\70\13\20\1\16\1\4\1\17\1\103\1\20"+ + "\1\0\1\47\1\53\1\51\1\56\1\42\1\43\1\57\1\36\1\33"+ + "\1\54\1\64\1\45\1\52\1\34\1\40\1\55\1\20\1\37\1\50"+ + "\1\35\1\6\1\46\1\41\1\5\1\44\1\20\1\32\1\73\1\30"+ + "\1\75\6\21\1\23\32\21\2\0\4\20\4\0\1\20\12\0\1\20"+ + "\4\0\1\20\5\0\27\20\1\0\37\20\1\0\u0128\20\2\0\22\20"+ + "\34\0\136\20\2\0\11\20\2\0\7\20\16\0\2\20\16\0\5\20"+ + "\11\0\1\20\21\0\117\21\21\0\3\21\27\0\1\20\13\0\1\20"+ + "\1\0\3\20\1\0\1\20\1\0\24\20\1\0\54\20\1\0\10\20"+ + "\2\0\32\20\14\0\202\20\1\0\4\21\5\0\71\20\2\0\2\20"+ + "\2\0\2\20\3\0\46\20\2\0\2\20\67\0\46\20\2\0\1\20"+ + "\7\0\47\20\11\0\21\21\1\0\27\21\1\0\3\21\1\0\1\21"+ + "\1\0\2\21\1\0\1\21\13\0\33\20\5\0\3\20\56\0\32\20"+ + "\5\0\13\20\13\21\12\0\12\21\6\0\1\21\143\20\1\0\1\20"+ + "\7\21\2\0\6\21\2\20\2\21\1\0\4\21\2\0\12\21\3\20"+ + "\22\0\1\21\1\20\1\21\33\20\3\0\33\21\65\0\46\20\13\21"+ + "\u0150\0\3\21\1\0\65\20\2\0\1\21\1\20\20\21\2\0\1\20"+ + "\4\21\3\0\12\20\2\21\2\0\12\21\21\0\3\21\1\0\10\20"+ + "\2\0\2\20\2\0\26\20\1\0\7\20\1\0\1\20\3\0\4\20"+ + "\2\0\1\21\1\0\7\21\2\0\2\21\2\0\3\21\11\0\1\21"+ + "\4\0\2\20\1\0\3\20\2\21\2\0\12\21\4\20\16\0\1\21"+ + "\2\0\6\20\4\0\2\20\2\0\26\20\1\0\7\20\1\0\2\20"+ + "\1\0\2\20\1\0\2\20\2\0\1\21\1\0\5\21\4\0\2\21"+ + "\2\0\3\21\13\0\4\20\1\0\1\20\7\0\14\21\3\20\14\0"+ + "\3\21\1\0\7\20\1\0\1\20\1\0\3\20\1\0\26\20\1\0"+ + "\7\20\1\0\2\20\1\0\5\20\2\0\1\21\1\20\10\21\1\0"+ + "\3\21\1\0\3\21\2\0\1\20\17\0\1\20\5\0\12\21\21\0"+ + "\3\21\1\0\10\20\2\0\2\20\2\0\26\20\1\0\7\20\1\0"+ + "\2\20\2\0\4\20\2\0\1\21\1\20\6\21\3\0\2\21\2\0"+ + "\3\21\10\0\2\21\4\0\2\20\1\0\3\20\4\0\12\21\22\0"+ + "\2\21\1\0\6\20\3\0\3\20\1\0\4\20\3\0\2\20\1\0"+ + "\1\20\1\0\2\20\3\0\2\20\3\0\3\20\3\0\10\20\1\0"+ + "\3\20\4\0\5\21\3\0\3\21\1\0\4\21\11\0\1\21\17\0"+ + "\11\21\21\0\3\21\1\0\10\20\1\0\3\20\1\0\27\20\1\0"+ + "\12\20\1\0\5\20\4\0\7\21\1\0\3\21\1\0\4\21\7\0"+ + "\2\21\11\0\2\20\4\0\12\21\22\0\2\21\1\0\10\20\1\0"+ + "\3\20\1\0\27\20\1\0\12\20\1\0\5\20\4\0\7\21\1\0"+ + "\3\21\1\0\4\21\7\0\2\21\7\0\1\20\1\0\2\20\4\0"+ + "\12\21\22\0\2\21\1\0\10\20\1\0\3\20\1\0\27\20\1\0"+ + "\20\20\4\0\6\21\2\0\3\21\1\0\4\21\11\0\1\21\10\0"+ + "\2\20\4\0\12\21\22\0\2\21\1\0\22\20\3\0\30\20\1\0"+ + "\11\20\1\0\1\20\2\0\7\20\3\0\1\21\4\0\6\21\1\0"+ + "\1\21\1\0\10\21\22\0\2\21\15\0\60\20\1\21\2\20\7\21"+ + "\4\0\10\20\10\21\1\0\12\21\47\0\2\20\1\0\1\20\2\0"+ + "\2\20\1\0\1\20\2\0\1\20\6\0\4\20\1\0\7\20\1\0"+ + "\3\20\1\0\1\20\1\0\1\20\2\0\2\20\1\0\4\20\1\21"+ + "\2\20\6\21\1\0\2\21\1\20\2\0\5\20\1\0\1\20\1\0"+ + "\6\21\2\0\12\21\2\0\2\20\42\0\1\20\27\0\2\21\6\0"+ + "\12\21\13\0\1\21\1\0\1\21\1\0\1\21\4\0\2\21\10\20"+ + "\1\0\42\20\6\0\24\21\1\0\2\21\4\20\4\0\10\21\1\0"+ + "\44\21\11\0\1\21\71\0\42\20\1\0\5\20\1\0\2\20\1\0"+ + "\7\21\3\0\4\21\6\0\12\21\6\0\6\20\4\21\106\0\46\20"+ + "\12\0\47\20\11\0\132\20\5\0\104\20\5\0\122\20\6\0\7\20"+ + "\1\0\77\20\1\0\1\20\1\0\4\20\2\0\7\20\1\0\1\20"+ + "\1\0\4\20\2\0\47\20\1\0\1\20\1\0\4\20\2\0\37\20"+ + "\1\0\1\20\1\0\4\20\2\0\7\20\1\0\1\20\1\0\4\20"+ + "\2\0\7\20\1\0\7\20\1\0\27\20\1\0\37\20\1\0\1\20"+ + "\1\0\4\20\2\0\7\20\1\0\47\20\1\0\23\20\16\0\11\21"+ + "\56\0\125\20\14\0\u026c\20\2\0\10\20\12\0\32\20\5\0\113\20"+ + "\225\0\64\20\40\21\7\0\1\20\4\0\12\21\41\0\4\21\1\0"+ + "\12\21\6\0\130\20\10\0\51\20\1\21\u0556\0\234\20\4\0\132\20"+ + "\6\0\26\20\2\0\6\20\2\0\46\20\2\0\6\20\2\0\10\20"+ + "\1\0\1\20\1\0\1\20\1\0\1\20\1\0\37\20\2\0\65\20"+ + "\1\0\7\20\1\0\1\20\3\0\3\20\1\0\7\20\3\0\4\20"+ + "\2\0\6\20\4\0\15\20\5\0\3\20\1\0\7\20\17\0\4\21"+ + "\30\0\2\11\5\21\20\0\2\20\51\0\6\21\17\0\1\20\40\0"+ + "\20\20\40\0\15\21\4\0\1\21\40\0\1\20\4\0\1\20\2\0"+ + "\12\20\1\0\1\20\3\0\5\20\6\0\1\20\1\0\1\20\1\0"+ + "\1\20\1\0\4\20\1\0\3\20\1\0\7\20\46\0\44\20\u0e81\0"+ + "\3\20\31\0\11\20\6\21\1\0\5\20\2\0\3\20\6\0\124\20"+ + "\4\0\2\21\2\0\2\20\2\0\136\20\6\0\50\20\4\0\136\20"+ + "\21\0\30\20\u0248\0\u19b6\20\112\0\u51a6\20\132\0\u048d\20\u0773\0\u2ba4\20"+ + "\u215c\0\u012e\20\322\0\7\20\14\0\5\20\5\0\1\20\1\21\12\20"+ + "\1\0\15\20\1\0\5\20\1\0\1\20\1\0\2\20\1\0\2\20"+ + "\1\0\154\20\41\0\u016b\20\22\0\100\20\2\0\66\20\50\0\14\20"+ + "\44\0\4\21\17\0\2\20\30\0\3\20\31\0\1\20\6\0\3\20"+ + "\1\0\1\20\1\0\207\20\2\0\1\21\4\0\1\20\13\0\12\21"+ + "\7\0\32\20\4\0\1\20\1\0\32\20\12\0\132\20\3\0\6\20"+ + "\2\0\6\20\2\0\6\20\2\0\3\20\3\0\2\20\3\0\2\20"+ + "\22\0\3\21\4\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 = + "\1\1\1\2\14\0\1\1\2\3\1\1\1\2\3\4"+ + "\1\5\1\6\2\7\1\6\1\10\2\6\1\4\1\11"+ + "\1\12\1\6\1\11\1\13\1\4\1\14\1\15\2\16"+ + "\1\6\2\17\1\20\1\21\1\22\1\23\1\24\1\25"+ + "\1\16\1\26\1\27\1\30\1\31\1\32\1\33\1\34"+ + "\1\35\1\36\1\37\3\4\1\40\1\41\1\6\1\42"+ + "\1\43\1\44\1\4\2\45\1\46\1\16\1\47\1\50"+ + "\1\51\1\52\1\16\1\53\1\54\1\4\2\44\1\4"+ + "\1\55\1\4\1\56\1\13\1\57\3\0\1\60\1\61"+ + "\1\0\1\62\1\0\2\11\1\0\15\11\3\0\1\63"+ + "\1\11\1\64\1\11\1\0\1\65\1\6\1\0\1\66"+ + "\1\67\2\66\1\67\1\70\1\71\1\72\1\73\1\74"+ + "\1\0\1\75\1\0\1\76\1\77\4\0\2\100\10\0"+ + "\1\101\1\102\2\101\1\102\1\103\1\104\1\105\1\106"+ + "\1\107\1\110\3\0\1\111\5\0\1\112\1\0\1\57"+ + "\2\6\1\11\2\113\34\11\3\0\2\114\1\11\2\115"+ + "\1\11\1\0\1\67\1\0\1\116\5\0\1\117\2\0"+ + "\1\37\4\0\1\102\1\0\1\120\1\121\2\122\3\0"+ + "\2\11\1\123\24\11\1\124\11\11\3\0\2\11\1\0"+ + "\2\116\14\0\2\120\3\0\20\11\1\125\3\11\1\126"+ + "\7\11\1\127\6\11\1\130\1\11\1\125\1\0\2\11"+ + "\1\0\1\116\13\0\1\120\5\0\11\11\1\0\1\11"+ + "\1\131\5\11\1\132\1\133\16\11\1\134\1\135\2\11"+ + "\7\0\2\37\10\0\2\136\3\0\11\11\1\137\11\11"+ + "\1\140\3\11\1\141\1\0\3\11\1\142\1\143\2\11"+ + "\6\0\1\144\1\37\3\0\1\37\6\0\2\145\4\0"+ + "\1\135\1\11\1\146\1\123\3\11\1\147\2\150\1\137"+ + "\1\0\11\11\2\151\1\11\1\152\1\11\2\153\1\11"+ + "\1\154\6\0\1\37\6\0\1\37\13\0\1\11\1\155"+ + "\2\11\1\150\1\156\1\150\1\137\1\0\2\11\1\157"+ + "\2\11\1\160\3\11\1\151\1\161\1\151\1\162\1\152"+ + "\1\163\1\153\2\164\1\153\4\0\1\165\1\166\2\37"+ + "\4\0\2\37\7\0\2\167\1\0\3\11\2\156\1\170"+ + "\2\171\1\0\1\11\1\0\5\11\2\161\2\164\2\0"+ + "\1\172\2\0\1\37\2\0\2\37\4\0\1\37\2\0"+ + "\2\37\7\0\2\173\1\11\1\156\1\0\1\170\1\171"+ + "\1\174\1\171\2\0\2\11\1\175\1\11\1\176\1\177"+ + "\2\200\1\161\4\0\1\201\1\0\4\37\3\0\4\37"+ + "\3\0\2\202\1\0\1\173\1\203\1\173\1\204\2\174"+ + "\2\0\2\11\1\175\2\205\1\200\1\206\1\200\7\0"+ + "\3\37\5\0\3\37\1\0\2\207\1\0\2\203\1\174"+ + "\3\0\2\11\1\205\1\210\1\205\2\206\1\211\1\212"+ + "\4\0\1\37\3\0\1\37\2\213\1\203\1\0\1\157"+ + "\1\0\1\157\1\11\2\210\1\206\4\0\1\37\2\0"+ + "\1\37\2\214\1\210\4\0\1\215"; + + private static int [] zzUnpackAction() { + int [] result = new int[764]; + 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\106\0\214\0\322\0\u0118\0\u015e\0\u01a4\0\u01ea"+ + "\0\u0230\0\u0276\0\u02bc\0\u0302\0\u0348\0\u038e\0\u03d4\0\u03d4"+ + "\0\u041a\0\u0460\0\u04a6\0\u04ec\0\u0532\0\u041a\0\u0578\0\u05be"+ + "\0\u041a\0\u0604\0\u064a\0\u0690\0\u06d6\0\u071c\0\u0762\0\u07a8"+ + "\0\u07ee\0\u0834\0\u087a\0\u08c0\0\u0906\0\u041a\0\u094c\0\u041a"+ + "\0\u0992\0\u09d8\0\u0a1e\0\u0a64\0\u041a\0\u0aaa\0\u041a\0\u0af0"+ + "\0\u041a\0\u0b36\0\u0b7c\0\u0bc2\0\u041a\0\u041a\0\u041a\0\u041a"+ + "\0\u041a\0\u041a\0\u041a\0\u041a\0\u0c08\0\u0c4e\0\u0c94\0\u0cda"+ + "\0\u041a\0\u041a\0\u0d20\0\u041a\0\u0d66\0\u0dac\0\u0df2\0\u041a"+ + "\0\u0e38\0\u041a\0\u0e7e\0\u0e7e\0\u0aaa\0\u041a\0\u041a\0\u0ec4"+ + "\0\u041a\0\u0f0a\0\u0f50\0\u0f50\0\u041a\0\u0f96\0\u041a\0\u0fdc"+ + "\0\u041a\0\u1022\0\u1068\0\u10ae\0\u10f4\0\u04ec\0\u041a\0\u041a"+ + "\0\u0532\0\u041a\0\u113a\0\u1180\0\u11c6\0\u120c\0\u1252\0\u1298"+ + "\0\u12de\0\u1324\0\u136a\0\u13b0\0\u13f6\0\u143c\0\u1482\0\u14c8"+ + "\0\u150e\0\u1554\0\u159a\0\u15e0\0\u1626\0\u166c\0\u041a\0\u16b2"+ + "\0\u16f8\0\u173e\0\u0906\0\u041a\0\u1784\0\u17ca\0\u041a\0\u1810"+ + "\0\u1856\0\u189c\0\u18e2\0\u041a\0\u041a\0\u041a\0\u041a\0\u041a"+ + "\0\u0a1e\0\u0b36\0\u1928\0\u041a\0\u196e\0\u19b4\0\u0b36\0\u19fa"+ + "\0\u0bc2\0\u041a\0\u1a40\0\u0c4e\0\u0c94\0\u0cda\0\u1a86\0\u1acc"+ + "\0\u1b12\0\u1b58\0\u1b9e\0\u041a\0\u1be4\0\u1c2a\0\u1c70\0\u1cb6"+ + "\0\u041a\0\u041a\0\u041a\0\u041a\0\u041a\0\u041a\0\u0e7e\0\u0aaa"+ + "\0\u1cfc\0\u041a\0\u0f50\0\u1d42\0\u1d88\0\u1dce\0\u1e14\0\u1e5a"+ + "\0\u0fdc\0\u041a\0\u113a\0\u041a\0\u1ea0\0\u120c\0\u041a\0\u1ee6"+ + "\0\u1f2c\0\u1f72\0\u1fb8\0\u1ffe\0\u2044\0\u208a\0\u20d0\0\u2116"+ + "\0\u215c\0\u21a2\0\u21e8\0\u222e\0\u2274\0\u22ba\0\u2300\0\u2346"+ + "\0\u238c\0\u23d2\0\u2418\0\u245e\0\u24a4\0\u24ea\0\u2530\0\u2576"+ + "\0\u25bc\0\u2602\0\u2648\0\u268e\0\u26d4\0\u271a\0\u2760\0\u27a6"+ + "\0\u27ec\0\u2832\0\u2878\0\u28be\0\u2904\0\u041a\0\u294a\0\u2990"+ + "\0\u29d6\0\u2a1c\0\u2a62\0\u2aa8\0\u2aee\0\u041a\0\u2b34\0\u2b7a"+ + "\0\u2bc0\0\u2c06\0\u2c4c\0\u2c92\0\u2cd8\0\u041a\0\u2d1e\0\u2d64"+ + "\0\u041a\0\u1d42\0\u041a\0\u2daa\0\u2df0\0\u2e36\0\u2e7c\0\u2ec2"+ + "\0\u2f08\0\u2f4e\0\u2f94\0\u2fda\0\u3020\0\u3066\0\u30ac\0\u30f2"+ + "\0\u3138\0\u317e\0\u31c4\0\u320a\0\u3250\0\u3296\0\u32dc\0\u3322"+ + "\0\u3368\0\u33ae\0\u33f4\0\u343a\0\u3480\0\u34c6\0\u350c\0\u3552"+ + "\0\u3598\0\u35de\0\u3624\0\u366a\0\u36b0\0\u36f6\0\u373c\0\u3782"+ + "\0\u37c8\0\u380e\0\u3854\0\u389a\0\u38e0\0\u041a\0\u3926\0\u396c"+ + "\0\u39b2\0\u39f8\0\u3a3e\0\u3a84\0\u3aca\0\u3b10\0\u3b56\0\u3b9c"+ + "\0\u3be2\0\u3c28\0\u3c6e\0\u041a\0\u3cb4\0\u3cfa\0\u3d40\0\u3d86"+ + "\0\u3dcc\0\u3e12\0\u3e58\0\u3e9e\0\u3ee4\0\u3f2a\0\u3f70\0\u3fb6"+ + "\0\u3ffc\0\u4042\0\u4088\0\u40ce\0\u4114\0\u415a\0\u41a0\0\u41e6"+ + "\0\u1180\0\u422c\0\u4272\0\u42b8\0\u1180\0\u42fe\0\u4344\0\u438a"+ + "\0\u43d0\0\u4416\0\u445c\0\u44a2\0\u1180\0\u44e8\0\u452e\0\u4574"+ + "\0\u45ba\0\u4600\0\u4646\0\u1180\0\u468c\0\u041a\0\u46d2\0\u4718"+ + "\0\u475e\0\u47a4\0\u294a\0\u47ea\0\u4830\0\u4876\0\u48bc\0\u4902"+ + "\0\u4948\0\u498e\0\u49d4\0\u4a1a\0\u4a60\0\u4aa6\0\u2d1e\0\u4aec"+ + "\0\u4b32\0\u4b78\0\u4bbe\0\u4c04\0\u4c4a\0\u4c90\0\u4cd6\0\u4d1c"+ + "\0\u4d62\0\u4da8\0\u4dee\0\u4e34\0\u4e7a\0\u4ec0\0\u4f06\0\u1180"+ + "\0\u4f4c\0\u4f92\0\u4fd8\0\u501e\0\u5064\0\u1180\0\u1180\0\u50aa"+ + "\0\u50f0\0\u5136\0\u517c\0\u51c2\0\u5208\0\u524e\0\u5294\0\u52da"+ + "\0\u5320\0\u5366\0\u53ac\0\u53f2\0\u5438\0\u1180\0\u041a\0\u547e"+ + "\0\u54c4\0\u550a\0\u5550\0\u5596\0\u55dc\0\u5622\0\u5668\0\u56ae"+ + "\0\u56f4\0\u573a\0\u5780\0\u57c6\0\u580c\0\u5852\0\u5898\0\u58de"+ + "\0\u5924\0\u596a\0\u4b32\0\u041a\0\u59b0\0\u59f6\0\u5a3c\0\u5a82"+ + "\0\u5ac8\0\u5b0e\0\u5b54\0\u5b9a\0\u5be0\0\u5c26\0\u5c6c\0\u5cb2"+ + "\0\u5cf8\0\u5d3e\0\u5d84\0\u5dca\0\u5e10\0\u5e56\0\u5e9c\0\u5ee2"+ + "\0\u5f28\0\u5f6e\0\u1180\0\u5fb4\0\u5ffa\0\u6040\0\u1180\0\u6086"+ + "\0\u60cc\0\u6112\0\u6158\0\u1180\0\u1180\0\u619e\0\u2878\0\u61e4"+ + "\0\u622a\0\u6270\0\u62b6\0\u62fc\0\u6342\0\u6388\0\u63ce\0\u6414"+ + "\0\u645a\0\u64a0\0\u64e6\0\u652c\0\u6572\0\u65b8\0\u65fe\0\u6644"+ + "\0\u668a\0\u5924\0\u041a\0\u66d0\0\u6716\0\u675c\0\u67a2\0\u1180"+ + "\0\u67e8\0\u1180\0\u1180\0\u682e\0\u6874\0\u68ba\0\u1180\0\u6900"+ + "\0\u6946\0\u698c\0\u69d2\0\u6a18\0\u6a5e\0\u6aa4\0\u6aea\0\u6b30"+ + "\0\u6b76\0\u6bbc\0\u6c02\0\u6c48\0\u6c8e\0\u6cd4\0\u6d1a\0\u6d60"+ + "\0\u6da6\0\u6dec\0\u6e32\0\u27a6\0\u041a\0\u6e78\0\u6ebe\0\u6f04"+ + "\0\u6f4a\0\u6f90\0\u6fd6\0\u701c\0\u7062\0\u70a8\0\u70ee\0\u7134"+ + "\0\u717a\0\u71c0\0\u7206\0\u724c\0\u7292\0\u72d8\0\u731e\0\u7364"+ + "\0\u73aa\0\u73f0\0\u7436\0\u747c\0\u74c2\0\u7508\0\u754e\0\u7594"+ + "\0\u75da\0\u7620\0\u7666\0\u76ac\0\u76f2\0\u7738\0\u777e\0\u77c4"+ + "\0\u780a\0\u7850\0\u7896\0\u78dc\0\u1180\0\u7922\0\u7968\0\u79ae"+ + "\0\u79f4\0\u7a3a\0\u7a80\0\u1180\0\u7ac6\0\u1180\0\u7b0c\0\u7b52"+ + "\0\u7b98\0\u7bde\0\u7c24\0\u7c6a\0\u7cb0\0\u7cf6\0\u041a\0\u041a"+ + "\0\u7d3c\0\u7d82\0\u7dc8\0\u7e0e\0\u7e54\0\u7e9a\0\u7ee0\0\u7f26"+ + "\0\u7f6c\0\u7fb2\0\u7ff8\0\u803e\0\u8084\0\u80ca\0\u8110\0\u74c2"+ + "\0\u041a\0\u8156\0\u819c\0\u81e2\0\u8228\0\u826e\0\u82b4\0\u82fa"+ + "\0\u8340\0\u8386\0\u83cc\0\u8412\0\u8458\0\u849e\0\u84e4\0\u852a"+ + "\0\u8570\0\u85b6\0\u85fc\0\u8642\0\u8688\0\u86ce\0\u8714\0\u875a"+ + "\0\u041a\0\u87a0\0\u87e6\0\u882c\0\u8872\0\u88b8\0\u88fe\0\u8944"+ + "\0\u898a\0\u89d0\0\u8a16\0\u8a5c\0\u8aa2\0\u8ae8\0\u8b2e\0\u8b74"+ + "\0\u8bba\0\u8c00\0\u8c46\0\u8c8c\0\u8cd2\0\u8d18\0\u8d5e\0\u8da4"+ + "\0\u8dea\0\u8e30\0\u8e76\0\u8ebc\0\u8f02\0\u8f48\0\u8f8e\0\u8fd4"+ + "\0\u901a\0\u9060\0\u90a6\0\u90ec\0\u9132\0\u9178\0\u91be\0\u1180"+ + "\0\u1180\0\u9204\0\u924a\0\u9290\0\u92d6\0\u931c\0\u9362\0\u93a8"+ + "\0\u041a\0\u93ee\0\u9434\0\u947a\0\u94c0\0\u9506\0\u954c\0\u9592"+ + "\0\u95d8\0\u961e\0\u9664\0\u96aa\0\u96f0\0\u9736\0\u977c\0\u97c2"+ + "\0\u8d5e\0\u041a\0\u9808\0\u984e\0\u9894\0\u98da\0\u9920\0\u9966"+ + "\0\u99ac\0\u99f2\0\u9a38\0\u9a7e\0\u9ac4\0\u9b0a\0\u9b50\0\u9b96"+ + "\0\u9bdc\0\u9c22\0\u9c68\0\u9cae\0\u9cf4\0\u9d3a\0\u9d80\0\u9dc6"+ + "\0\u9e0c\0\u9e52\0\u9e98\0\u9ede\0\u9f24\0\u9f6a\0\u9fb0\0\u9ff6"+ + "\0\ua03c\0\ua082\0\ua0c8\0\ua10e\0\ua154\0\ua19a\0\u97c2\0\u041a"+ + "\0\ua1e0\0\ua226\0\ua26c\0\ua2b2\0\ua2f8\0\ua33e\0\ua384\0\ua3ca"+ + "\0\ua410\0\ua456\0\ua49c\0\ua4e2\0\ua528\0\ua56e\0\u041a\0\u041a"+ + "\0\ua5b4\0\ua5fa\0\ua640\0\ua686\0\ua6cc\0\ua712\0\ua758\0\ua79e"+ + "\0\ua7e4\0\ua1e0\0\u041a\0\ua82a\0\ua870\0\u041a\0\ua8b6\0\u1180"+ + "\0\ua8fc\0\ua942\0\ua988\0\ua9ce\0\uaa14\0\uaa5a\0\uaaa0\0\uaae6"+ + "\0\uab2c\0\uab72\0\uabb8\0\uabfe\0\u041a\0\u1180\0\uac44\0\uac8a"+ + "\0\uacd0\0\uad16\0\uad5c\0\u041a"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[764]; + 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 = + "\11\17\2\20\1\21\7\17\1\20\5\17\1\22\54\17"+ + "\24\23\1\24\1\25\60\23\2\26\1\27\2\26\2\27"+ + "\1\26\1\30\1\31\1\32\1\31\1\26\1\33\2\26"+ + "\1\27\2\26\1\31\7\26\25\27\4\26\1\27\2\26"+ + "\3\27\10\26\1\27\5\26\1\34\2\26\2\34\1\26"+ + "\1\35\3\36\4\26\1\34\1\26\1\35\1\36\1\26"+ + "\1\37\3\26\1\40\1\26\25\34\4\26\1\34\1\41"+ + "\1\26\3\34\10\26\1\34\5\26\1\34\2\26\2\34"+ + "\1\26\1\42\3\36\4\26\1\34\1\26\1\42\1\36"+ + "\1\26\1\37\3\26\1\43\1\26\25\34\4\26\1\34"+ + "\1\41\1\26\3\34\10\26\1\34\13\26\4\44\6\26"+ + "\2\44\1\26\1\45\2\26\1\46\35\26\1\47\17\26"+ + "\4\50\1\51\3\50\1\52\1\53\1\54\1\53\1\55"+ + "\1\50\1\56\3\50\1\52\1\53\1\57\1\60\1\61"+ + "\3\50\1\62\33\50\1\63\4\50\1\64\1\65\1\66"+ + "\1\67\1\70\1\71\1\72\1\73\1\74\2\50\25\75"+ + "\1\76\1\77\1\100\1\101\1\75\1\102\53\75\2\26"+ + "\1\34\2\26\2\34\1\26\4\103\1\26\1\104\2\26"+ + "\1\34\1\26\2\103\7\26\25\34\4\26\1\34\2\26"+ + "\3\34\1\105\7\26\1\34\3\26\4\106\1\107\4\106"+ + "\1\110\1\111\1\110\7\106\1\110\2\106\1\112\57\106"+ + "\4\50\1\51\3\50\3\113\1\114\2\50\1\115\1\116"+ + "\2\50\2\113\2\50\1\117\3\50\1\120\50\50\1\121"+ + "\1\50\1\122\11\123\2\124\1\125\7\123\1\124\5\123"+ + "\1\126\54\123\10\26\1\35\2\26\1\127\1\26\1\130"+ + "\4\26\1\35\5\26\1\131\65\26\4\132\6\26\2\132"+ + "\62\26\11\17\2\20\1\21\7\17\1\20\62\17\106\0"+ + "\11\17\2\20\1\21\7\17\1\20\5\17\1\133\54\17"+ + "\24\23\1\134\1\135\104\23\1\136\1\137\104\23\1\140"+ + "\1\141\60\23\1\0\3\27\1\0\3\27\10\0\4\27"+ + "\7\0\32\27\2\0\3\27\10\0\1\27\13\0\1\30"+ + "\4\0\1\33\103\0\1\31\102\0\1\33\76\0\3\34"+ + "\1\0\3\34\10\0\4\34\7\0\32\34\2\0\3\34"+ + "\10\0\1\34\13\0\1\35\11\0\1\35\74\0\3\36"+ + "\7\0\1\36\106\0\1\142\1\143\62\0\1\144\2\0"+ + "\1\144\1\145\11\0\1\144\11\0\1\146\1\147\1\150"+ + "\1\151\4\144\1\152\1\153\1\154\1\155\1\144\1\156"+ + "\1\157\1\160\1\144\1\161\1\144\1\162\1\163\1\144"+ + "\1\164\1\165\1\166\1\0\1\144\2\0\3\144\10\0"+ + "\1\144\13\0\1\41\11\0\1\41\73\0\1\42\11\0"+ + "\1\42\6\0\1\167\56\0\1\144\2\0\1\170\1\145"+ + "\11\0\1\144\10\0\1\171\1\146\1\147\1\150\1\151"+ + "\4\144\1\152\1\153\1\154\1\155\1\144\1\156\1\172"+ + "\1\160\1\144\1\161\1\144\1\162\1\163\1\144\1\164"+ + "\1\165\1\166\1\0\1\144\2\0\3\144\10\0\1\144"+ + "\13\0\4\44\6\0\2\44\1\0\1\173\2\0\1\46"+ + "\35\0\1\47\43\0\1\174\1\175\146\0\1\176\17\0"+ + "\3\177\1\200\1\177\1\201\1\202\1\203\3\177\1\0"+ + "\20\177\1\204\1\205\1\177\1\206\3\177\1\207\7\177"+ + "\1\210\4\177\1\200\1\177\1\203\1\200\22\177\10\0"+ + "\1\52\3\211\1\55\1\0\1\56\3\0\1\52\1\211"+ + "\1\57\1\60\1\61\3\0\1\212\40\0\1\64\1\65"+ + "\1\66\1\67\1\70\1\71\1\72\1\73\1\74\12\0"+ + "\4\211\1\55\1\0\1\56\3\0\2\211\1\57\1\60"+ + "\1\61\3\0\1\212\40\0\1\64\1\65\1\66\1\67"+ + "\1\70\1\71\1\72\1\73\1\74\12\0\3\211\1\53"+ + "\1\55\1\0\1\56\3\0\2\211\1\57\1\60\1\61"+ + "\3\0\1\212\40\0\1\64\1\65\1\66\1\67\1\70"+ + "\1\71\1\72\1\73\1\74\106\0\1\213\25\0\1\214"+ + "\1\175\61\0\1\215\1\216\1\215\1\0\2\216\1\215"+ + "\1\217\7\0\1\216\1\0\1\217\10\0\25\216\4\215"+ + "\1\216\2\0\3\216\10\0\1\216\71\0\1\220\27\0"+ + "\1\221\1\222\1\223\1\222\6\0\1\221\1\222\62\0"+ + "\25\75\1\224\1\225\1\226\1\0\1\75\1\0\77\75"+ + "\1\227\1\230\60\75\4\225\1\231\4\225\3\0\7\225"+ + "\1\0\2\225\1\75\57\225\4\232\1\233\4\232\3\0"+ + "\7\232\1\0\3\232\1\0\56\232\10\0\4\103\6\0"+ + "\2\103\72\0\4\105\6\0\2\105\62\0\4\106\1\0"+ + "\4\106\3\0\7\106\1\0\2\106\1\0\57\106\3\234"+ + "\1\235\1\234\1\236\1\237\1\240\3\234\1\0\12\234"+ + "\1\241\5\234\1\242\1\243\1\234\1\244\3\234\1\245"+ + "\7\234\1\246\4\234\1\235\1\234\1\240\1\235\22\234"+ + "\13\0\1\110\102\0\4\247\2\0\1\250\3\0\2\247"+ + "\64\0\1\251\2\0\2\251\11\0\1\251\12\0\25\251"+ + "\4\0\1\251\2\0\3\251\10\0\1\251\22\0\1\252"+ + "\66\0\11\253\2\124\1\125\7\253\1\124\73\253\2\124"+ + "\1\125\7\253\1\124\4\253\1\254\2\253\1\255\6\253"+ + "\1\256\1\253\1\257\41\253\1\0\1\260\1\0\1\260"+ + "\3\0\1\260\1\261\11\0\1\261\35\0\4\260\32\0"+ + "\4\132\6\0\2\132\62\0\13\133\1\262\72\133\24\23"+ + "\1\134\1\0\104\23\1\0\1\135\60\23\11\143\2\263"+ + "\1\264\7\143\1\263\62\143\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\32\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\1\144"+ + "\1\265\30\144\2\0\3\144\10\0\1\144\3\0\11\146"+ + "\2\266\1\267\7\146\1\266\62\146\1\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\1\144\1\270\15\144\1\271"+ + "\4\144\1\272\5\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\5\144\1\273"+ + "\24\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\3\144\1\274\5\144\1\275"+ + "\2\144\1\276\15\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\1\277\2\144\10\0\4\144\7\0\5\144"+ + "\1\300\24\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\1\144\1\301\1\144\10\0\4\144\7\0\1\302"+ + "\31\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\11\144\1\303\20\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\1\304\31\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\20\144"+ + "\1\305\1\144\1\306\7\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\2\144"+ + "\1\307\3\144\1\310\7\144\1\311\13\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\1\144\1\312\1\144"+ + "\10\0\4\144\7\0\3\144\1\313\1\144\1\314\4\144"+ + "\1\315\1\144\1\316\15\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\1\144\1\317\1\144\10\0\4\144"+ + "\7\0\11\144\1\320\20\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\1\144\1\321\1\144\10\0\4\144"+ + "\7\0\14\144\1\322\15\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\7\144"+ + "\1\323\22\144\2\0\3\144\10\0\1\144\56\0\1\324"+ + "\105\0\1\325\115\0\1\326\23\0\3\144\1\0\3\144"+ + "\1\327\7\0\2\144\1\330\1\144\7\0\15\144\1\331"+ + "\14\144\2\0\3\144\10\0\1\144\3\0\11\171\3\0"+ + "\7\171\1\0\62\171\1\0\3\144\1\0\3\144\1\332"+ + "\7\0\2\144\1\333\1\144\7\0\2\144\1\334\3\144"+ + "\1\310\7\144\1\311\13\144\2\0\3\144\10\0\1\144"+ + "\3\0\11\175\3\0\7\175\1\0\62\175\67\0\1\335"+ + "\21\0\1\336\3\0\1\336\50\0\1\336\1\0\2\336"+ + "\23\0\3\337\3\0\1\337\32\0\2\337\3\0\1\337"+ + "\1\0\1\337\1\0\1\337\2\0\1\337\1\0\4\337"+ + "\3\0\1\337\1\0\1\337\15\0\3\340\3\0\1\340"+ + "\32\0\2\340\3\0\1\340\1\0\1\340\1\0\1\340"+ + "\2\0\1\340\1\0\4\340\3\0\1\340\1\0\1\340"+ + "\17\0\1\200\3\0\1\200\50\0\1\200\1\0\2\200"+ + "\30\0\1\341\36\0\1\342\6\0\1\343\1\0\1\344"+ + "\30\0\1\215\1\0\1\215\3\0\1\215\50\0\4\215"+ + "\23\0\3\216\1\0\3\216\1\345\7\0\4\216\4\0"+ + "\1\346\2\0\32\216\2\0\3\216\10\0\1\216\72\0"+ + "\1\347\31\0\1\222\72\0\24\227\1\350\61\227\11\230"+ + "\2\351\1\75\7\230\1\351\62\230\11\225\3\0\7\225"+ + "\1\0\62\225\27\0\1\75\56\0\3\232\1\352\1\353"+ + "\1\232\1\354\1\355\1\232\3\0\7\232\1\0\34\232"+ + "\1\352\1\232\1\355\1\352\22\232\3\0\1\356\3\0"+ + "\1\356\50\0\1\356\1\0\2\356\23\0\3\357\3\0"+ + "\1\357\32\0\2\357\3\0\1\357\1\0\1\357\1\0"+ + "\1\357\2\0\1\357\1\0\4\357\3\0\1\357\1\0"+ + "\1\357\15\0\3\360\3\0\1\360\32\0\2\360\3\0"+ + "\1\360\1\0\1\360\1\0\1\360\2\0\1\360\1\0"+ + "\4\360\3\0\1\360\1\0\1\360\17\0\1\235\3\0"+ + "\1\235\50\0\1\235\1\0\2\235\23\0\3\251\1\0"+ + "\3\251\10\0\4\251\4\0\1\361\2\0\32\251\2\0"+ + "\3\251\10\0\1\251\3\0\11\254\2\362\1\363\7\254"+ + "\1\362\62\254\11\253\2\124\1\125\7\253\1\124\10\253"+ + "\1\364\62\253\2\124\1\125\7\253\1\124\14\253\1\365"+ + "\56\253\2\124\1\125\7\253\1\124\20\253\1\366\41\253"+ + "\1\0\1\260\1\0\1\260\3\0\1\260\50\0\4\260"+ + "\23\0\3\144\1\0\3\144\10\0\4\144\7\0\1\367"+ + "\31\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\1\370\1\144\1\371\13\144"+ + "\1\372\13\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\22\144\1\373\7\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\1\144\1\374\30\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\2\144\1\375\27\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\4\144"+ + "\1\376\25\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\22\144\1\377\7\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\20\144\1\u0100\11\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\2\144\1\u0101\27\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\10\144"+ + "\1\u0102\21\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\1\144\1\u0103\10\144"+ + "\1\u0104\17\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\1\144\1\u0105\30\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u0106\2\144\1\u0107\17\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\1\144\1\u0108\30\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\15\144\1\u0109\14\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\1\u010a"+ + "\31\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\14\144\1\u010b\15\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\1\u010c\31\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\14\144"+ + "\1\u010d\15\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\22\144\1\u010e\7\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\14\144\1\u010f\15\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\12\144\1\u0110\17\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\14\144"+ + "\1\u0111\15\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\15\144\1\u0112\14\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\10\144\1\u0113\21\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\14\144\1\u0114\15\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\20\144"+ + "\1\u0115\11\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\16\144\1\u0116\13\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\20\144\1\u0117\11\144\2\0\3\144"+ + "\10\0\1\144\36\0\1\u0118\105\0\1\u0119\125\0\1\u011a"+ + "\42\0\1\327\11\0\1\327\64\0\3\144\1\0\3\144"+ + "\1\327\7\0\2\144\1\330\1\144\7\0\32\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\2\144\1\u011b\27\144\2\0\3\144\10\0"+ + "\1\144\13\0\1\332\11\0\1\332\64\0\3\144\1\0"+ + "\3\144\1\332\7\0\2\144\1\333\1\144\7\0\32\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\14\144\1\u011c\15\144\2\0\3\144"+ + "\10\0\1\144\73\0\1\u011d\16\0\3\u011e\3\0\1\u011e"+ + "\32\0\2\u011e\3\0\1\u011e\1\0\1\u011e\1\0\1\u011e"+ + "\2\0\1\u011e\1\0\4\u011e\3\0\1\u011e\1\0\1\u011e"+ + "\15\0\3\u011f\3\0\1\u011f\32\0\2\u011f\3\0\1\u011f"+ + "\1\0\1\u011f\1\0\1\u011f\2\0\1\u011f\1\0\4\u011f"+ + "\3\0\1\u011f\1\0\1\u011f\71\0\1\u0120\70\0\1\u0121"+ + "\1\0\1\u0122\110\0\1\u0123\73\0\1\u0124\62\0\1\345"+ + "\11\0\1\345\5\0\1\346\145\0\1\u0125\15\0\24\227"+ + "\1\350\1\75\60\227\13\351\1\75\11\351\1\u0126\1\u0127"+ + "\1\u0128\1\230\1\351\1\230\53\351\3\0\1\232\3\0"+ + "\1\232\17\0\1\75\30\0\1\232\1\0\2\232\26\0"+ + "\1\u0129\1\0\1\u012a\20\0\1\75\57\0\3\u012b\3\0"+ + "\1\u012b\17\0\1\75\12\0\2\u012b\3\0\1\u012b\1\0"+ + "\1\u012b\1\0\1\u012b\2\0\1\u012b\1\0\4\u012b\3\0"+ + "\1\u012b\1\0\1\u012b\17\0\1\352\3\0\1\352\17\0"+ + "\1\75\30\0\1\352\1\0\2\352\23\0\3\u012c\3\0"+ + "\1\u012c\32\0\2\u012c\3\0\1\u012c\1\0\1\u012c\1\0"+ + "\1\u012c\2\0\1\u012c\1\0\4\u012c\3\0\1\u012c\1\0"+ + "\1\u012c\15\0\3\u012d\3\0\1\u012d\32\0\2\u012d\3\0"+ + "\1\u012d\1\0\1\u012d\1\0\1\u012d\2\0\1\u012d\1\0"+ + "\4\u012d\3\0\1\u012d\1\0\1\u012d\14\0\11\253\2\124"+ + "\1\125\7\253\1\124\7\253\1\u012e\63\253\2\124\1\125"+ + "\7\253\1\124\17\253\1\u012f\53\253\2\124\1\125\7\253"+ + "\1\124\21\253\1\u0130\40\253\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\16\144\1\u0131\13\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\2\144\1\u0132\27\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\6\144"+ + "\1\u0133\1\u0134\22\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\12\144\1\u0135"+ + "\17\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\12\144\1\u0136\17\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\5\144\1\u0137\24\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\1\144\1\u0138\1\144\10\0"+ + "\4\144\7\0\32\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\5\144\1\u0139"+ + "\24\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\7\144\1\u013a\22\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\12\144\1\u013b\17\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\7\144\1\u013c\22\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\6\0\1\146\2\144"+ + "\1\u013d\10\144\1\u013e\2\144\1\u013f\13\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\16\144\1\u0140\13\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\12\144"+ + "\1\u0141\17\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\14\144\1\u0142\15\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\5\144\1\u0143\24\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\7\144\1\u0144\22\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\7\144"+ + "\1\u0145\22\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\2\144\1\u0146\27\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\22\144\1\u0147\7\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\1\144\1\u0148\30\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\2\144"+ + "\1\u0149\27\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\1\144\1\u014a\30\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\15\144\1\u014b\5\144\1\u014c\6\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\4\144\1\u014d\25\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\1\144\1\u014e\1\144"+ + "\10\0\4\144\7\0\32\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\15\144"+ + "\1\u014f\14\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\7\144\1\u0150\22\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\10\144\1\u0151\21\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\16\144\1\u0152\13\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\12\144"+ + "\1\u0153\17\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\31\144\1\u0154\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\1\144\1\u0155"+ + "\1\144\10\0\4\144\7\0\32\144\2\0\3\144\10\0"+ + "\1\144\40\0\1\264\105\0\1\u0156\103\0\1\u0157\53\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\14\144\1\u0158"+ + "\15\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\1\144\1\u0148\1\u0159\27\144"+ + "\2\0\3\144\10\0\1\144\74\0\1\u015a\15\0\3\u015b"+ + "\3\0\1\u015b\32\0\2\u015b\3\0\1\u015b\1\0\1\u015b"+ + "\1\0\1\u015b\2\0\1\u015b\1\0\4\u015b\3\0\1\u015b"+ + "\1\0\1\u015b\71\0\1\u015c\71\0\1\u015d\101\0\1\u015e"+ + "\112\0\1\u015f\122\0\1\u0160\117\0\1\u0161\14\0\13\351"+ + "\1\75\10\351\1\u0162\1\230\60\351\4\u0127\1\u0163\4\u0127"+ + "\2\351\1\75\7\u0127\1\351\2\u0127\1\351\57\u0127\4\u0164"+ + "\1\u0165\4\u0164\2\351\1\75\7\u0164\1\351\3\u0164\1\230"+ + "\56\u0164\4\0\1\u0129\1\0\1\u012a\100\0\3\u012b\3\0"+ + "\1\u012b\32\0\2\u012b\3\0\1\u012b\1\0\1\u012b\1\0"+ + "\1\u012b\2\0\1\u012b\1\0\4\u012b\3\0\1\u012b\1\0"+ + "\1\u012b\15\0\3\u0166\3\0\1\u0166\32\0\2\u0166\3\0"+ + "\1\u0166\1\0\1\u0166\1\0\1\u0166\2\0\1\u0166\1\0"+ + "\4\u0166\3\0\1\u0166\1\0\1\u0166\15\0\3\u0167\3\0"+ + "\1\u0167\32\0\2\u0167\3\0\1\u0167\1\0\1\u0167\1\0"+ + "\1\u0167\2\0\1\u0167\1\0\4\u0167\3\0\1\u0167\1\0"+ + "\1\u0167\14\0\11\253\2\124\1\125\7\253\1\124\11\253"+ + "\1\u0168\61\253\2\124\1\125\7\253\1\124\4\253\1\u0169"+ + "\4\253\1\u016a\10\253\1\u016b\50\253\2\124\1\125\7\253"+ + "\1\124\16\253\1\u016c\43\253\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\5\144\1\u016d\24\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\6\0\1\146\2\144\1\u016e\27\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\4\144\1\u016f\25\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\24\144\1\u0170"+ + "\5\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\1\144\1\u0171\1\144\10\0\4\144\7\0\32\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\7\144\1\u0172\22\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\4\144\1\u0173\25\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\1\144\1\u0174"+ + "\30\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\6\144\1\u0175\23\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\1\u0176"+ + "\7\0\2\144\1\u0177\1\144\7\0\32\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\7\144\1\u0178\22\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\1\144"+ + "\1\u0179\30\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\3\144\1\u017a\26\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\14\144\1\u017b\15\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\12\144\1\u017c\17\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\2\144"+ + "\1\u017d\27\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\12\144\1\u017e\17\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\10\144\1\u017f\21\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\1\u0180\2\144\10\0"+ + "\4\144\7\0\32\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\4\144\1\u0181"+ + "\25\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\4\144\1\u0182\25\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\23\144\1\u0183\6\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\16\144\1\u0184\13\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\7\144\1\u0185"+ + "\22\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\11\144\1\u0186\20\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\7\144\1\u0187\22\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\17\144\1\u0188\12\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\15\144\1\u0189"+ + "\14\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\12\144\1\u018a\17\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\7\144\1\u018b\22\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\16\144\1\u018c\13\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\1\u018d\31\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\24\144\1\u018e\5\144\2\0\3\144"+ + "\10\0\1\144\40\0\1\u018f\51\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\2\144\1\u0190\27\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\7\144\1\u0191\22\144\2\0\3\144\10\0\1\144"+ + "\75\0\1\u0192\55\0\1\u0193\105\0\1\u0194\100\0\1\u0195"+ + "\105\0\1\u0196\103\0\1\u0197\144\0\1\u0198\13\0\11\u0162"+ + "\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\61\u0162\11\u0127\2\351"+ + "\1\75\7\u0127\1\351\62\u0127\11\230\2\351\1\75\7\230"+ + "\1\351\3\230\1\351\56\230\3\u0164\1\u019c\1\u019d\1\u0164"+ + "\1\u019e\1\u019f\1\u0164\2\351\1\75\7\u0164\1\351\34\u0164"+ + "\1\u019c\1\u0164\1\u019f\1\u019c\22\u0164\1\0\3\u01a0\3\0"+ + "\1\u01a0\32\0\2\u01a0\3\0\1\u01a0\1\0\1\u01a0\1\0"+ + "\1\u01a0\2\0\1\u01a0\1\0\4\u01a0\3\0\1\u01a0\1\0"+ + "\1\u01a0\14\0\11\253\2\124\1\125\7\253\1\124\4\253"+ + "\1\u01a1\4\253\1\u01a2\50\253\11\u0169\2\u01a3\1\u01a4\7\u0169"+ + "\1\u01a3\62\u0169\11\253\2\124\1\125\7\253\1\124\12\253"+ + "\1\u01a5\60\253\2\124\1\125\7\253\1\124\23\253\1\u01a6"+ + "\43\253\1\u01a7\3\253\2\124\1\125\7\253\1\124\62\253"+ + "\1\0\3\144\1\0\3\144\10\0\4\144\7\0\23\144"+ + "\1\u01a8\6\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\3\144\1\u01a9\26\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\14\144\1\u01aa\15\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\7\144\1\u01ab\22\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\23\144"+ + "\1\u01ac\6\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\17\144\1\u01ad\12\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u01ae\22\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\1\u01af\31\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\15\144\1\u01b0"+ + "\14\144\2\0\3\144\10\0\1\144\5\0\1\u01b1\2\0"+ + "\2\u01b1\1\0\1\u0176\7\0\1\u01b1\1\0\1\u0176\10\0"+ + "\25\u01b1\4\0\1\u01b1\2\0\3\u01b1\10\0\1\u01b1\4\0"+ + "\1\144\1\u01b1\1\144\1\0\2\u01b1\1\144\1\u0176\7\0"+ + "\1\u01b1\1\144\1\u0177\1\144\7\0\25\u01b1\4\144\1\u01b1"+ + "\2\0\3\u01b1\10\0\1\u01b1\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\23\144\1\u01b2\6\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\4\144\1\u01b3\25\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\12\144"+ + "\1\u01b4\17\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\5\144\1\u01b5\24\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\1\u01b6\31\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\2\144\1\u01b7\27\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\14\144\1\u01b8"+ + "\15\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\1\u01b9\31\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\14\144\1\u01ba\15\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\3\144"+ + "\1\u01bb\26\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\4\144\1\u01bc\25\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\17\144\1\u01bd\12\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\20\144\1\u01be\11\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\1\144"+ + "\1\u01bf\30\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\1\u01c0\7\0\2\144\1\u01c1\1\144\7\0"+ + "\32\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\7\144\1\u01c2\22\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\4\144\1\u01c3\25\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\21\144\1\u01c4\10\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\16\144\1\u01c5"+ + "\13\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\7\144\1\u01c6\22\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\1\332"+ + "\7\0\2\144\1\333\1\144\7\0\15\144\1\u01c7\14\144"+ + "\2\0\3\144\10\0\1\144\75\0\1\u01c8\52\0\1\u01c9"+ + "\105\0\1\u01ca\110\0\1\u01cb\100\0\1\u01cc\105\0\1\u01cd"+ + "\142\0\1\u01ce\13\0\13\u0199\1\u019a\10\u0199\1\u01cf\1\u01d0"+ + "\1\u01d1\1\u01d2\1\u0162\1\u0199\1\u0162\53\u0199\24\u019a\1\u01d3"+ + "\1\u01d4\1\u01d5\1\u01d6\1\227\1\u019a\1\227\53\u019a\11\u0162"+ + "\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\1\351\60\u0162\3\230"+ + "\1\u0164\3\230\1\u0164\1\230\2\351\1\75\7\230\1\351"+ + "\3\230\1\351\30\230\1\u0164\1\230\2\u0164\26\230\1\u01d7"+ + "\1\230\1\u01d8\2\230\2\351\1\75\7\230\1\351\3\230"+ + "\1\351\57\230\3\u01d9\3\230\1\u01d9\1\230\2\351\1\75"+ + "\7\230\1\351\3\230\1\351\12\230\2\u01d9\3\230\1\u01d9"+ + "\1\230\1\u01d9\1\230\1\u01d9\2\230\1\u01d9\1\230\4\u01d9"+ + "\3\230\1\u01d9\1\230\1\u01d9\17\230\1\u019c\3\230\1\u019c"+ + "\1\230\2\351\1\75\7\230\1\351\3\230\1\351\30\230"+ + "\1\u019c\1\230\2\u019c\22\230\1\0\3\232\3\0\1\232"+ + "\32\0\2\232\3\0\1\232\1\0\1\232\1\0\1\232"+ + "\2\0\1\232\1\0\4\232\3\0\1\232\1\0\1\232"+ + "\14\0\11\u01a1\2\u01da\1\u01db\7\u01a1\1\u01da\62\u01a1\11\253"+ + "\2\124\1\125\7\253\1\124\12\253\1\u01dc\60\253\2\124"+ + "\1\125\7\253\1\124\13\253\1\u01dd\57\253\2\124\1\125"+ + "\7\253\1\124\21\253\1\u01de\51\253\2\124\1\125\7\253"+ + "\1\124\11\253\1\u01df\50\253\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u01e0\22\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\4\144\1\u01e1\25\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\22\144"+ + "\1\u01e2\7\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\4\144\1\u01e3\25\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u01e4\22\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\7\144\1\u01e5\22\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\16\144"+ + "\1\u01e6\13\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\1\u01e7\2\144\10\0\4\144\7\0\32\144\2\0"+ + "\3\144\10\0\1\144\4\0\3\144\1\0\3\144\1\u01e8"+ + "\7\0\2\144\1\u01e9\1\144\7\0\32\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\u01b1\1\0\3\u01b1\1\u01ea\3\0"+ + "\1\u0176\1\0\1\u01eb\1\0\4\u01b1\7\0\32\u01b1\2\0"+ + "\3\u01b1\10\0\1\u01b1\4\0\3\144\1\0\3\144\10\0"+ + "\4\144\7\0\15\144\1\u01ec\14\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\5\144\1\u01ed\24\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\6\0\1\146\32\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\15\144\1\u01ee\14\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\5\144\1\u01ef\24\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\3\144"+ + "\1\u01f0\26\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\16\144\1\u01f1\13\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\13\144\1\u01f2\16\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\12\144\1\u01f3\17\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\4\144"+ + "\1\u01f4\25\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\1\u01f5\7\0\2\144\1\u01f6\1\144\7\0"+ + "\32\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\1\144\1\u01f7\1\144\10\0\4\144\7\0\32\144\2\0"+ + "\3\144\10\0\1\144\5\0\1\u01f8\2\0\2\u01f8\1\0"+ + "\1\u01c0\7\0\1\u01f8\1\0\1\u01c0\10\0\25\u01f8\4\0"+ + "\1\u01f8\2\0\3\u01f8\10\0\1\u01f8\4\0\1\144\1\u01f8"+ + "\1\144\1\0\2\u01f8\1\144\1\u01c0\7\0\1\u01f8\1\144"+ + "\1\u01c1\1\144\7\0\25\u01f8\4\144\1\u01f8\2\0\3\u01f8"+ + "\10\0\1\u01f8\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\15\144\1\u01f9\14\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\1\u01fa\7\0\2\144\1\u01fb"+ + "\1\144\7\0\32\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\1\327\7\0\2\144\1\330\1\144"+ + "\7\0\15\144\1\u01fc\14\144\2\0\3\144\10\0\1\144"+ + "\13\0\4\u01c8\6\0\2\u01c8\6\0\1\u01fd\124\0\1\u01fe"+ + "\105\0\1\u01ff\73\0\1\u0200\110\0\1\u0201\147\0\1\u0202"+ + "\11\0\4\u0203\6\0\2\u0203\62\0\13\u0199\1\u019a\10\u0199"+ + "\1\u01cf\1\u0204\1\u01d1\1\u01d2\1\u0162\1\u0199\1\u0162\66\u0199"+ + "\1\u019a\10\u0199\1\u0205\1\u0162\60\u0199\4\u01d1\1\u0206\4\u01d1"+ + "\2\u0199\1\u019a\7\u01d1\1\u0199\1\u0207\1\u01d1\1\u0199\57\u01d1"+ + "\4\u0208\1\u0209\4\u0208\2\u0199\1\u019a\7\u0208\1\u0199\1\u020a"+ + "\2\u0208\1\u0162\56\u0208\24\u019a\1\u01d3\1\u020b\1\u01d5\1\u01d6"+ + "\1\227\1\u019a\1\227\77\u019a\1\u020c\1\u0162\60\u019a\4\u01d5"+ + "\1\u020d\4\u01d5\3\227\7\u01d5\1\227\1\u020e\1\u01d5\1\u019a"+ + "\57\u01d5\4\u020f\1\u0210\4\u020f\3\227\7\u020f\1\227\1\u0211"+ + "\2\u020f\1\227\56\u020f\4\230\1\u01d7\1\230\1\u01d8\2\230"+ + "\2\351\1\75\7\230\1\351\63\230\3\u01d9\3\230\1\u01d9"+ + "\1\230\2\351\1\75\7\230\1\351\16\230\2\u01d9\3\230"+ + "\1\u01d9\1\230\1\u01d9\1\230\1\u01d9\2\230\1\u01d9\1\230"+ + "\4\u01d9\3\230\1\u01d9\1\230\1\u01d9\15\230\3\u0212\3\230"+ + "\1\u0212\1\230\2\351\1\75\7\230\1\351\16\230\2\u0212"+ + "\3\230\1\u0212\1\230\1\u0212\1\230\1\u0212\2\230\1\u0212"+ + "\1\230\4\u0212\3\230\1\u0212\1\230\1\u0212\14\230\11\253"+ + "\2\124\1\125\7\253\1\124\13\253\1\u0213\57\253\2\124"+ + "\1\125\7\253\1\124\14\253\1\u0214\56\253\2\124\1\125"+ + "\7\253\1\124\4\253\1\u0215\66\253\2\124\1\125\7\253"+ + "\1\124\12\253\1\u0216\47\253\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\5\144\1\u0217\24\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\1\u0218\7\0"+ + "\2\144\1\u0218\1\144\7\0\32\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\10\0\4\144\7\0"+ + "\1\144\1\u0219\30\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\14\144\1\u021a"+ + "\15\144\2\0\3\144\10\0\1\144\3\0\2\u021b\1\u021c"+ + "\2\u021b\2\u021c\1\u021b\1\u01e8\3\0\4\u021b\1\u021c\1\u021b"+ + "\1\u01e8\1\0\7\u021b\25\u021c\4\u021b\1\u021c\2\u021b\3\u021c"+ + "\10\u021b\1\u021c\4\u021b\1\u021d\1\u021c\1\u021d\1\u021b\2\u021c"+ + "\1\u021d\1\u01e8\3\0\4\u021b\1\u021c\1\u021d\1\u01e9\1\144"+ + "\7\u021b\25\u021c\4\u021d\1\u021c\2\u021b\3\u021c\10\u021b\1\u021c"+ + "\3\u021b\10\0\1\u01ea\3\0\1\u0176\1\0\1\u01eb\3\0"+ + "\1\u01ea\73\0\1\u01eb\6\0\1\u021e\2\0\1\u01eb\64\0"+ + "\3\144\1\0\3\144\1\u021f\7\0\2\144\1\u0220\1\144"+ + "\7\0\32\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\6\144\1\u0221\23\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u0222\22\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\1\144\1\u0223\30\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\4\144"+ + "\1\u0224\25\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\2\144\1\u0225\27\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\14\144\1\u0226\15\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\5\144\1\u0227\24\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\5\144"+ + "\1\u0228\24\144\2\0\3\144\10\0\1\144\3\0\2\u0229"+ + "\1\u022a\2\u0229\2\u022a\1\u0229\1\u01f5\3\0\4\u0229\1\u022a"+ + "\1\u0229\1\u01f5\1\0\7\u0229\25\u022a\4\u0229\1\u022a\2\u0229"+ + "\3\u022a\10\u0229\1\u022a\4\u0229\1\u022b\1\u022a\1\u022b\1\u0229"+ + "\2\u022a\1\u022b\1\u01f5\3\0\4\u0229\1\u022a\1\u022b\1\u01f6"+ + "\1\144\7\u0229\25\u022a\4\u022b\1\u022a\2\u0229\3\u022a\10\u0229"+ + "\1\u022a\3\u0229\1\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\24\144\1\u022c\5\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\u01f8\1\0\3\u01f8\1\u022d\7\0\4\u01f8\7\0"+ + "\32\u01f8\2\0\3\u01f8\10\0\1\u01f8\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\15\144\1\u022e\14\144\2\0"+ + "\3\144\10\0\1\144\3\0\1\u022f\1\u0230\1\u022f\1\u0230"+ + "\3\u022f\1\u0230\1\u01fa\3\0\6\u022f\1\u01fa\1\0\34\u022f"+ + "\4\u0230\23\u022f\1\u0231\1\u0232\1\u0231\1\u022f\2\u0232\1\u0231"+ + "\1\u01fa\3\0\4\u022f\2\u0232\1\u01fb\1\144\7\u022f\25\u0232"+ + "\4\u0231\1\u0232\2\u022f\3\u0232\10\u022f\1\u0232\3\u022f\47\0"+ + "\1\u0233\105\0\1\u0234\142\0\1\u0235\40\0\1\u0236\65\0"+ + "\1\u0237\76\0\4\u0203\6\0\2\u0203\6\0\1\u0238\53\0"+ + "\13\351\1\75\10\351\1\u0199\1\u0126\1\u0239\1\u023a\56\351"+ + "\11\u0162\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\1\u0199\60\u0162"+ + "\11\u01d1\2\u0199\1\u019a\7\u01d1\1\u0199\1\u0207\65\u01d1\1\u0206"+ + "\4\u01d1\2\u0199\1\u019a\7\u01d1\1\u0199\1\u0207\1\u0239\1\u0199"+ + "\57\u01d1\11\u0162\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\2\u0162"+ + "\1\u0199\56\u0162\3\u0208\1\u023b\1\u023c\1\u0208\1\u023d\1\u023e"+ + "\1\u0208\2\u0199\1\u019a\7\u0208\1\u0199\1\u020a\33\u0208\1\u023b"+ + "\1\u0208\1\u023e\1\u023b\22\u0208\11\u0162\2\u0199\1\u019a\7\u0162"+ + "\1\u0199\1\u019b\1\351\1\u0162\1\u0199\56\u0162\24\75\1\u019a"+ + "\1\u0126\1\u023f\1\u0240\56\75\24\227\1\350\1\u019a\60\227"+ + "\11\u01d5\3\227\7\u01d5\1\227\1\u020e\65\u01d5\1\u020d\4\u01d5"+ + "\3\227\7\u01d5\1\227\1\u020e\1\u023f\1\u019a\57\u01d5\24\227"+ + "\1\350\2\227\1\u019a\56\227\3\u020f\1\u0241\1\u0242\1\u020f"+ + "\1\u0243\1\u0244\1\u020f\3\227\7\u020f\1\227\1\u0211\33\u020f"+ + "\1\u0241\1\u020f\1\u0244\1\u0241\22\u020f\24\227\1\350\1\75"+ + "\1\227\1\u019a\56\227\1\230\3\u0245\3\230\1\u0245\1\230"+ + "\2\351\1\75\7\230\1\351\16\230\2\u0245\3\230\1\u0245"+ + "\1\230\1\u0245\1\230\1\u0245\2\230\1\u0245\1\230\4\u0245"+ + "\3\230\1\u0245\1\230\1\u0245\14\230\11\253\2\124\1\125"+ + "\7\253\1\124\14\253\1\u0246\56\253\2\124\1\125\7\253"+ + "\1\124\15\253\1\u0247\44\253\11\u0215\2\u0248\1\u0249\7\u0215"+ + "\1\u0248\62\u0215\11\253\2\124\1\125\7\253\1\124\13\253"+ + "\1\u024a\46\253\1\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\6\144\1\u024b\23\144\2\0\3\144\10\0\1\144"+ + "\3\0\13\u0218\1\0\72\u0218\1\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\2\144\1\u024c\27\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\15\144\1\u024d\14\144\2\0\3\144\10\0\1\144"+ + "\3\0\11\u021b\3\0\7\u021b\1\0\63\u021b\3\u021c\1\u021b"+ + "\3\u021c\1\u024e\3\0\2\u01e8\2\u021b\3\u021c\1\u024f\7\u021b"+ + "\32\u021c\2\u021b\3\u021c\10\u021b\1\u021c\4\u021b\3\u021d\1\u021b"+ + "\3\u021d\1\u021b\3\0\4\u021b\3\u021d\1\144\7\u021b\32\u021d"+ + "\2\u021b\3\u021d\10\u021b\1\u021d\3\u021b\10\0\1\u021e\5\0"+ + "\1\u01eb\3\0\1\u021e\65\0\1\u0250\2\0\2\u0250\1\0"+ + "\1\u021f\7\0\1\u0250\1\0\1\u021f\10\0\25\u0250\4\0"+ + "\1\u0250\2\0\3\u0250\10\0\1\u0250\4\0\1\144\1\u0250"+ + "\1\144\1\0\2\u0250\1\144\1\u021f\7\0\1\u0250\1\144"+ + "\1\u0220\1\144\7\0\25\u0250\4\144\1\u0250\2\0\3\u0250"+ + "\10\0\1\u0250\4\0\3\144\1\0\3\144\1\u0251\7\0"+ + "\2\144\1\u0252\1\144\6\0\1\146\32\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\1\u0253\7\0"+ + "\2\144\1\u0254\1\144\7\0\32\144\2\0\3\144\10\0"+ + "\1\144\4\0\3\144\1\0\3\144\1\u0255\7\0\2\144"+ + "\1\u0256\1\144\7\0\32\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\5\144"+ + "\1\u0257\24\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\2\144\1\u0258\27\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\1\144\1\u0259\30\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\4\144\1\u025a\25\144\2\0\3\144\10\0\1\144"+ + "\3\0\11\u0229\3\0\7\u0229\1\0\63\u0229\3\u022a\1\u0229"+ + "\3\u022a\1\u025b\3\0\1\u01f5\3\u0229\3\u022a\1\u025c\7\u0229"+ + "\32\u022a\2\u0229\3\u022a\10\u0229\1\u022a\4\u0229\3\u022b\1\u0229"+ + "\3\u022b\1\u0229\3\0\4\u0229\3\u022b\1\144\7\u0229\32\u022b"+ + "\2\u0229\3\u022b\10\u0229\1\u022b\3\u0229\10\0\1\u022d\11\0"+ + "\1\u022d\63\0\11\u022f\3\0\7\u022f\1\0\63\u022f\1\u0230"+ + "\1\u022f\1\u0230\3\u022f\1\u0230\1\u025d\3\0\6\u022f\1\u025d"+ + "\1\0\34\u022f\4\u0230\23\u022f\1\u0231\1\u0232\1\u0231\1\u022f"+ + "\2\u0232\1\u0231\1\u025d\3\0\4\u022f\2\u0232\1\u025e\1\144"+ + "\7\u022f\25\u0232\4\u0231\1\u0232\2\u022f\3\u0232\10\u022f\1\u0232"+ + "\4\u022f\3\u0232\1\u022f\3\u0232\1\u022f\3\0\4\u022f\3\u0232"+ + "\1\144\7\u022f\32\u0232\2\u022f\3\u0232\10\u022f\1\u0232\3\u022f"+ + "\50\0\1\u025f\105\0\1\u0260\54\0\1\u0261\144\0\1\u0262"+ + "\25\0\1\u0263\1\0\4\u0239\1\u0264\4\u0239\2\351\1\75"+ + "\7\u0239\1\351\1\u0239\1\u0265\1\u0239\1\u0266\1\u0127\1\u0239"+ + "\1\u0127\53\u0239\4\u0267\1\u0268\4\u0267\2\351\1\75\7\u0267"+ + "\1\351\1\u0267\1\u0126\1\u0269\1\u0128\1\u0164\1\u0267\1\u0164"+ + "\53\u0267\3\u0162\1\u0208\3\u0162\1\u0208\1\u0162\2\u0199\1\u019a"+ + "\7\u0162\1\u0199\1\u019b\2\u0162\1\u0199\30\u0162\1\u0208\1\u0162"+ + "\2\u0208\26\u0162\1\u026a\1\u0162\1\u026b\2\u0162\2\u0199\1\u019a"+ + "\7\u0162\1\u0199\1\u019b\2\u0162\1\u0199\57\u0162\3\u026c\3\u0162"+ + "\1\u026c\1\u0162\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\2\u0162"+ + "\1\u0199\12\u0162\2\u026c\3\u0162\1\u026c\1\u0162\1\u026c\1\u0162"+ + "\1\u026c\2\u0162\1\u026c\1\u0162\4\u026c\3\u0162\1\u026c\1\u0162"+ + "\1\u026c\17\u0162\1\u023b\3\u0162\1\u023b\1\u0162\2\u0199\1\u019a"+ + "\7\u0162\1\u0199\1\u019b\2\u0162\1\u0199\30\u0162\1\u023b\1\u0162"+ + "\2\u023b\22\u0162\4\u023f\1\u026d\4\u023f\3\75\7\u023f\1\75"+ + "\1\u023f\1\u026e\1\u023f\1\u026f\1\225\1\u023f\1\225\53\u023f"+ + "\4\u0270\1\u0271\4\u0270\3\75\7\u0270\1\75\1\u0270\1\224"+ + "\1\u0272\1\226\1\232\1\u0270\1\232\53\u0270\3\227\1\u020f"+ + "\3\227\1\u020f\14\227\1\350\2\227\1\u019a\30\227\1\u020f"+ + "\1\227\2\u020f\26\227\1\u0273\1\227\1\u0274\15\227\1\350"+ + "\2\227\1\u019a\57\227\3\u0275\3\227\1\u0275\14\227\1\350"+ + "\2\227\1\u019a\12\227\2\u0275\3\227\1\u0275\1\227\1\u0275"+ + "\1\227\1\u0275\2\227\1\u0275\1\227\4\u0275\3\227\1\u0275"+ + "\1\227\1\u0275\17\227\1\u0241\3\227\1\u0241\14\227\1\350"+ + "\2\227\1\u019a\30\227\1\u0241\1\227\2\u0241\22\227\1\230"+ + "\3\u0164\3\230\1\u0164\1\230\2\351\1\75\7\230\1\351"+ + "\16\230\2\u0164\3\230\1\u0164\1\230\1\u0164\1\230\1\u0164"+ + "\2\230\1\u0164\1\230\4\u0164\3\230\1\u0164\1\230\1\u0164"+ + "\14\230\11\253\2\124\1\125\7\253\1\124\15\253\1\u0276"+ + "\55\253\2\124\1\125\7\253\1\124\4\253\1\u0277\66\253"+ + "\2\124\1\125\7\253\1\124\14\253\1\u0278\45\253\1\0"+ + "\3\144\1\0\3\144\1\u0279\7\0\2\144\1\u027a\1\144"+ + "\6\0\1\146\32\144\2\0\3\144\10\0\1\144\4\0"+ + "\3\144\1\0\3\144\10\0\4\144\7\0\15\144\1\u027b"+ + "\14\144\2\0\3\144\10\0\1\144\4\0\3\144\1\0"+ + "\3\144\10\0\4\144\7\0\7\144\1\u022e\22\144\2\0"+ + "\3\144\10\0\1\144\3\0\10\u021b\1\u024e\3\0\2\u01e8"+ + "\4\u021b\1\u024e\1\0\62\u021b\1\0\3\u024f\1\0\3\u024f"+ + "\1\u027c\3\0\2\u027d\2\0\4\u024f\7\0\32\u024f\2\0"+ + "\3\u024f\10\0\1\u024f\4\0\3\u0250\1\0\3\u0250\1\u027e"+ + "\3\0\1\u021f\3\0\4\u0250\7\0\32\u0250\2\0\3\u0250"+ + "\10\0\1\u0250\3\0\2\u027f\1\u0280\2\u027f\2\u0280\1\u027f"+ + "\1\u0251\3\0\4\u027f\1\u0280\1\u027f\1\u0251\1\0\7\u027f"+ + "\25\u0280\4\u027f\1\u0280\2\u027f\3\u0280\10\u027f\1\u0280\4\u027f"+ + "\1\u0281\1\u0280\1\u0281\1\u027f\2\u0280\1\u0281\1\u0251\3\0"+ + "\4\u027f\1\u0280\1\u0281\1\u0252\1\144\7\u027f\25\u0280\4\u0281"+ + "\1\u0280\2\u027f\3\u0280\10\u027f\1\u0280\3\u027f\10\0\1\u0253"+ + "\11\0\1\u0253\12\0\1\u0282\5\0\1\u0283\43\0\3\144"+ + "\1\0\3\144\1\u0253\7\0\2\144\1\u0254\1\144\7\0"+ + "\2\144\1\u0284\5\144\1\u0285\21\144\2\0\3\144\10\0"+ + "\1\144\5\0\1\u0286\2\0\2\u0286\1\0\1\u0255\7\0"+ + "\1\u0286\1\0\1\u0255\10\0\25\u0286\4\0\1\u0286\2\0"+ + "\3\u0286\10\0\1\u0286\4\0\1\144\1\u0286\1\144\1\0"+ + "\2\u0286\1\144\1\u0255\7\0\1\u0286\1\144\1\u0256\1\144"+ + "\7\0\25\u0286\4\144\1\u0286\2\0\3\u0286\10\0\1\u0286"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\6\144"+ + "\1\u0287\23\144\2\0\3\144\10\0\1\144\4\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\7\144\1\u0288\22\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\7\144\1\u0289\22\144\2\0\3\144"+ + "\10\0\1\144\4\0\3\144\1\0\3\144\1\u028a\7\0"+ + "\2\144\1\u028b\1\144\7\0\32\144\2\0\3\144\10\0"+ + "\1\144\3\0\10\u0229\1\u025b\3\0\1\u01f5\5\u0229\1\u025b"+ + "\1\0\62\u0229\1\0\3\u025c\1\0\3\u025c\1\u028c\3\0"+ + "\1\u028d\3\0\4\u025c\7\0\32\u025c\2\0\3\u025c\10\0"+ + "\1\u025c\3\0\10\u022f\1\u025d\3\0\6\u022f\1\u025d\1\0"+ + "\63\u022f\3\u0232\1\u022f\3\u0232\1\u025d\3\0\4\u022f\2\u0232"+ + "\1\u025e\1\144\7\u022f\32\u0232\2\u022f\3\u0232\10\u022f\1\u0232"+ + "\3\u022f\42\0\1\u028e\105\0\1\u028f\76\0\1\u0290\71\0"+ + "\1\u0291\66\0\11\u0239\2\351\1\75\7\u0239\1\351\1\u0239"+ + "\1\u0265\1\u0127\1\u0266\1\u0127\1\u0239\1\u0127\57\u0239\1\u0264"+ + "\4\u0239\2\351\1\75\7\u0239\1\351\1\u01d1\1\u0127\1\351"+ + "\57\u0239\4\u0269\1\u0292\4\u0269\2\351\1\75\7\u0269\1\351"+ + "\2\u0269\1\u0267\1\u0127\56\u0269\13\351\1\75\11\351\1\u0126"+ + "\1\u0127\1\u023a\1\230\1\351\1\230\53\351\3\u0267\1\u0293"+ + "\1\u0294\1\u0267\1\u0295\1\u0296\1\u0267\2\351\1\75\7\u0267"+ + "\1\351\1\u0267\1\u0126\1\u0269\1\u0297\1\u0164\1\u0267\1\u0164"+ + "\25\u0267\1\u0293\1\u0267\1\u0296\1\u0293\22\u0267\4\u0127\1\u0163"+ + "\4\u0127\2\351\1\75\7\u0127\1\351\2\u0127\1\351\1\u0239"+ + "\56\u0127\4\u0162\1\u026a\1\u0162\1\u026b\2\u0162\2\u0199\1\u019a"+ + "\7\u0162\1\u0199\1\u019b\62\u0162\3\u026c\3\u0162\1\u026c\1\u0162"+ + "\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\15\u0162\2\u026c\3\u0162"+ + "\1\u026c\1\u0162\1\u026c\1\u0162\1\u026c\2\u0162\1\u026c\1\u0162"+ + "\4\u026c\3\u0162\1\u026c\1\u0162\1\u026c\15\u0162\3\u0298\3\u0162"+ + "\1\u0298\1\u0162\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b\15\u0162"+ + "\2\u0298\3\u0162\1\u0298\1\u0162\1\u0298\1\u0162\1\u0298\2\u0162"+ + "\1\u0298\1\u0162\4\u0298\3\u0162\1\u0298\1\u0162\1\u0298\14\u0162"+ + "\11\u023f\3\75\7\u023f\1\75\1\u023f\1\u026e\1\225\1\u026f"+ + "\1\225\1\u023f\1\225\57\u023f\1\u026d\4\u023f\3\75\7\u023f"+ + "\1\75\1\u01d5\1\u0127\1\75\57\u023f\4\u0272\1\u0299\4\u0272"+ + "\3\0\7\u0272\1\0\2\u0272\1\u0270\1\225\56\u0272\25\75"+ + "\1\224\1\225\1\u0240\1\0\1\75\1\0\53\75\3\u0270"+ + "\1\u029a\1\u029b\1\u0270\1\u029c\1\u029d\1\u0270\3\75\7\u0270"+ + "\1\75\1\u0270\1\224\1\u0272\1\u029e\1\232\1\u0270\1\232"+ + "\25\u0270\1\u029a\1\u0270\1\u029d\1\u029a\22\u0270\4\225\1\231"+ + "\4\225\3\0\7\225\1\0\2\225\1\75\1\u023f\56\225"+ + "\4\227\1\u0273\1\227\1\u0274\15\227\1\350\62\227\3\u0275"+ + "\3\227\1\u0275\14\227\1\350\15\227\2\u0275\3\227\1\u0275"+ + "\1\227\1\u0275\1\227\1\u0275\2\227\1\u0275\1\227\4\u0275"+ + "\3\227\1\u0275\1\227\1\u0275\15\227\3\u029f\3\227\1\u029f"+ + "\14\227\1\350\15\227\2\u029f\3\227\1\u029f\1\227\1\u029f"+ + "\1\227\1\u029f\2\227\1\u029f\1\227\4\u029f\3\227\1\u029f"+ + "\1\227\1\u029f\14\227\11\253\2\124\1\125\7\253\1\124"+ + "\4\253\1\u02a0\55\253\11\u0277\2\u02a1\1\u02a2\7\u0277\1\u02a1"+ + "\62\u0277\11\253\2\124\1\125\7\253\1\124\15\253\1\u02a3"+ + "\44\253\2\u02a4\1\u02a5\2\u02a4\2\u02a5\1\u02a4\1\u0279\3\0"+ + "\4\u02a4\1\u02a5\1\u02a4\1\u0279\1\0\7\u02a4\25\u02a5\4\u02a4"+ + "\1\u02a5\2\u02a4\3\u02a5\10\u02a4\1\u02a5\4\u02a4\1\u02a6\1\u02a5"+ + "\1\u02a6\1\u02a4\2\u02a5\1\u02a6\1\u0279\3\0\4\u02a4\1\u02a5"+ + "\1\u02a6\1\u027a\1\144\7\u02a4\25\u02a5\4\u02a6\1\u02a5\2\u02a4"+ + "\3\u02a5\10\u02a4\1\u02a5\3\u02a4\1\0\3\144\1\0\3\144"+ + "\1\u02a7\7\0\2\144\1\u02a7\1\144\7\0\32\144\2\0"+ + "\3\144\10\0\1\144\13\0\1\u027c\3\0\2\u027d\4\0"+ + "\1\u027c\65\0\1\u024f\2\0\2\u024f\1\0\1\u027d\7\0"+ + "\1\u024f\1\0\1\u027d\10\0\25\u024f\4\0\1\u024f\2\0"+ + "\3\u024f\10\0\1\u024f\13\0\1\u027e\3\0\1\u021f\5\0"+ + "\1\u027e\63\0\11\u027f\3\0\7\u027f\1\0\63\u027f\3\u0280"+ + "\1\u027f\3\u0280\1\u02a8\3\0\2\u0251\2\u027f\3\u0280\1\u02a9"+ + "\7\u027f\32\u0280\2\u027f\3\u0280\10\u027f\1\u0280\4\u027f\3\u0281"+ + "\1\u027f\3\u0281\1\u027f\3\0\4\u027f\3\u0281\1\144\7\u027f"+ + "\32\u0281\2\u027f\3\u0281\10\u027f\1\u0281\3\u027f\37\0\1\u02aa"+ + "\115\0\1\u02ab\37\0\3\144\1\0\3\144\10\0\4\144"+ + "\7\0\4\144\1\u02ac\25\144\2\0\3\144\10\0\1\144"+ + "\4\0\3\144\1\0\3\144\10\0\4\144\7\0\14\144"+ + "\1\u02ad\15\144\2\0\3\144\10\0\1\144\4\0\3\u0286"+ + "\1\0\3\u0286\1\u02ae\7\0\4\u0286\7\0\32\u0286\2\0"+ + "\3\u0286\10\0\1\u0286\4\0\3\144\1\0\3\144\1\u02af"+ + "\7\0\2\144\1\u02b0\1\144\6\0\1\146\32\144\2\0"+ + "\3\144\10\0\1\144\3\0\2\u02b1\1\u02b2\2\u02b1\2\u02b2"+ + "\1\u02b1\1\u028a\3\0\4\u02b1\1\u02b2\1\u02b1\1\u028a\1\0"+ + "\7\u02b1\25\u02b2\4\u02b1\1\u02b2\2\u02b1\3\u02b2\10\u02b1\1\u02b2"+ + "\4\u02b1\1\u02b3\1\u02b2\1\u02b3\1\u02b1\2\u02b2\1\u02b3\1\u028a"+ + "\3\0\4\u02b1\1\u02b2\1\u02b3\1\u028b\1\144\7\u02b1\25\u02b2"+ + "\4\u02b3\1\u02b2\2\u02b1\3\u02b2\10\u02b1\1\u02b2\3\u02b1\10\0"+ + "\1\u028c\3\0\1\u028d\5\0\1\u028c\65\0\1\u025c\2\0"+ + "\2\u025c\1\0\1\u028d\7\0\1\u025c\1\0\1\u028d\10\0"+ + "\25\u025c\4\0\1\u025c\2\0\3\u025c\10\0\1\u025c\107\0"+ + "\1\u02b4\105\0\1\u02b5\60\0\1\u02b6\26\0\3\u0269\1\u02b7"+ + "\1\u02b8\1\u0269\1\u02b9\1\u02ba\1\u0269\2\351\1\75\7\u0269"+ + "\1\351\34\u0269\1\u02b7\1\u0269\1\u02ba\1\u02b7\22\u0269\3\351"+ + "\1\u0267\3\351\1\u0267\3\351\1\75\11\351\1\u0126\1\u0127"+ + "\1\u023a\1\230\1\351\1\230\25\351\1\u0267\1\351\2\u0267"+ + "\26\351\1\u02bb\1\351\1\u02bc\4\351\1\75\11\351\1\u0126"+ + "\1\u0127\1\u023a\1\230\1\351\1\230\54\351\3\u02bd\3\351"+ + "\1\u02bd\3\351\1\75\11\351\1\u0126\1\u0127\1\u023a\1\230"+ + "\1\351\1\230\7\351\2\u02bd\3\351\1\u02bd\1\351\1\u02bd"+ + "\1\351\1\u02bd\2\351\1\u02bd\1\351\4\u02bd\3\351\1\u02bd"+ + "\1\351\1\u02bd\17\351\1\u0293\3\351\1\u0293\3\351\1\75"+ + "\11\351\1\u0126\1\u0127\1\u023a\1\230\1\351\1\230\25\351"+ + "\1\u0293\1\351\2\u0293\22\351\4\u0164\1\u0165\4\u0164\2\351"+ + "\1\75\7\u0164\1\351\3\u0164\1\351\56\u0164\1\u0162\3\u02be"+ + "\3\u0162\1\u02be\1\u0162\2\u0199\1\u019a\7\u0162\1\u0199\1\u019b"+ + "\15\u0162\2\u02be\3\u0162\1\u02be\1\u0162\1\u02be\1\u0162\1\u02be"+ + "\2\u0162\1\u02be\1\u0162\4\u02be\3\u0162\1\u02be\1\u0162\1\u02be"+ + "\14\u0162\3\u0272\1\u02bf\1\u02c0\1\u0272\1\u02c1\1\u02c2\1\u0272"+ + "\3\0\7\u0272\1\0\34\u0272\1\u02bf\1\u0272\1\u02c2\1\u02bf"+ + "\22\u0272\3\75\1\u0270\3\75\1\u0270\15\75\1\224\1\225"+ + "\1\u0240\1\0\1\75\1\0\25\75\1\u0270\1\75\2\u0270"+ + "\26\75\1\u02c3\1\75\1\u02c4\16\75\1\224\1\225\1\u0240"+ + "\1\0\1\75\1\0\54\75\3\u02c5\3\75\1\u02c5\15\75"+ + "\1\224\1\225\1\u0240\1\0\1\75\1\0\7\75\2\u02c5"+ + "\3\75\1\u02c5\1\75\1\u02c5\1\75\1\u02c5\2\75\1\u02c5"+ + "\1\75\4\u02c5\3\75\1\u02c5\1\75\1\u02c5\17\75\1\u029a"+ + "\3\75\1\u029a\15\75\1\224\1\225\1\u0240\1\0\1\75"+ + "\1\0\25\75\1\u029a\1\75\2\u029a\22\75\4\232\1\233"+ + "\4\232\3\0\7\232\1\0\3\232\1\75\56\232\1\227"+ + "\3\u02c6\3\227\1\u02c6\14\227\1\350\15\227\2\u02c6\3\227"+ + "\1\u02c6\1\227\1\u02c6\1\227\1\u02c6\2\227\1\u02c6\1\227"+ + "\4\u02c6\3\227\1\u02c6\1\227\1\u02c6\14\227\11\u02a0\2\u02c7"+ + "\1\u02c8\7\u02a0\1\u02c7\62\u02a0\11\253\2\124\1\125\7\253"+ + "\1\124\4\253\1\u02c9\55\253\11\u02a4\3\0\7\u02a4\1\0"+ + "\63\u02a4\3\u02a5\1\u02a4\3\u02a5\1\u02ca\3\0\2\u0279\2\u02a4"+ + "\3\u02a5\1\u02cb\7\u02a4\32\u02a5\2\u02a4\3\u02a5\10\u02a4\1\u02a5"+ + "\4\u02a4\3\u02a6\1\u02a4\3\u02a6\1\u02a4\3\0\4\u02a4\3\u02a6"+ + "\1\144\7\u02a4\32\u02a6\2\u02a4\3\u02a6\10\u02a4\1\u02a6\3\u02a4"+ + "\13\u02a7\1\0\72\u02a7\10\u027f\1\u02a8\3\0\2\u0251\4\u027f"+ + "\1\u02a8\1\0\62\u027f\1\0\3\u02a9\1\0\3\u02a9\1\u02cc"+ + "\3\0\2\u02cd\2\0\4\u02a9\7\0\32\u02a9\2\0\3\u02a9"+ + "\10\0\1\u02a9\11\0\1\u02ce\144\0\1\u02cf\41\0\3\144"+ + "\1\0\1\144\1\u02d0\1\144\10\0\4\144\7\0\32\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\12\144\1\u02d1\17\144\2\0\3\144"+ + "\10\0\1\144\13\0\1\u02ae\11\0\1\u02ae\63\0\2\u02d2"+ + "\1\u02d3\2\u02d2\2\u02d3\1\u02d2\1\u02af\3\0\4\u02d2\1\u02d3"+ + "\1\u02d2\1\u02af\1\0\7\u02d2\25\u02d3\4\u02d2\1\u02d3\2\u02d2"+ + "\3\u02d3\10\u02d2\1\u02d3\4\u02d2\1\u02d4\1\u02d3\1\u02d4\1\u02d2"+ + "\2\u02d3\1\u02d4\1\u02af\3\0\4\u02d2\1\u02d3\1\u02d4\1\u02b0"+ + "\1\144\7\u02d2\25\u02d3\4\u02d4\1\u02d3\2\u02d2\3\u02d3\10\u02d2"+ + "\1\u02d3\3\u02d2\11\u02b1\3\0\7\u02b1\1\0\63\u02b1\3\u02b2"+ + "\1\u02b1\3\u02b2\1\u02d5\3\0\1\u028a\3\u02b1\3\u02b2\1\u02d6"+ + "\7\u02b1\32\u02b2\2\u02b1\3\u02b2\10\u02b1\1\u02b2\4\u02b1\3\u02b3"+ + "\1\u02b1\3\u02b3\1\u02b1\3\0\4\u02b1\3\u02b3\1\144\7\u02b1"+ + "\32\u02b3\2\u02b1\3\u02b3\10\u02b1\1\u02b3\3\u02b1\17\0\1\u02d7"+ + "\105\0\1\u02d8\121\0\1\u02d9\52\0\3\u0127\1\u0269\1\u0163"+ + "\2\u0127\1\u0269\1\u0127\2\351\1\75\7\u0127\1\351\2\u0127"+ + "\1\351\1\u0239\30\u0127\1\u0269\1\u0127\2\u0269\26\u0127\1\u02da"+ + "\1\u0127\1\u02db\2\u0127\2\351\1\75\7\u0127\1\351\2\u0127"+ + "\1\351\1\u0239\57\u0127\3\u02dc\1\u0163\2\u0127\1\u02dc\1\u0127"+ + "\2\351\1\75\7\u0127\1\351\2\u0127\1\351\1\u0239\12\u0127"+ + "\2\u02dc\3\u0127\1\u02dc\1\u0127\1\u02dc\1\u0127\1\u02dc\2\u0127"+ + "\1\u02dc\1\u0127\4\u02dc\3\u0127\1\u02dc\1\u0127\1\u02dc\17\u0127"+ + "\1\u02b7\1\u0163\2\u0127\1\u02b7\1\u0127\2\351\1\75\7\u0127"+ + "\1\351\2\u0127\1\351\1\u0239\30\u0127\1\u02b7\1\u0127\2\u02b7"+ + "\22\u0127\4\351\1\u02bb\1\351\1\u02bc\4\351\1\75\11\351"+ + "\1\u0126\1\u0127\1\u0128\1\230\1\351\1\230\54\351\3\u02bd"+ + "\3\351\1\u02bd\3\351\1\75\11\351\1\u0126\1\u0127\1\u0128"+ + "\1\230\1\351\1\230\7\351\2\u02bd\3\351\1\u02bd\1\351"+ + "\1\u02bd\1\351\1\u02bd\2\351\1\u02bd\1\351\4\u02bd\3\351"+ + "\1\u02bd\1\351\1\u02bd\15\351\3\u02dd\3\351\1\u02dd\3\351"+ + "\1\75\11\351\1\u0126\1\u0127\1\u0128\1\230\1\351\1\230"+ + "\7\351\2\u02dd\3\351\1\u02dd\1\351\1\u02dd\1\351\1\u02dd"+ + "\2\351\1\u02dd\1\351\4\u02dd\3\351\1\u02dd\1\351\1\u02dd"+ + "\14\351\1\u0162\3\u0208\3\u0162\1\u0208\1\u0162\2\u0199\1\u019a"+ + "\7\u0162\1\u0199\1\u019b\15\u0162\2\u0208\3\u0162\1\u0208\1\u0162"+ + "\1\u0208\1\u0162\1\u0208\2\u0162\1\u0208\1\u0162\4\u0208\3\u0162"+ + "\1\u0208\1\u0162\1\u0208\14\u0162\3\225\1\u0272\1\231\2\225"+ + "\1\u0272\1\225\3\0\7\225\1\0\2\225\1\75\1\u023f"+ + "\30\225\1\u0272\1\225\2\u0272\26\225\1\u02de\1\225\1\u02df"+ + "\2\225\3\0\7\225\1\0\2\225\1\75\1\u023f\57\225"+ + "\3\u02e0\1\231\2\225\1\u02e0\1\225\3\0\7\225\1\0"+ + "\2\225\1\75\1\u023f\12\225\2\u02e0\3\225\1\u02e0\1\225"+ + "\1\u02e0\1\225\1\u02e0\2\225\1\u02e0\1\225\4\u02e0\3\225"+ + "\1\u02e0\1\225\1\u02e0\17\225\1\u02bf\1\231\2\225\1\u02bf"+ + "\1\225\3\0\7\225\1\0\2\225\1\75\1\u023f\30\225"+ + "\1\u02bf\1\225\2\u02bf\22\225\4\75\1\u02c3\1\75\1\u02c4"+ + "\16\75\1\224\1\225\1\226\1\0\1\75\1\0\54\75"+ + "\3\u02c5\3\75\1\u02c5\15\75\1\224\1\225\1\226\1\0"+ + "\1\75\1\0\7\75\2\u02c5\3\75\1\u02c5\1\75\1\u02c5"+ + "\1\75\1\u02c5\2\75\1\u02c5\1\75\4\u02c5\3\75\1\u02c5"+ + "\1\75\1\u02c5\15\75\3\u02e1\3\75\1\u02e1\15\75\1\224"+ + "\1\225\1\226\1\0\1\75\1\0\7\75\2\u02e1\3\75"+ + "\1\u02e1\1\75\1\u02e1\1\75\1\u02e1\2\75\1\u02e1\1\75"+ + "\4\u02e1\3\75\1\u02e1\1\75\1\u02e1\14\75\1\227\3\u020f"+ + "\3\227\1\u020f\14\227\1\350\15\227\2\u020f\3\227\1\u020f"+ + "\1\227\1\u020f\1\227\1\u020f\2\227\1\u020f\1\227\4\u020f"+ + "\3\227\1\u020f\1\227\1\u020f\14\227\11\u02c9\2\u02e2\1\u02e3"+ + "\7\u02c9\1\u02e2\62\u02c9\10\u02a4\1\u02ca\3\0\2\u0279\4\u02a4"+ + "\1\u02ca\1\0\62\u02a4\1\0\3\u02cb\1\0\3\u02cb\1\u02e4"+ + "\3\0\2\u02e5\2\0\4\u02cb\7\0\32\u02cb\2\0\3\u02cb"+ + "\10\0\1\u02cb\13\0\1\u02cc\3\0\2\u02cd\4\0\1\u02cc"+ + "\65\0\1\u02a9\2\0\2\u02a9\1\0\1\u02cd\7\0\1\u02a9"+ + "\1\0\1\u02cd\10\0\25\u02a9\4\0\1\u02a9\2\0\3\u02a9"+ + "\10\0\1\u02a9\45\0\1\u02e6\113\0\1\u02e7\36\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\7\144\1\u02e8\22\144"+ + "\2\0\3\144\10\0\1\144\4\0\3\144\1\0\3\144"+ + "\10\0\4\144\7\0\15\144\1\u02e9\14\144\2\0\3\144"+ + "\10\0\1\144\3\0\11\u02d2\3\0\7\u02d2\1\0\63\u02d2"+ + "\3\u02d3\1\u02d2\3\u02d3\1\u02ea\3\0\2\u02af\2\u02d2\3\u02d3"+ + "\1\u02eb\7\u02d2\32\u02d3\2\u02d2\3\u02d3\10\u02d2\1\u02d3\4\u02d2"+ + "\3\u02d4\1\u02d2\3\u02d4\1\u02d2\3\0\4\u02d2\3\u02d4\1\144"+ + "\7\u02d2\32\u02d4\2\u02d2\3\u02d4\10\u02d2\1\u02d4\3\u02d2\10\u02b1"+ + "\1\u02d5\3\0\1\u028a\5\u02b1\1\u02d5\1\0\62\u02b1\1\0"+ + "\3\u02d6\1\0\3\u02d6\1\u02ec\3\0\1\u02ed\3\0\4\u02d6"+ + "\7\0\32\u02d6\2\0\3\u02d6\10\0\1\u02d6\40\0\1\u02ee"+ + "\50\0\4\u0127\1\u02ef\1\u0127\1\u02db\2\u0127\2\351\1\75"+ + "\7\u0127\1\351\63\u0127\3\u02dc\1\u0163\2\u0127\1\u02dc\1\u0127"+ + "\2\351\1\75\7\u0127\1\351\2\u0127\1\351\13\u0127\2\u02dc"+ + "\3\u0127\1\u02dc\1\u0127\1\u02dc\1\u0127\1\u02dc\2\u0127\1\u02dc"+ + "\1\u0127\4\u02dc\3\u0127\1\u02dc\1\u0127\1\u02dc\15\u0127\3\u02f0"+ + "\1\u0163\2\u0127\1\u02f0\1\u0127\2\351\1\75\7\u0127\1\351"+ + "\2\u0127\1\351\13\u0127\2\u02f0\3\u0127\1\u02f0\1\u0127\1\u02f0"+ + "\1\u0127\1\u02f0\2\u0127\1\u02f0\1\u0127\4\u02f0\3\u0127\1\u02f0"+ + "\1\u0127\1\u02f0\14\u0127\1\351\3\u02f1\3\351\1\u02f1\3\351"+ + "\1\75\11\351\1\u0126\1\u0127\1\u0128\1\230\1\351\1\230"+ + "\7\351\2\u02f1\3\351\1\u02f1\1\351\1\u02f1\1\351\1\u02f1"+ + "\2\351\1\u02f1\1\351\4\u02f1\3\351\1\u02f1\1\351\1\u02f1"+ + "\14\351\4\225\1\u02f2\1\225\1\u02df\2\225\3\0\7\225"+ + "\1\0\63\225\3\u02e0\1\231\2\225\1\u02e0\1\225\3\0"+ + "\7\225\1\0\2\225\1\75\13\225\2\u02e0\3\225\1\u02e0"+ + "\1\225\1\u02e0\1\225\1\u02e0\2\225\1\u02e0\1\225\4\u02e0"+ + "\3\225\1\u02e0\1\225\1\u02e0\15\225\3\u02f3\1\231\2\225"+ + "\1\u02f3\1\225\3\0\7\225\1\0\2\225\1\75\13\225"+ + "\2\u02f3\3\225\1\u02f3\1\225\1\u02f3\1\225\1\u02f3\2\225"+ + "\1\u02f3\1\225\4\u02f3\3\225\1\u02f3\1\225\1\u02f3\14\225"+ + "\1\75\3\u02f4\3\75\1\u02f4\15\75\1\224\1\225\1\226"+ + "\1\0\1\75\1\0\7\75\2\u02f4\3\75\1\u02f4\1\75"+ + "\1\u02f4\1\75\1\u02f4\2\75\1\u02f4\1\75\4\u02f4\3\75"+ + "\1\u02f4\1\75\1\u02f4\14\75\10\0\1\u02e4\3\0\2\u02e5"+ + "\4\0\1\u02e4\65\0\1\u02cb\2\0\2\u02cb\1\0\1\u02e5"+ + "\7\0\1\u02cb\1\0\1\u02e5\10\0\25\u02cb\4\0\1\u02cb"+ + "\2\0\3\u02cb\10\0\1\u02cb\45\0\1\u02f5\44\0\3\144"+ + "\1\0\3\144\10\0\4\144\7\0\7\144\1\u02f6\22\144"+ + "\2\0\3\144\10\0\1\144\3\0\10\u02d2\1\u02ea\3\0"+ + "\2\u02af\4\u02d2\1\u02ea\1\0\62\u02d2\1\0\3\u02eb\1\0"+ + "\3\u02eb\1\u02f7\3\0\2\u02f8\2\0\4\u02eb\7\0\32\u02eb"+ + "\2\0\3\u02eb\10\0\1\u02eb\13\0\1\u02ec\3\0\1\u02ed"+ + "\5\0\1\u02ec\65\0\1\u02d6\2\0\2\u02d6\1\0\1\u02ed"+ + "\7\0\1\u02d6\1\0\1\u02ed\10\0\25\u02d6\4\0\1\u02d6"+ + "\2\0\3\u02d6\10\0\1\u02d6\107\0\1\u02f9\1\0\4\u0127"+ + "\1\u02da\1\u0127\1\u02db\2\u0127\2\351\1\75\7\u0127\1\351"+ + "\2\u0127\1\351\60\u0127\3\u02fa\1\u0163\2\u0127\1\u02fa\1\u0127"+ + "\2\351\1\75\7\u0127\1\351\2\u0127\1\351\13\u0127\2\u02fa"+ + "\3\u0127\1\u02fa\1\u0127\1\u02fa\1\u0127\1\u02fa\2\u0127\1\u02fa"+ + "\1\u0127\4\u02fa\3\u0127\1\u02fa\1\u0127\1\u02fa\14\u0127\1\351"+ + "\3\u0267\3\351\1\u0267\3\351\1\75\11\351\1\u0126\1\u0127"+ + "\1\u0128\1\230\1\351\1\230\7\351\2\u0267\3\351\1\u0267"+ + "\1\351\1\u0267\1\351\1\u0267\2\351\1\u0267\1\351\4\u0267"+ + "\3\351\1\u0267\1\351\1\u0267\14\351\4\225\1\u02de\1\225"+ + "\1\u02df\2\225\3\0\7\225\1\0\2\225\1\75\60\225"+ + "\3\u02fb\1\231\2\225\1\u02fb\1\225\3\0\7\225\1\0"+ + "\2\225\1\75\13\225\2\u02fb\3\225\1\u02fb\1\225\1\u02fb"+ + "\1\225\1\u02fb\2\225\1\u02fb\1\225\4\u02fb\3\225\1\u02fb"+ + "\1\225\1\u02fb\14\225\1\75\3\u0270\3\75\1\u0270\15\75"+ + "\1\224\1\225\1\226\1\0\1\75\1\0\7\75\2\u0270"+ + "\3\75\1\u0270\1\75\1\u0270\1\75\1\u0270\2\75\1\u0270"+ + "\1\75\4\u0270\3\75\1\u0270\1\75\1\u0270\14\75\10\0"+ + "\1\u02f7\3\0\2\u02f8\4\0\1\u02f7\65\0\1\u02eb\2\0"+ + "\2\u02eb\1\0\1\u02f8\7\0\1\u02eb\1\0\1\u02f8\10\0"+ + "\25\u02eb\4\0\1\u02eb\2\0\3\u02eb\10\0\1\u02eb\22\0"+ + "\1\u02fc\66\0\1\u0127\3\u0269\1\u0163\2\u0127\1\u0269\1\u0127"+ + "\2\351\1\75\7\u0127\1\351\2\u0127\1\351\13\u0127\2\u0269"+ + "\3\u0127\1\u0269\1\u0127\1\u0269\1\u0127\1\u0269\2\u0127\1\u0269"+ + "\1\u0127\4\u0269\3\u0127\1\u0269\1\u0127\1\u0269\14\u0127\1\225"+ + "\3\u0272\1\231\2\225\1\u0272\1\225\3\0\7\225\1\0"+ + "\2\225\1\75\13\225\2\u0272\3\225\1\u0272\1\225\1\u0272"+ + "\1\225\1\u0272\2\225\1\u0272\1\225\4\u0272\3\225\1\u0272"+ + "\1\225\1\u0272\14\225"; + + private static int [] zzUnpackTrans() { + int [] result = new int[44450]; + 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[] = { + "Unkown 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 = + "\2\1\14\0\2\1\1\11\4\1\1\11\2\1\1\11"+ + "\14\1\1\11\1\1\1\11\4\1\1\11\1\1\1\11"+ + "\1\1\1\11\2\1\1\3\10\11\4\1\2\11\1\1"+ + "\1\11\3\1\1\11\1\1\1\11\3\1\2\11\1\1"+ + "\1\11\3\1\1\11\1\1\1\11\1\1\1\11\2\1"+ + "\3\0\2\11\1\0\1\11\1\0\2\1\1\0\15\1"+ + "\3\0\1\11\3\1\1\0\1\11\1\1\1\0\1\11"+ + "\4\1\5\11\1\0\1\1\1\0\1\11\1\1\3\0"+ + "\1\2\1\15\1\5\10\0\1\11\4\1\6\11\3\0"+ + "\1\11\5\0\1\1\1\0\1\11\1\1\1\11\2\1"+ + "\1\11\34\1\3\0\6\1\1\0\1\11\1\0\1\1"+ + "\5\0\1\11\2\0\1\1\4\0\1\11\1\0\1\1"+ + "\1\11\1\1\1\11\3\0\41\1\3\0\2\1\1\0"+ + "\1\11\1\1\14\0\1\11\1\1\3\0\45\1\1\11"+ + "\1\0\2\1\1\0\1\1\13\0\1\1\5\0\11\1"+ + "\1\0\30\1\1\11\2\1\7\0\2\1\10\0\1\1"+ + "\1\11\3\0\30\1\1\0\7\1\6\0\2\1\3\0"+ + "\1\1\6\0\1\1\1\11\4\0\13\1\1\0\21\1"+ + "\1\11\6\0\1\1\6\0\1\1\13\0\10\1\1\0"+ + "\23\1\4\0\2\11\2\1\4\0\2\1\7\0\1\1"+ + "\1\11\1\0\10\1\1\0\1\1\1\0\11\1\2\0"+ + "\1\11\2\0\1\1\2\0\2\1\4\0\1\1\2\0"+ + "\2\1\7\0\4\1\1\0\4\1\2\0\11\1\4\0"+ + "\1\11\1\0\4\1\3\0\4\1\3\0\1\1\1\11"+ + "\1\0\6\1\2\0\10\1\7\0\3\1\5\0\3\1"+ + "\1\0\1\1\1\11\1\0\3\1\3\0\7\1\2\11"+ + "\4\0\1\1\3\0\2\1\1\11\1\1\1\0\1\11"+ + "\1\0\5\1\4\0\1\1\2\0\1\1\1\11\2\1"+ + "\4\0\1\11"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[764]; + 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 textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** 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; + + + /** the stack of open (nested) input streams to read from */ + private java.util.Stack zzStreams = new java.util.Stack(); + + /** + * inner class used to store info for nested + * input streams + */ + private static final class ZzFlexStreamInfo { + java.io.Reader zzReader; + int zzEndRead; + int zzStartRead; + int zzCurrentPos; + int zzMarkedPos; + int zzPushbackPos; + int yyline; + int yycolumn; + char [] zzBuffer; + boolean zzAtEOF; + + /** sets all values stored in this class */ + ZzFlexStreamInfo(java.io.Reader zzReader, int zzEndRead, int zzStartRead, + int zzCurrentPos, int zzMarkedPos, int zzPushbackPos, + char [] zzBuffer, boolean zzAtEOF, int yyline, int yycolumn) { + this.zzReader = zzReader; + this.zzEndRead = zzEndRead; + this.zzStartRead = zzStartRead; + this.zzCurrentPos = zzCurrentPos; + this.zzMarkedPos = zzMarkedPos; + this.zzPushbackPos = zzPushbackPos; + this.zzBuffer = zzBuffer; + this.zzAtEOF = zzAtEOF; + this.yyline = yyline; + this.yycolumn = yycolumn; + } + } + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /* user code: */ + int balance = 0; + int commentbalance = 0; + int action_line = 0; + int bufferSize = 16384; + + File file; + Stack files = new Stack(); + + StringBuffer userCode = new StringBuffer(); + + String classCode; + String initCode; + String initThrow; + String eofCode; + String eofThrow; + String lexThrow; + String eofVal; + String scanErrorException; + String cupSymbol = "sym"; + + StringBuffer actionText = new StringBuffer(); + StringBuffer string = new StringBuffer(); + + boolean charCount; + boolean lineCount; + boolean columnCount; + boolean cupCompatible; + boolean cupDebug; + boolean isInteger; + boolean isIntWrap; + boolean isYYEOF; + boolean notUnix; + boolean isPublic; + boolean isFinal; + boolean isAbstract; + boolean lookAheadUsed; + boolean bolUsed; + boolean standalone; + boolean debugOption; + boolean useRowMap = Options.gen_method == Options.PACK || Options.gen_method == Options.TABLE; + boolean packed = Options.gen_method == Options.PACK; + boolean caseless; + boolean inclusive_states; + boolean eofclose; + + String isImplementing; + String isExtending; + String className = "Yylex"; + String functionName; + String tokenType; + String visibility = "public"; + + LexicalStates states = new LexicalStates(); + + Vector actions = new Vector(); + + private int nextState; + + boolean macroDefinition; + + Timer t = new Timer(); + + public int currentLine() { + return yyline; + } + + public void setFile(File file) { + this.file = file; + } + + private Symbol symbol(int type, Object value) { + return new Symbol(type, yyline, yycolumn, value); + } + + private Symbol symbol(int type) { + return new Symbol(type, yyline, yycolumn); + } + + // updates line and column count to the beginning of the first + // non whitespace character in yytext, but leaves yyline+yycolumn + // untouched + private Symbol symbol_countUpdate(int type, Object value) { + int lc = yyline; + int cc = yycolumn; + String text = yytext(); + + for (int i=0; i < text.length(); i++) { + char c = text.charAt(i); + + if (c != '\n' && c != '\r' && c != ' ' && c != '\t' ) + return new Symbol(type, lc, cc, value); + + if (c == '\n') { + lc++; + cc = 0; + } + else + cc++; + } + + return new Symbol(type, yyline, yycolumn, value); + } + + private String makeMacroIdent() { + String matched = yytext().trim(); + return matched.substring(1, matched.length()-1).trim(); + } + + public static String conc(Object a, Object b) { + if (a == null && b == null) return null; + if (a == null) return b.toString(); + if (b == null) return a.toString(); + + return a.toString()+b.toString(); + } + + public static String concExc(Object a, Object b) { + if (a == null && b == null) return null; + if (a == null) return b.toString(); + if (b == null) return a.toString(); + + return a.toString()+", "+b.toString(); + } + + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ + public LexScan(java.io.Reader in) { + states.insert("YYINITIAL", true); + this.zzReader = in; + } + + /** + * Creates a new scanner. + * There is also java.io.Reader version of this constructor. + * + * @param in the java.io.Inputstream to read input from. + */ + public LexScan(java.io.InputStream in) { + this(new java.io.InputStreamReader(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[0x10000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 1666) { + 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) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzPushbackPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * 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(); + } + + + /** + * Stores the current input stream on a stack, and + * reads from a new stream. Lexical state, line, + * char, and column counting remain untouched. + * + * The current input stream can be restored with + * yypopstream (usually in an <> action). + * + * @param reader the new input stream to read from + * + * @see #yypopStream() + */ + public final void yypushStream(java.io.Reader reader) { + zzStreams.push( + new ZzFlexStreamInfo(zzReader, zzEndRead, zzStartRead, zzCurrentPos, + zzMarkedPos, zzPushbackPos, zzBuffer, zzAtEOF, + yyline, yycolumn) + ); + zzAtEOF = false; + zzBuffer = new char[ZZ_BUFFERSIZE]; + zzReader = reader; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yycolumn = 0; + } + + + /** + * Closes the current input stream and continues to + * read from the one on top of the stream stack. + * + * @throws java.util.EmptyStackException + * if there is no further stream to read from. + * + * @throws java.io.IOException + * if there was an error in closing the stream. + * + * @see #yypushStream(java.io.Reader) + */ + public final void yypopStream() throws java.io.IOException { + zzReader.close(); + ZzFlexStreamInfo s = (ZzFlexStreamInfo) zzStreams.pop(); + zzBuffer = s.zzBuffer; + zzReader = s.zzReader; + zzEndRead = s.zzEndRead; + zzStartRead = s.zzStartRead; + zzCurrentPos = s.zzCurrentPos; + zzMarkedPos = s.zzMarkedPos ; + zzPushbackPos = s.zzPushbackPos; + zzAtEOF = s.zzAtEOF; + yyline = s.yyline; + yycolumn = s.yycolumn; + } + + + /** + * Returns true iff there are still streams left + * to read from on the stream stack. + */ + public final boolean yymoreStreams() { + return !zzStreams.isEmpty(); + } + + + /** + * 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. + * + * @param reader the new input stream + * + * @see #yypushStream(java.io.Reader) + * @see #yypopStream() + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * 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; + } + + + /** + * Contains user EOF-code, which will be executed exactly once, + * when the end of file is reached + */ + private void zzDoEOF() throws java.io.IOException { + if (!zzEOFDone) { + zzEOFDone = true; + yyclose(); + } + } + + + /** + * 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 Symbol next_token() throws java.io.IOException { + int zzInput; + int zzAction; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + int zzPushbackPosL = zzPushbackPos = -1; + boolean zzWasPushback; + + while (true) { + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL = zzMarkedPos; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + boolean zzR = false; + for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL; + zzCurrentPosL++) { + switch (zzBufferL[zzCurrentPosL]) { + 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++; + } + } + + 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--; + } + if (zzMarkedPosL > zzStartRead) { + switch (zzBufferL[zzMarkedPosL-1]) { + case '\n': + case '\u000B': + case '\u000C': + case '\u0085': + case '\u2028': + case '\u2029': + zzAtBOL = true; + break; + case '\r': + if (zzMarkedPosL < zzEndReadL) + zzAtBOL = zzBufferL[zzMarkedPosL] != '\n'; + else if (zzAtEOF) + zzAtBOL = false; + else { + boolean eof = zzRefill(); + zzMarkedPosL = zzMarkedPos; + zzEndReadL = zzEndRead; + zzBufferL = zzBuffer; + if (eof) + zzAtBOL = false; + else + zzAtBOL = zzBufferL[zzMarkedPosL] != '\n'; + } + break; + default: + zzAtBOL = false; + } + } + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + if (zzAtBOL) + zzState = ZZ_LEXSTATE[zzLexicalState+1]; + else + zzState = ZZ_LEXSTATE[zzLexicalState]; + + zzWasPushback = false; + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = zzBufferL[zzCurrentPosL++]; + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + zzPushbackPos = zzPushbackPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + zzPushbackPosL = zzPushbackPos; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = zzBufferL[zzCurrentPosL++]; + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 2) == 2 ) + zzPushbackPosL = zzCurrentPosL; + + if ( (zzAttributes & 1) == 1 ) { + zzWasPushback = (zzAttributes & 4) == 4; + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + if (zzWasPushback) + zzMarkedPos = zzPushbackPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 85: + { return symbol(FULL); + } + case 142: break; + case 92: + { debugOption = true; + } + case 143: break; + case 57: + { return symbol(CHAR,new Character('\t')); + } + case 144: break; + case 108: + { actionText.setLength(0); yybegin(JAVA_CODE); + Symbol s = symbol_countUpdate(EOFRULE, null); + action_line = s.left+1; + return s; + } + case 145: break; + case 107: + { throw new ScannerException(file,ErrorMessages.NO_BUFFER_SIZE, yyline); + } + case 146: break; + case 91: + { isYYEOF = true; + } + case 147: break; + case 54: + { return symbol(CHAR, new Character(yytext().charAt(1))); + } + case 148: break; + case 98: + { isInteger = true; + if (eofVal == null) + eofVal = "return 0;"; + eofclose = true; + } + case 149: break; + case 11: + { yybegin(REGEXP); + } + case 150: break; + case 112: + { isAbstract = true; + } + case 151: break; + case 101: + { initCode = conc(initCode,string); yybegin(MACROS); + } + case 152: break; + case 45: + { throw new ScannerException(file,ErrorMessages.UNEXPECTED_NL, yyline, yycolumn); + } + case 153: break; + case 12: + { return symbol_countUpdate(RBRACE, null); + } + case 154: break; + case 74: + { return symbol(REPEAT, new Integer(yytext().substring(1).trim())); + } + case 155: break; + case 55: + { return symbol(CHAR, new Character( (char) Integer.parseInt(yytext().substring(1,yytext().length()), 8))); + } + case 156: break; + case 97: + { columnCount = true; + } + case 157: break; + case 122: + { return symbol(LETTERCLASS); + } + case 158: break; + case 15: + { if (macroDefinition) { yybegin(MACROS); } return symbol(REGEXPEND); + } + case 159: break; + case 77: + { inclusive_states = true; yybegin(STATELIST); + } + case 160: break; + case 56: + { return symbol(CHAR,new Character('\n')); + } + case 161: break; + case 81: + { return symbol(MACROUSE, yytext().substring(1,yytext().length()-1)); + } + case 162: break; + case 25: + { return symbol(OPENBRACKET); + } + case 163: break; + case 123: + { throw new ScannerException(file,ErrorMessages.QUIL_INITTHROW, yyline); + } + case 164: break; + case 126: + { visibility = "private"; Skeleton.makePrivate(); + } + case 165: break; + case 49: + { commentbalance++; + } + case 166: break; + case 9: + { throw new ScannerException(file,ErrorMessages.UNKNOWN_OPTION, yyline, yycolumn); + } + case 167: break; + case 68: + { string.append('\n'); + } + case 168: break; + case 33: + { balance++; actionText.append('{'); + } + case 169: break; + case 48: + { if (commentbalance > 0) + commentbalance--; + else + yybegin(nextState); + } + case 170: break; + case 67: + { string.append('\"'); + } + case 171: break; + case 95: + { tokenType = yytext().substring(6).trim(); + } + case 172: break; + case 79: + { return symbol_countUpdate(MACROUSE, makeMacroIdent()); + } + case 173: break; + case 14: + { return symbol(CHAR, new Character(yytext().charAt(0))); + } + case 174: break; + case 140: + { eofclose = false; + } + case 175: break; + case 32: + { if (balance > 0) { + balance--; + actionText.append('}'); + } + else { + yybegin(REGEXPSTART); + Action a = new Action(actionText.toString(), action_line); + actions.addElement(a); + return symbol(ACTION, a); + } + } + case 176: break; + case 120: + { isExtending = yytext().substring(9).trim(); + } + case 177: break; + case 113: + { cupSymbol = yytext().substring(8).trim(); + if (cupCompatible) Out.warning(ErrorMessages.CUPSYM_AFTER_CUP, yyline); + } + case 178: break; + case 63: + { yybegin(REPEATEXP); return symbol(REPEAT, new Integer(yytext().trim().substring(1).trim())); + } + case 179: break; + case 88: + { packed = true; useRowMap = true; + } + case 180: break; + case 27: + { return symbol(PLUS); + } + case 181: break; + case 99: + { isPublic = true; + } + case 182: break; + case 70: + { string.append('\r'); + } + case 183: break; + case 76: + { inclusive_states = false; yybegin(STATELIST); + } + case 184: break; + case 3: + { userCode.append(yytext()); + } + case 185: break; + case 19: + { lookAheadUsed = true; return symbol(LOOKAHEAD); + } + case 186: break; + case 110: + { lexThrow = concExc(lexThrow,yytext().substring(8).trim()); + } + case 187: break; + case 26: + { return symbol(CLOSEBRACKET); + } + case 188: break; + case 80: + { string.append( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16)); + } + case 189: break; + case 37: + { throw new ScannerException(file,ErrorMessages.UNTERMINATED_STR, yyline, yycolumn); + } + case 190: break; + case 69: + { string.append('\t'); + } + case 191: break; + case 23: + { return symbol(BANG); + } + case 192: break; + case 111: + { eofclose = true; + } + case 193: break; + case 17: + { yybegin(CHARCLASS); return symbol(OPENCLASS); + } + case 194: break; + case 114: + { cupDebug = true; + } + case 195: break; + case 87: + { charCount = true; + } + case 196: break; + case 58: + { return symbol(CHAR,new Character('\r')); + } + case 197: break; + case 66: + { string.append( (char) Integer.parseInt(yytext().substring(1,yytext().length()), 8)); + } + case 198: break; + case 134: + { scanErrorException = yytext().substring(11).trim(); + } + case 199: break; + case 60: + { return symbol(CHAR,new Character('\b')); + } + case 200: break; + case 35: + { yybegin(REGEXP); return symbol(MORETHAN); + } + case 201: break; + case 132: + { isImplementing = concExc(isImplementing, yytext().substring(12).trim()); + } + case 202: break; + case 78: + { return symbol(CHAR, new Character( (char) Integer.parseInt(yytext().substring(2,yytext().length()), 16))); + } + case 203: break; + case 90: + { isFinal = true; + } + case 204: break; + case 137: + { return symbol(UPPERCLASS); + } + case 205: break; + case 46: + { yybegin(REGEXP); return symbol(RBRACE); + } + case 206: break; + case 51: + { Out.warning(ErrorMessages.NOT_AT_BOL, yyline); yypushback(1); + } + case 207: break; + case 28: + { return symbol(QUESTION); + } + case 208: break; + case 36: + { string.append(yytext()); + } + case 209: break; + case 135: + { initThrow = concExc(initThrow,string); yybegin(MACROS); + } + case 210: break; + case 141: + { return symbol(JLETTERDIGITCLASS); + } + case 211: break; + case 53: + { nextState = REGEXPSTART; yybegin(COMMENT); + } + case 212: break; + case 130: + { eofThrow = concExc(eofThrow,string); yybegin(MACROS); + } + case 213: break; + case 61: + { actionText.setLength(0); yybegin(JAVA_CODE); action_line = yyline+1; return symbol(REGEXPEND); + } + case 214: break; + case 138: + { return symbol(LOWERCLASS); + } + case 215: break; + case 38: + { yybegin(nextState); return symbol(STRING, string.toString()); + } + case 216: break; + case 82: + { classCode = conc(classCode,string); yybegin(MACROS); + } + case 217: break; + case 8: + { return symbol(IDENT, yytext()); + } + case 218: break; + case 43: + { return symbol(HAT); + } + case 219: break; + case 29: + { lookAheadUsed = true; return symbol(DOLLAR); + } + case 220: break; + case 124: + { eofThrow = concExc(eofThrow,yytext().substring(10).trim()); + } + case 221: break; + case 5: + { states.insert(yytext(),inclusive_states); + } + case 222: break; + case 127: + { standalone = true; isInteger = true; + } + case 223: break; + case 4: + { throw new ScannerException(file,ErrorMessages.UNEXPECTED_CHAR, yyline, yycolumn); + } + case 224: break; + case 47: + { t.start(); + yybegin(MACROS); + macroDefinition = true; + return symbol(USERCODE,userCode); + } + case 225: break; + case 59: + { return symbol(CHAR,new Character('\f')); + } + case 226: break; + case 94: + { eofCode = conc(eofCode,string); yybegin(MACROS); + } + case 227: break; + case 65: + { string.append(yytext().charAt(1)); + } + case 228: break; + case 115: + { caseless = true; + } + case 229: break; + case 39: + { throw new ScannerException(file,ErrorMessages.EOL_IN_CHARCLASS,yyline,yycolumn); + } + case 230: break; + case 117: + { return symbol(DIGITCLASS); + } + case 231: break; + case 64: + { if (macroDefinition) { + yybegin(EATWSPNL); + return symbol(BAR); + } + else { + yybegin(REGEXPSTART); + return symbol(NOACTION); + } + } + case 232: break; + case 30: + { bolUsed = true; return symbol(HAT); + } + case 233: break; + case 105: + { throw new ScannerException(file,ErrorMessages.QUIL_CUPSYM, yyline); + } + case 234: break; + case 102: + { isIntWrap = true; + } + case 235: break; + case 41: + { if (balance > 0) balance--; else yybegin(REGEXP); return symbol(CLOSECLASS); + } + case 236: break; + case 84: + { cupCompatible = true; + isImplementing = concExc(isImplementing, "java_cup.runtime.Scanner"); + if (functionName == null) + functionName = "next_token"; + if (tokenType == null) + tokenType = "java_cup.runtime.Symbol"; + if (eofVal == null) + eofVal = "return new java_cup.runtime.Symbol("+cupSymbol+".EOF);"; + if (!Options.jlex) eofclose = true; + } + case 237: break; + case 116: + { bufferSize = Integer.parseInt(yytext().substring(8).trim()); + } + case 238: break; + case 31: + { actionText.append(yytext()); + } + case 239: break; + case 86: + { lineCount = true; + } + case 240: break; + case 128: + { throw new ScannerException(file,ErrorMessages.QUIL_SCANERROR, yyline); + } + case 241: break; + case 104: + { throw new ScannerException(file,ErrorMessages.QUIL_THROW, yyline); + } + case 242: break; + case 83: + { isInteger = true; + } + case 243: break; + case 129: + { return symbol(JLETTERCLASS); + } + case 244: break; + case 18: + { return symbol(STAR); + } + case 245: break; + case 121: + { throw new ScannerException(file,ErrorMessages.QUIL_EOFTHROW, yyline); + } + case 246: break; + case 44: + { return symbol(DASH); + } + case 247: break; + case 106: + { className = yytext().substring(7).trim(); + } + case 248: break; + case 62: + { nextState = REGEXP; yybegin(COMMENT); + } + case 249: break; + case 136: + { lexThrow = concExc(lexThrow,yytext().substring(12).trim()); + } + case 250: break; + case 22: + { return symbol(BAR); + } + case 251: break; + case 125: + { functionName = yytext().substring(10).trim(); + } + case 252: break; + case 13: + { yybegin(STATES); return symbol_countUpdate(LESSTHAN, null); + } + case 253: break; + case 119: + { eofVal = string.toString(); yybegin(MACROS); + } + case 254: break; + case 73: + { yypushback(1); yycolumn--; return symbol(CHAR, new Character(yytext().charAt(0))); + } + case 255: break; + case 24: + { return symbol(TILDE); + } + case 256: break; + case 139: + { lexThrow = concExc(lexThrow,string); yybegin(MACROS); + } + case 257: break; + case 103: + { notUnix = true; + } + case 258: break; + case 89: + { packed = false; useRowMap = true; + } + case 259: break; + case 20: + { string.setLength(0); nextState = REGEXP; yybegin(STRING_CONTENT); + } + case 260: break; + case 2: + { /* ignore */ + } + case 261: break; + case 93: + { return symbol(UNICODE); + } + case 262: break; + case 16: + { return symbol(POINT); + } + case 263: break; + case 72: + { string.append('\b'); + } + case 264: break; + case 21: + { yybegin(REGEXPSTART); return symbol(LBRACE); + } + case 265: break; + case 131: + { initThrow = concExc(initThrow,yytext().substring(11).trim()); + } + case 266: break; + case 96: + { packed = false; useRowMap = false; + } + case 267: break; + case 7: + { yybegin(MACROS); + } + case 268: break; + case 75: + { string.setLength(0); yybegin(COPY); + } + case 269: break; + case 42: + { string.setLength(0); nextState = CHARCLASS; yybegin(STRING_CONTENT); + } + case 270: break; + case 118: + { actionText.setLength(0); yybegin(JAVA_CODE); action_line = yyline+1; return symbol(EOFRULE); + } + case 271: break; + case 52: + { macroDefinition = false; yybegin(REGEXPSTART); return symbol(DELIMITER); + } + case 272: break; + case 50: + { nextState = MACROS; yybegin(COMMENT); + } + case 273: break; + case 10: + { yybegin(REGEXP); return symbol(EQUALS); + } + case 274: break; + case 34: + { return symbol(COMMA); + } + case 275: break; + case 1: + { return symbol(EOF); + } + case 276: break; + case 100: + { throw new ScannerException(file,ErrorMessages.EOF_WO_ACTION); + } + case 277: break; + case 71: + { string.append('\f'); + } + case 278: break; + case 40: + { balance++; return symbol(OPENCLASS); + } + case 279: break; + case 133: + { throw new ScannerException(file,ErrorMessages.QUIL_YYLEXTHROW, yyline); + } + case 280: break; + case 109: + { File f = new File(yytext().substring(9).trim()); + if ( !f.canRead() ) + throw new ScannerException(file,ErrorMessages.NOT_READABLE, yyline); + // check for cycle + if (files.search(f) > 0) + throw new ScannerException(file,ErrorMessages.FILE_CYCLE, yyline); + try { + yypushStream( new FileReader(f) ); + files.push(file); + file = f; + Out.println("Including \""+file+"\""); + } + catch (FileNotFoundException e) { + throw new ScannerException(file,ErrorMessages.NOT_READABLE, yyline); + } + } + case 281: break; + case 6: + { + } + case 282: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + zzDoEOF(); + switch (zzLexicalState) { + case STRING_CONTENT: { + throw new ScannerException(file,ErrorMessages.EOF_IN_STRING); + } + case 765: break; + case MACROS: { + if ( yymoreStreams() ) { + file = (File) files.pop(); + yypopStream(); + } + else + throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); + } + case 766: break; + case STATELIST: { + throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); + } + case 767: break; + case CHARCLASS: { + throw new ScannerException(file,ErrorMessages.EOF_IN_REGEXP); + } + case 768: break; + case JAVA_CODE: { + throw new ScannerException(file,ErrorMessages.EOF_IN_ACTION, action_line-1); + } + case 769: break; + case REPEATEXP: { + throw new ScannerException(file,ErrorMessages.EOF_IN_REGEXP); + } + case 770: break; + case COMMENT: { + throw new ScannerException(file,ErrorMessages.EOF_IN_COMMENT); + } + case 771: break; + case STATES: { + throw new ScannerException(file,ErrorMessages.EOF_IN_STATES); + } + case 772: break; + case COPY: { + throw new ScannerException(file,ErrorMessages.EOF_IN_MACROS); + } + case 773: break; + default: + { + if ( yymoreStreams() ) { + file = (File) files.pop(); + yypopStream(); + } + else + return symbol(EOF); + } + } + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + /** + * Converts an int token code into the name of the + * token by reflection on the cup symbol class/interface sym + * + * This code was contributed by Karl Meissner + */ + private String getTokenName(int token) { + try { + java.lang.reflect.Field [] classFields = sym.class.getFields(); + for (int i = 0; i < classFields.length; i++) { + if (classFields[i].getInt(null) == token) { + return classFields[i].getName(); + } + } + } catch (Exception e) { + e.printStackTrace(System.err); + } + + return "UNKNOWN TOKEN"; + } + + /** + * Same as next_token but also prints the token to standard out + * for debugging. + * + * This code was contributed by Karl Meissner + */ + public Symbol debug_next_token() throws java.io.IOException { + java_cup.runtime.Symbol s = next_token(); + System.out.println( "line:" + (yyline+1) + " col:" + (yycolumn+1) + " --"+ yytext() + "--" + getTokenName(s.sym) + "--"); + return s; + } + + /** + * Runs the scanner on input files. + * + * This main method is the debugging routine for the scanner. + * It prints debugging information about each returned token to + * System.out until the end of file is reached, or an error occured. + * + * @param argv the command line, contains the filenames to run + * the scanner on. + */ + public static void main(String argv[]) { + if (argv.length == 0) { + System.out.println("Usage : java LexScan "); + } + else { + for (int i = 0; i < argv.length; i++) { + LexScan scanner = null; + try { + scanner = new LexScan( new java.io.FileReader(argv[i]) ); + while ( !scanner.zzAtEOF ) scanner.debug_next_token(); + } + catch (java.io.FileNotFoundException e) { + System.out.println("File not found : \""+argv[i]+"\""); + } + catch (java.io.IOException e) { + System.out.println("IO error scanning file \""+argv[i]+"\""); + System.out.println(e); + } + catch (Exception e) { + System.out.println("Unexpected exception:"); + e.printStackTrace(); + } + } + } + } + + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/LexicalStates.java b/tools/lexer/jflex-1.4/src/JFlex/LexicalStates.java new file mode 100644 index 000000000000..4fca957831be --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/LexicalStates.java @@ -0,0 +1,99 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + + +/** + * Simple symbol table, mapping lexical state names to integers. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +public class LexicalStates { + + /** maps state name to state number */ + Hashtable states; + + /** codes of inclusive states (subset of states) */ + Vector inclusive; + + /** number of declared states */ + int numStates; + + + /** + * constructs a new lexical state symbol table + */ + public LexicalStates() { + states = new Hashtable(); + inclusive = new Vector(); + } + + + /** + * insert a new state declaration + */ + public void insert(String name, boolean is_inclusive) { + if ( states.containsKey(name) ) return; + + Integer code = new Integer(numStates++); + states.put(name, code); + + if (is_inclusive) + inclusive.addElement(code); + } + + + /** + * returns the number (code) of a declared state, + * null if no such state has been declared. + */ + public Integer getNumber(String name) { + return (Integer) states.get(name); + } + + + /** + * returns the number of declared states + */ + public int number() { + return numStates; + } + + + /** + * returns the names of all states + */ + public Enumeration names() { + return states.keys(); + } + + /** + * returns the code of all inclusive states + */ + public Enumeration getInclusiveStates() { + return inclusive.elements(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/MacroException.java b/tools/lexer/jflex-1.4/src/JFlex/MacroException.java new file mode 100644 index 000000000000..85db5ad23c3a --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/MacroException.java @@ -0,0 +1,49 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * This Exception is used in the macro expander to report cycles or + * undefined macro usages. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +public class MacroException extends RuntimeException { + + /** + * Creates a new MacroException without message + */ + public MacroException() { + } + + + /** + * Creates a new MacroException with the specified message + * + * @param message the error description presented to the user. + */ + public MacroException(String message) { + super(message); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Macros.java b/tools/lexer/jflex-1.4/src/JFlex/Macros.java new file mode 100644 index 000000000000..a1f18e538402 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Macros.java @@ -0,0 +1,219 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + + +/** + * Symbol table and expander for macros. + * + * Maps macros to their (expanded) definitions, detects cycles and + * unused macros. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:32 $ + */ +final public class Macros { + + /** Maps names of macros to their definition */ + private Hashtable macros; + + /** Maps names of macros to their "used" flag */ + private Hashtable used; + + + /** + * Creates a new macro expander. + */ + public Macros() { + macros = new Hashtable(); + used = new Hashtable(); + } + + + /** + * Stores a new macro and its definition. + * + * @param name the name of the new macro + * @param definition the definition of the new macro + * + * @return true, iff the macro name has not been + * stored before. + */ + public boolean insert(String name, RegExp definition) { + + if (Options.DEBUG) + Out.debug("inserting macro "+name+" with definition :"+Out.NL+definition); //$NON-NLS-1$ //$NON-NLS-2$ + + used.put(name, Boolean.FALSE); + return macros.put(name,definition) == null; + } + + + /** + * Marks a makro as used. + * + * @return true, iff the macro name has been + * stored before. + */ + public boolean markUsed(String name) { + return used.put(name, Boolean.TRUE) != null; + } + + + /** + * Tests if a macro has been used. + * + * @return true, iff the macro has been used in + * a regular expression. + */ + public boolean isUsed(String name) { + return ((Boolean)used.get(name)).booleanValue(); + } + + + /** + * Returns all unused macros. + * + * @return the enumeration of macro names that have not been used. + */ + public Enumeration unused() { + + Vector unUsed = new Vector(); + + Enumeration names = used.keys(); + while ( names.hasMoreElements() ) { + String name = (String) names.nextElement(); + Boolean isUsed = (Boolean) used.get( name ); + if ( !isUsed.booleanValue() ) unUsed.addElement(name); + } + + return unUsed.elements(); + } + + + /** + * Fetches the definition of the macro with the specified name, + *

+ * The definition will either be the same as stored (expand() not + * called), or an equivalent one, that doesn't contain any macro + * usages (expand() called before). + * + * @param name the name of the macro + * + * @return the definition of the macro, null if + * no macro with the specified name has been stored. + * + * @see JFlex.Macros#expand + */ + public RegExp getDefinition(String name) { + return (RegExp) macros.get(name); + } + + + /** + * Expands all stored macros, so that getDefinition always returns + * a defintion that doesn't contain any macro usages. + * + * @throws MacroException if there is a cycle in the macro usage graph. + */ + public void expand() throws MacroException { + + Enumeration names; + + names = macros.keys(); + + while ( names.hasMoreElements() ) { + String name = (String) names.nextElement(); + if ( isUsed(name) ) + macros.put(name, expandMacro(name, getDefinition(name))); + // this put doesn't get a new key, so only a new value + // is set for the key "name" (without changing the enumeration + // "names"!) + } + } + + + /** + * Expands the specified macro by replacing each macro usage + * with the stored definition. + * + * @param name the name of the macro to expand (for detecting cycles) + * @param definition the definition of the macro to expand + * + * @return the expanded definition of the macro. + * + * @throws MacroException when an error (such as a cyclic definition) + * occurs during expansion + */ + private RegExp expandMacro(String name, RegExp definition) throws MacroException { + + // Out.print("checking macro "+name); + // Out.print("definition is "+definition); + + switch ( definition.type ) { + case sym.BAR: + case sym.CONCAT: + RegExp2 binary = (RegExp2) definition; + binary.r1 = expandMacro(name, binary.r1); + binary.r2 = expandMacro(name, binary.r2); + return definition; + + case sym.STAR: + case sym.PLUS: + case sym.QUESTION: + case sym.BANG: + case sym.TILDE: + RegExp1 unary = (RegExp1) definition; + unary.content = expandMacro(name, (RegExp) unary.content); + return definition; + + case sym.MACROUSE: + String usename = (String) ((RegExp1) definition).content; + + if ( name.equals(usename) ) + throw new MacroException(ErrorMessages.get(ErrorMessages.MACRO_CYCLE, name)); + + RegExp usedef = getDefinition(usename); + + if ( usedef == null ) + throw new MacroException(ErrorMessages.get(ErrorMessages.MACRO_DEF_MISSING, usename, name)); + + markUsed(usename); + + return expandMacro(name, usedef); + + case sym.STRING: + case sym.STRING_I: + case sym.CHAR: + case sym.CHAR_I: + case sym.CCLASS: + case sym.CCLASSNOT: + return definition; + + default: + throw new MacroException("unknown expression type "+definition.type+" in macro expansion"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Main.java b/tools/lexer/jflex-1.4/src/JFlex/Main.java new file mode 100644 index 000000000000..20227c03cbdf --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Main.java @@ -0,0 +1,344 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import JFlex.gui.MainFrame; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.Vector; + + +/** + * This is the main class of JFlex controlling the scanner generation process. + * It is responsible for parsing the commandline, getting input files, + * starting up the GUI if necessary, etc. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.20 $, $Date: 2004/11/06 23:03:32 $ + */ +public class Main { + + /** JFlex version */ + final public static String version = "1.4.1"; //$NON-NLS-1$ + + /** + * Generates a scanner for the specified input file. + * + * @param inputFile a file containing a lexical specification + * to generate a scanner for. + */ + public static void generate(File inputFile) { + + Out.resetCounters(); + + Timer totalTime = new Timer(); + Timer time = new Timer(); + + LexScan scanner = null; + LexParse parser = null; + FileReader inputReader = null; + + totalTime.start(); + + try { + Out.println(ErrorMessages.READING, inputFile.toString()); + inputReader = new FileReader(inputFile); + scanner = new LexScan(inputReader); + scanner.setFile(inputFile); + parser = new LexParse(scanner); + } + catch (FileNotFoundException e) { + Out.error(ErrorMessages.CANNOT_OPEN, inputFile.toString()); + throw new GeneratorException(); + } + + try { + NFA nfa = (NFA) parser.parse().value; + + Out.checkErrors(); + + if (Options.dump) Out.dump(ErrorMessages.get(ErrorMessages.NFA_IS)+ + Out.NL+nfa+Out.NL); + + if (Options.dot) + nfa.writeDot(Emitter.normalize("nfa.dot", null)); //$NON-NLS-1$ + + Out.println(ErrorMessages.NFA_STATES, nfa.numStates); + + time.start(); + DFA dfa = nfa.getDFA(); + time.stop(); + Out.time(ErrorMessages.DFA_TOOK, time); + + dfa.checkActions(scanner, parser); + + nfa = null; + + if (Options.dump) Out.dump(ErrorMessages.get(ErrorMessages.DFA_IS)+ + Out.NL+dfa+Out.NL); + + if (Options.dot) + dfa.writeDot(Emitter.normalize("dfa-big.dot", null)); //$NON-NLS-1$ + + time.start(); + dfa.minimize(); + time.stop(); + + Out.time(ErrorMessages.MIN_TOOK, time); + + if (Options.dump) + Out.dump(ErrorMessages.get(ErrorMessages.MIN_DFA_IS)+ + Out.NL+dfa); + + if (Options.dot) + dfa.writeDot(Emitter.normalize("dfa-min.dot", null)); //$NON-NLS-1$ + + time.start(); + + Emitter e = new Emitter(inputFile, parser, dfa); + e.emit(); + + time.stop(); + + Out.time(ErrorMessages.WRITE_TOOK, time); + + totalTime.stop(); + + Out.time(ErrorMessages.TOTAL_TIME, totalTime); + } + catch (ScannerException e) { + Out.error(e.file, e.message, e.line, e.column); + throw new GeneratorException(); + } + catch (MacroException e) { + Out.error(e.getMessage()); + throw new GeneratorException(); + } + catch (IOException e) { + Out.error(ErrorMessages.IO_ERROR, e.toString()); + throw new GeneratorException(); + } + catch (OutOfMemoryError e) { + Out.error(ErrorMessages.OUT_OF_MEMORY); + throw new GeneratorException(); + } + catch (GeneratorException e) { + throw new GeneratorException(); + } + catch (Exception e) { + e.printStackTrace(); + throw new GeneratorException(); + } + + } + + public static Vector parseOptions(String argv[]) throws SilentExit { + Vector files = new Vector(); + + for (int i = 0; i < argv.length; i++) { + + if ( argv[i].equals("-d") || argv[i].equals("--outdir") ) { //$NON-NLS-1$ //$NON-NLS-2$ + if ( ++i >= argv.length ) { + Out.error(ErrorMessages.NO_DIRECTORY); + throw new GeneratorException(); + } + Options.setDir(argv[i]); + continue; + } + + if ( argv[i].equals("--skel") || argv[i].equals("-skel") ) { //$NON-NLS-1$ //$NON-NLS-2$ + if ( ++i >= argv.length ) { + Out.error(ErrorMessages.NO_SKEL_FILE); + throw new GeneratorException(); + } + + Options.setSkeleton(new File(argv[i])); + continue; + } + + if ( argv[i].equals("-jlex") || argv[i].equals("--jlex") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.jlex = true; + continue; + } + + if ( argv[i].equals("-v") || argv[i].equals("--verbose") || argv[i].equals("-verbose") ) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + Options.verbose = true; + Options.progress = true; + continue; + } + + if ( argv[i].equals("-q") || argv[i].equals("--quiet") || argv[i].equals("-quiet") ) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + Options.verbose = false; + Options.progress = false; + continue; + } + + if ( argv[i].equals("--dump") || argv[i].equals("-dump") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.dump = true; + continue; + } + + if ( argv[i].equals("--time") || argv[i].equals("-time") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.time = true; + continue; + } + + if ( argv[i].equals("--version") || argv[i].equals("-version") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Out.println(ErrorMessages.THIS_IS_JFLEX, version); + throw new SilentExit(); + } + + if ( argv[i].equals("--dot") || argv[i].equals("-dot") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.dot = true; + continue; + } + + if ( argv[i].equals("--help") || argv[i].equals("-h") || argv[i].equals("/h") ) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + printUsage(); + throw new SilentExit(); + } + + if ( argv[i].equals("--info") || argv[i].equals("-info") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Out.printSystemInfo(); + throw new SilentExit(); + } + + if ( argv[i].equals("--nomin") || argv[i].equals("-nomin") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.no_minimize = true; + continue; + } + + if ( argv[i].equals("--pack") || argv[i].equals("-pack") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.gen_method = Options.PACK; + continue; + } + + if ( argv[i].equals("--table") || argv[i].equals("-table") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.gen_method = Options.TABLE; + continue; + } + + if ( argv[i].equals("--switch") || argv[i].equals("-switch") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.gen_method = Options.SWITCH; + continue; + } + + if ( argv[i].equals("--nobak") || argv[i].equals("-nobak") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.no_backup = true; + continue; + } + + if ( argv[i].equals("--charat") || argv[i].equals("-charat") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.char_at = true; + continue; + } + + if ( argv[i].equals("--sliceandcharat") || argv[i].equals("-sliceandcharat") ) { //$NON-NLS-1$ //$NON-NLS-2$ + Options.sliceAndCharAt = true; + continue; + } + + if ( argv[i].startsWith("-") ) { //$NON-NLS-1$ + Out.error(ErrorMessages.UNKNOWN_COMMANDLINE, argv[i]); + printUsage(); + throw new SilentExit(); + } + + // if argv[i] is not an option, try to read it as file + File f = new File(argv[i]); + if ( f.isFile() && f.canRead() ) + files.addElement(f); + else { + Out.error("Sorry, couldn't open \""+f+"\""); //$NON-NLS-2$ + throw new GeneratorException(); + } + } + + return files; + } + + + public static void printUsage() { + Out.println(""); //$NON-NLS-1$ + Out.println("Usage: jflex "); + Out.println(""); + Out.println("Where can be one or more of"); + Out.println("-d write generated file to "); + Out.println("--skel use external skeleton "); + Out.println("--switch"); + Out.println("--table"); + Out.println("--pack set default code generation method"); + Out.println("--jlex strict JLex compatibility"); + Out.println("--nomin skip minimization step"); + Out.println("--nobak don't create backup files"); + Out.println("--dump display transition tables"); + Out.println("--dot write graphviz .dot files for the generated automata (alpha)"); + Out.println("--verbose"); + Out.println("-v display generation progress messages (default)"); + Out.println("--quiet"); + Out.println("-q display errors only"); + Out.println("--time display generation time statistics"); + Out.println("--version print the version number of this copy of jflex"); + Out.println("--info print system + JDK information"); + Out.println("--help"); + Out.println("-h print this message"); + Out.println(""); + Out.println(ErrorMessages.THIS_IS_JFLEX, version); + Out.println("Have a nice day!"); + } + + + public static void generate(String argv[]) throws SilentExit { + Vector files = parseOptions(argv); + + if (files.size() > 0) { + for (int i = 0; i < files.size(); i++) + generate((File) files.elementAt(i)); + } + else { + new MainFrame(); + } + } + + + /** + * Starts the generation process with the files in argv or + * pops up a window to choose a file, when argv doesn't have + * any file entries. + * + * @param argv the commandline. + */ + public static void main(String argv[]) { + try { + generate(argv); + } + catch (GeneratorException e) { + Out.statistics(); + System.exit(1); + } + catch (SilentExit e) { + System.exit(1); + } + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Messages.properties b/tools/lexer/jflex-1.4/src/JFlex/Messages.properties new file mode 100644 index 000000000000..e491a95005ab --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Messages.properties @@ -0,0 +1,70 @@ +UNTERMINATED_STR = Unterminated string at end of line. +EOF_WO_ACTION = <> must be followed by an action. +EOF_SINGLERULE = <> can only be used as a single rule. +UNKNOWN_OPTION = Unkown %-option +UNEXPECTED_CHAR = Unexpected character +UNEXPECTED_NL = Unexpected character +LEXSTATE_UNDECL = Lexical state has not been declared. +STATE_IDENT_EXP = State identifier expected. +REPEAT_ZERO = Illegal repeat statement. At least one operand must be > 0 +REPEAT_GREATER = Illegal repeat statement. First operand must not be greater than second one. +REGEXP_EXPECTED = Regular expression expected. +MACRO_UNDECL = Macro has not been declared. +CHARSET_2_SMALL = Character set is too small for this class. +CS2SMALL_STRING = Character set is too small for a charactor of this string. +CS2SMALL_CHAR = Character set is too small for this character. +CHARCLASS_MACRO = Macros in character classes are not supported. +UNKNOWN_SYNTAX = Syntax error. +SYNTAX_ERROR = Syntax error. +NOT_AT_BOL = %-option is not at the beginning of the line. +NO_MATCHING_BR = Didn't find matching bracket +EOF_IN_ACTION = Unexpected end of file in action code +EOF_IN_COMMENT = Unexpected end of file in comment +EOF_IN_STRING = Unexpected end of file in string +EOF_IN_MACROS = Unexpected end of file in macros +EOF_IN_STATES = Unexpected end of file in state list +EOF_IN_REGEXP = Unexpected end of file in regular expression +UNEXPECTED_EOF = Unexpected end of file (maybe missing "*/" ")" "]" or "}") +NO_LEX_SPEC = This seems not to be a lexical specification (first %% is missing) +NO_LAST_ACTION = Last action in the specification must not be "|" +LOOKAHEAD_ERROR = Dangerous lookahead expression, yytext might contain too many characters. +NO_DIRECTORY = No directory for -d option +NO_SKEL_FILE = No file provided for -skel option +WRONG_SKELETON = Incorrect skeleton file (wrong number of sections). +OUT_OF_MEMORY = JFlex has run out of memory. Please try increasing the maximum JVM heap size +QUIL_INITTHROW = %initthrow needs a list of (qualified) identifiers +QUIL_EOFTHROW = %eofthrow needs a list of (qualified) identifiers +QUIL_YYLEXTHROW = %yylexthrow needs a list of (qualified) identifiers +ZERO_STATES = Your scanner has zero states. Very funny. +NO_BUFFER_SIZE = %buffer expects the size of the scanner buffer as decimal number +NOT_READABLE = Could not open file. +FILE_CYCLE = Cyclic file inclusion. +FILE_WRITE = Error writing to file +QUIL_SCANERROR = %scannerror needs a (qualified) identifier +NEVER_MATCH = Rule can never be matched: +QUIL_THROW = %throws needs a list of (qualified) identifiers +EOL_IN_CHARCLASS = Unexpected newline in character class (closing "]" is missing) +QUIL_CUPSYM = %cupsym needs a (qualified) identifier +CUPSYM_AFTER_CUP = %cupsym should be used before %cup +ALREADY_RUNNING = The generator is already running +CANNOT_READ_SKEL = Cannot read skeleton file "{0}". +READING_SKEL = Reading skeleton file "{0}". +SKEL_IO_ERROR = IO problem reading skeleton file. +SKEL_IO_ERROR_DEFAULT = IO problem reading default skeleton file. +READING=Reading "{0}" +CANNOT_OPEN=Sorry, couldn''t find the file "{0}". +NFA_IS=NFA is +NFA_STATES={0} states in NFA +DFA_TOOK=DFA construction took {0} +DFA_IS=DFA is +MIN_TOOK=Minimization took {0} +MIN_DFA_IS=Miniminal DFA is +WRITE_TOOK=Writing took {0} +TOTAL_TIME=Overall scanner generation time: {0} +IO_ERROR=An I/O-Error occured: {0} +THIS_IS_JFLEX=This is JFlex {0} +UNKNOWN_COMMANDLINE=Error: unknown option "{0}". +MACRO_CYCLE=Macro {0} contains a cycle. +MACRO_DEF_MISSING=Found no definition for '{{0}'} while expanding '{{1}'} +PARSING_TOOK=Parsing took {0} +NFA_TOOK=NFA construction took {0} \ No newline at end of file diff --git a/tools/lexer/jflex-1.4/src/JFlex/NFA.java b/tools/lexer/jflex-1.4/src/JFlex/NFA.java new file mode 100644 index 000000000000..219c95249d30 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/NFA.java @@ -0,0 +1,996 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + + +/** + * NFA representation in JFlex. + * + * Contains algorithms RegExp -> NFA and NFA -> DFA. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.8 $, $Date: 2004/11/06 23:03:32 $ + */ +final public class NFA { + + // table[current_state][next_char] is the set of states that can be reached + // from current_state with an input next_char + StateSet [][] table; + + // epsilon[current_state] is the set of states that can be reached + // from current_state via epsilon-edges + StateSet [] epsilon; + + // isFinal[state] == true <=> state is a final state of the NFA + boolean [] isFinal; + + // isPushback[state] == true <=> state is the final state of a regexp that + // should only be matched when followed by a certain lookahead. + boolean [] isPushback; + + // action[current_state]: the action associated with the state + // current_state (null, if there is no action for the state) + Action [] action; + + // the number of states in this NFA + int numStates; + + // the current maximum number of input characters + int numInput; + + // the number of lexical States. Lexical states have the indices + // 0..numLexStates-1 in the transition table + int numLexStates; + + // estimated size of the NFA (before actual construction) + int estSize = 256; + + Macros macros; + CharClasses classes; + + LexScan scanner; + RegExps regExps; + + // will be reused by several methods (avoids excessive object creation) + private static StateSetEnumerator states = new StateSetEnumerator(); + private static StateSet tempStateSet = new StateSet(); + + public NFA(int numInput, int estSize) { + this.numInput = numInput; + this.estSize = estSize; + numStates = 0; + epsilon = new StateSet [estSize]; + action = new Action [estSize]; + isFinal = new boolean [estSize]; + isPushback = new boolean [estSize]; + table = new StateSet [estSize][numInput]; + } + + public NFA(int numInput, LexScan scanner, RegExps regExps, + Macros macros, CharClasses classes) { + this(numInput, regExps.NFASize(macros)+2*scanner.states.number()); + + this.scanner = scanner; + this.regExps = regExps; + this.macros = macros; + this.classes = classes; + + numLexStates = scanner.states.number(); + + ensureCapacity(2*numLexStates); + + numStates = 2*numLexStates; + } + + public void addStandaloneRule() { + // standalone rule has least priority, fires + // transition on all characters and has "print it rule" + int start = numStates; + int end = numStates+1; + + for (int c = 0; c < classes.getNumClasses(); c++) + addTransition(start, c, end); + + for (int i = 0; i < numLexStates*2; i++) + addEpsilonTransition(i, start); + + action[end] = new Action("System.out.print(yytext());", Integer.MAX_VALUE); + isFinal[end] = true; + } + + + public void addRegExp(int regExpNum) { + + if (Options.DEBUG) + Out.debug("Adding nfa for regexp "+regExpNum+" :"+Out.NL+regExps.getRegExp(regExpNum)); + + IntPair nfa = insertNFA( regExps.getRegExp(regExpNum) ); + + Enumeration lexStates = regExps.getStates(regExpNum).elements(); + + if ( !lexStates.hasMoreElements() ) + lexStates = scanner.states.getInclusiveStates(); + + while ( lexStates.hasMoreElements() ) { + int stateNum = ((Integer)lexStates.nextElement()).intValue(); + + if ( !regExps.isBOL(regExpNum) ) + addEpsilonTransition(2*stateNum, nfa.start); + + addEpsilonTransition(2*stateNum+1, nfa.start); + } + + + if ( regExps.getLookAhead(regExpNum) != null ) { + IntPair look = insertNFA( regExps.getLookAhead(regExpNum) ); + + addEpsilonTransition(nfa.end, look.start); + + Action a = regExps.getAction(regExpNum); + a.setLookAction(true); + + isPushback[nfa.end] = true; + action[look.end] = a; + isFinal[look.end] = true; + } + else { + action[nfa.end] = regExps.getAction(regExpNum); + isFinal[nfa.end] = true; + } + } + + + private void ensureCapacity(int newNumStates) { + int oldLength = epsilon.length; + + if ( newNumStates < oldLength ) return; + + int newStatesLength = Math.max(oldLength*2, newNumStates); + + boolean [] newFinal = new boolean [newStatesLength]; + boolean [] newIsPush = new boolean [newStatesLength]; + Action [] newAction = new Action [newStatesLength]; + StateSet [] [] newTable = new StateSet [newStatesLength] [numInput]; + StateSet [] newEpsilon = new StateSet [newStatesLength]; + + System.arraycopy(isFinal,0,newFinal,0,numStates); + System.arraycopy(isPushback,0,newIsPush,0,numStates); + System.arraycopy(action,0,newAction,0,numStates); + System.arraycopy(epsilon,0,newEpsilon,0,numStates); + System.arraycopy(table,0,newTable,0,numStates); + + isFinal = newFinal; + isPushback = newIsPush; + action = newAction; + epsilon = newEpsilon; + table = newTable; + } + + public void addTransition(int start, int input, int dest) { + Out.debug("Adding transition ("+start+", "+input+", "+dest+")"); + + int maxS = Math.max(start,dest)+1; + + ensureCapacity( maxS ); + + if (maxS > numStates) numStates = maxS; + + if ( table[start][input] != null ) + table[start][input].addState(dest); + else + table[start][input] = new StateSet(estSize,dest); + } + + public void addEpsilonTransition(int start, int dest) { + int max = Math.max(start,dest)+1; + ensureCapacity( max ); + if (max > numStates) numStates = max; + + if (epsilon[start] != null) + epsilon[start].addState(dest); + else + epsilon[start] = new StateSet(estSize,dest); + } + + + /** + * Returns true, iff the specified set of states + * contains a final state. + * + * @param set the set of states that is tested for final states. + */ + private boolean containsFinal(StateSet set) { + states.reset(set); + + while ( states.hasMoreElements() ) + if ( isFinal[states.nextElement()] ) return true; + + return false; + } + + + /** + * Returns true, iff the specified set of states + * contains a pushback-state. + * + * @param set the set of states that is tested for pushback-states. + */ + private boolean containsPushback(StateSet set) { + states.reset(set); + + while ( states.hasMoreElements() ) + if ( isPushback[states.nextElement()] ) return true; + + return false; + } + + + /** + * Returns the action with highest priority in the specified + * set of states. + * + * @param set the set of states for which to determine the action + */ + private Action getAction(StateSet set) { + + states.reset(set); + + Action maxAction = null; + + Out.debug("Determining action of : "+set); + + while ( states.hasMoreElements() ) { + + Action currentAction = action[ states.nextElement() ]; + + if ( currentAction != null ) { + if (maxAction == null) + maxAction = currentAction; + else + maxAction = maxAction.getHigherPriority(currentAction); + } + + } + + return maxAction; + } + + + /** + * Calculates the epsilon closure for a specified set of states. + * + * The epsilon closure for set a is the set of states that can be reached + * by epsilon edges from a. + * + * @param set the set of states to calculate the epsilon closure for + * + * @return the epsilon closure of the specified set of states + * in this NFA + */ + private StateSet closure(int startState) { + + // Out.debug("Calculating closure of "+set); + + StateSet notvisited = tempStateSet; + StateSet closure = new StateSet(numStates,startState); + + notvisited.clear(); + notvisited.addState(startState); + + while ( notvisited.containsElements() ) { + // Out.debug("closure is now "+closure); + // Out.debug("notvisited is "+notvisited); + int state = notvisited.getAndRemoveElement(); + // Out.debug("removed element "+state+" of "+notvisited); + // Out.debug("epsilon[states] = "+epsilon[state]); + notvisited.add(closure.complement(epsilon[state])); + closure.add(epsilon[state]); + } + + // Out.debug("Closure is : "+closure); + + return closure; + } + + /** + * Returns the epsilon closure of a set of states + */ + private StateSet closure(StateSet startStates) { + StateSet result = new StateSet(numStates); + + if (startStates != null) { + states.reset(startStates); + while (states.hasMoreElements()) + result.add( closure(states.nextElement()) ); + } + + return result; + } + + + private void epsilonFill() { + for (int i = 0; i < numStates; i++) { + epsilon[i] = closure(i); + } + } + + /** + * Calculates the set of states that can be reached from another + * set of states start with an specified input + * character input + * + * @param start the set of states to start from + * @param input the input character for which to search the next states + * + * @return the set of states that are reached from start + * via input + */ + private StateSet DFAEdge(StateSet start, char input) { + // Out.debug("Calculating DFAEdge for state set "+start+" and input '"+input+"'"); + + tempStateSet.clear(); + + states.reset(start); + while ( states.hasMoreElements() ) + tempStateSet.add( table[states.nextElement()][input] ); + + StateSet result = new StateSet(tempStateSet); + + states.reset(tempStateSet); + while ( states.hasMoreElements() ) + result.add( epsilon[states.nextElement()] ); + + // Out.debug("DFAEdge is : "+result); + + return result; + } + + + /** + * Returns an DFA that accepts the same language as this NFA. + * This DFA is usualy not minimal. + */ + public DFA getDFA() { + + Hashtable dfaStates = new Hashtable(numStates); + Vector dfaVector = new Vector(numStates); + + DFA dfa = new DFA(2*numLexStates, numInput); + + int numDFAStates = 0; + int currentDFAState = 0; + + Out.println("Converting NFA to DFA : "); + + epsilonFill(); + + StateSet currentState, newState; + + for ( int i = 0; i < 2*numLexStates; i++ ) { + newState = epsilon[i]; + + dfaStates.put(newState, new Integer(numDFAStates)); + dfaVector.addElement(newState); + + dfa.setLexState( i, numDFAStates ); + + dfa.setFinal( numDFAStates, containsFinal(newState) ); + dfa.setPushback( numDFAStates, containsPushback(newState) ); + dfa.setAction( numDFAStates, getAction(newState) ); + + numDFAStates++; + } + + numDFAStates--; + + if (Options.DEBUG) + Out.debug("DFA start states are :"+Out.NL+dfaStates+Out.NL+Out.NL+"ordered :"+Out.NL+dfaVector); + + currentDFAState = 0; + + StateSet tempStateSet = NFA.tempStateSet; + StateSetEnumerator states = NFA.states; + + // will be reused + newState = new StateSet(numStates); + + while ( currentDFAState <= numDFAStates ) { + + currentState = (StateSet) dfaVector.elementAt(currentDFAState); + + for (char input = 0; input < numInput; input++) { + + // newState = DFAEdge(currentState, input); + + // inlining DFAEdge for performance: + + // Out.debug("Calculating DFAEdge for state set "+currentState+" and input '"+input+"'"); + + tempStateSet.clear(); + states.reset(currentState); + while ( states.hasMoreElements() ) + tempStateSet.add( table[states.nextElement()][input] ); + + newState.copy(tempStateSet); + + states.reset(tempStateSet); + while ( states.hasMoreElements() ) + newState.add( epsilon[states.nextElement()] ); + + // Out.debug("DFAEdge is : "+newState); + + + if ( newState.containsElements() ) { + + // Out.debug("DFAEdge for input "+(int)input+" and state set "+currentState+" is "+newState); + + // Out.debug("Looking for state set "+newState); + Integer nextDFAState = (Integer) dfaStates.get(newState); + + if ( nextDFAState != null ) { + // Out.debug("FOUND!"); + dfa.addTransition(currentDFAState, input, nextDFAState.intValue()); + } + else { + if (Options.progress) Out.print("."); + // Out.debug("NOT FOUND!"); + // Out.debug("Table was "+dfaStates); + numDFAStates++; + + // make a new copy of newState to store in dfaStates + StateSet storeState = new StateSet(newState); + + dfaStates.put(storeState, new Integer(numDFAStates)); + dfaVector.addElement(storeState); + + dfa.addTransition(currentDFAState, input, numDFAStates); + dfa.setFinal( numDFAStates, containsFinal(storeState) ); + dfa.setPushback( numDFAStates, containsPushback(storeState) ); + dfa.setAction( numDFAStates, getAction(storeState) ); + } + } + } + + currentDFAState++; + } + + if (Options.verbose) Out.println(""); + + return dfa; + } + + + public void dumpTable() { + Out.dump(toString()); + } + + public String toString() { + StringBuffer result = new StringBuffer(); + + for (int i=0; i < numStates; i++) { + result.append("State"); + if ( isFinal[i] ) result.append("[FINAL]"); + if ( isPushback[i] ) result.append(" [PUSHBACK]"); + result.append(" "+i+Out.NL); + + for (char input = 0; input < numInput; input++) { + if ( table[i][input] != null && table[i][input].containsElements() ) + result.append(" with "+((int) input)+" in "+table[i][input]+Out.NL); + + + } + + if ( epsilon[i] != null && epsilon[i].containsElements() ) + result.append(" with epsilon in "+epsilon[i]+Out.NL); + } + + return result.toString(); + } + + public void writeDot(File file) { + try { + PrintWriter writer = new PrintWriter(new FileWriter(file)); + writer.println(dotFormat()); + writer.close(); + } + catch (IOException e) { + Out.error(ErrorMessages.FILE_WRITE, file); + throw new GeneratorException(); + } + } + + public String dotFormat() { + StringBuffer result = new StringBuffer(); + + result.append("digraph NFA {"+Out.NL); + result.append("rankdir = LR"+Out.NL); + + for (int i=0; i < numStates; i++) { + if ( isFinal[i] || isPushback[i] ) result.append(i); + if ( isFinal[i] ) result.append(" [shape = doublecircle]"); + if ( isPushback[i] ) result.append(" [shape = box]"); + if ( isFinal[i] || isPushback[i] ) result.append(Out.NL); + } + + for (int i=0; i < numStates; i++) { + for (int input = 0; input < numInput; input++) { + if ( table[i][input] != null ) { + StateSetEnumerator states = table[i][input].states(); + + while (states.hasMoreElements()) { + int s = states.nextElement(); + result.append(i+" -> "+s); + result.append(" [label=\""+classes.toString(input)+"\"]"+Out.NL); + } + } + } + if ( epsilon[i] != null ) { + StateSetEnumerator states = epsilon[i].states(); + while (states.hasMoreElements()) { + int s = states.nextElement(); + result.append(i+" -> "+s+" [style=dotted]"+Out.NL); + } + } + } + + result.append("}"+Out.NL); + + return result.toString(); + } + + + //----------------------------------------------------------------------- + // Functions for constructing NFAs out of regular expressions. + + private void insertLetterNFA(boolean caseless, char letter, int start, int end) { + if (caseless) { + int lower = classes.getClassCode(Character.toLowerCase(letter)); + int upper = classes.getClassCode(Character.toUpperCase(letter)); + addTransition(start, lower, end); + if (upper != lower) addTransition(start, upper, end); + } + else { + addTransition(start, classes.getClassCode(letter), end); + } + } + + private IntPair insertStringNFA(boolean caseless, String letters) { + int start = numStates; + int i; + + for (i = 0; i < letters.length(); i++) { + if (caseless) { + char c = letters.charAt(i); + int lower = classes.getClassCode(Character.toLowerCase(c)); + int upper = classes.getClassCode(Character.toUpperCase(c)); + addTransition(i+start, lower, i+start+1); + if (upper != lower) addTransition(i+start, upper, i+start+1); + } + else { + addTransition(i+start, classes.getClassCode(letters.charAt(i)), i+start+1); + } + } + + return new IntPair(start, i+start); + } + + + private void insertClassNFA(Vector intervalls, int start, int end) { + // empty char class is ok: + if (intervalls == null) return; + + int [] cl = classes.getClassCodes(intervalls); + for (int i = 0; i < cl.length; i++) + addTransition(start, cl[i], end); + } + + private void insertNotClassNFA(Vector intervalls, int start, int end) { + int [] cl = classes.getNotClassCodes(intervalls); + + for (int i = 0; i < cl.length; i++) + addTransition(start, cl[i], end); + } + + + /** + * Constructs an NFA accepting the complement of the language + * of a given NFA. + * + * Converts the NFA into a DFA, then negates that DFA. + * Exponential state blowup possible and common. + * + * @param the NFA to construct the complement for. + * + * @return a pair of integers denoting the index of start + * and end state of the complement NFA. + */ + private IntPair complement(IntPair nfa) { + + if (Options.DEBUG) { + Out.debug("complement for "+nfa); + Out.debug("NFA is :"+Out.NL+this); + } + + int dfaStart = nfa.end+1; + + // fixme: only need epsilon closure of states reachable from nfa.start + epsilonFill(); + + Hashtable dfaStates = new Hashtable(numStates); + Vector dfaVector = new Vector(numStates); + + int numDFAStates = 0; + int currentDFAState = 0; + + StateSet currentState, newState; + + newState = epsilon[nfa.start]; + dfaStates.put(newState, new Integer(numDFAStates)); + dfaVector.addElement(newState); + + if (Options.DEBUG) + Out.debug("pos DFA start state is :"+Out.NL+dfaStates+Out.NL+Out.NL+"ordered :"+Out.NL+dfaVector); + + currentDFAState = 0; + + while ( currentDFAState <= numDFAStates ) { + + currentState = (StateSet) dfaVector.elementAt(currentDFAState); + + for (char input = 0; input < numInput; input++) { + newState = DFAEdge(currentState, input); + + if ( newState.containsElements() ) { + + // Out.debug("DFAEdge for input "+(int)input+" and state set "+currentState+" is "+newState); + + // Out.debug("Looking for state set "+newState); + Integer nextDFAState = (Integer) dfaStates.get(newState); + + if ( nextDFAState != null ) { + // Out.debug("FOUND!"); + addTransition(dfaStart+currentDFAState, input, dfaStart+nextDFAState.intValue()); + } + else { + if (Options.dump) Out.print("+"); + // Out.debug("NOT FOUND!"); + // Out.debug("Table was "+dfaStates); + numDFAStates++; + + dfaStates.put(newState, new Integer(numDFAStates)); + dfaVector.addElement(newState); + + addTransition(dfaStart+currentDFAState, input, dfaStart+numDFAStates); + } + } + } + + currentDFAState++; + } + + // We have a dfa accepting the positive regexp. + + // Now the complement: + if (Options.DEBUG) + Out.debug("dfa finished, nfa is now :"+Out.NL+this); + + int start = dfaStart+numDFAStates+1; + int error = dfaStart+numDFAStates+2; + int end = dfaStart+numDFAStates+3; + + addEpsilonTransition(start, dfaStart); + + for (int i = 0; i < numInput; i++) + addTransition(error, i, error); + + addEpsilonTransition(error, end); + + for (int s = 0; s <= numDFAStates; s++) { + currentState = (StateSet) dfaVector.elementAt(s); + + currentDFAState = dfaStart+s; + + // if it was not a final state, it is now in the complement + if (!currentState.isElement(nfa.end)) + addEpsilonTransition(currentDFAState, end); + + // all inputs not present (formerly leading to an implicit error) + // now lead to an explicit (final) state accepting everything. + for (int i = 0; i < numInput; i++) + if (table[currentDFAState][i] == null) + addTransition(currentDFAState, i, error); + } + + // eliminate transitions leading to dead states + if (live == null || live.length < numStates) { + live = new boolean [2*numStates]; + visited = new boolean [2*numStates]; + } + + _end = end; + _dfaStates = dfaVector; + _dfaStart = dfaStart; + removeDead(dfaStart); + + if (Options.DEBUG) + Out.debug("complement finished, nfa ("+start+","+end+") is now :"+this); + + return new IntPair(start, end); + } + + // "global" data for use in method removeDead only: + // live[s] == false <=> no final state can be reached from s + private boolean [] live; // = new boolean [estSize]; + private boolean [] visited; // = new boolean [estSize]; + private int _end; // final state of original nfa for dfa (nfa coordinates) + private Vector _dfaStates; + private int _dfaStart; // in nfa coordinates + + private void removeDead(int start) { + // Out.debug("removeDead ("+start+")"); + + if ( visited[start] || live[start] ) return; + visited[start] = true; + + // Out.debug("not yet visited"); + + if (closure(start).isElement(_end)) + live[start] = true; + + // Out.debug("is final :"+live[start]); + + for (int i = 0; i < numInput; i++) { + StateSet nextState = closure(table[start][i]); + StateSetEnumerator states = nextState.states(); + while (states.hasMoreElements()) { + int next = states.nextElement(); + + if (next != start) { + removeDead(next); + + if (live[next]) + live[start] = true; + else + table[start][i] = null; + } + } + } + + StateSet nextState = closure(epsilon[start]); + StateSetEnumerator states = nextState.states(); + while (states.hasMoreElements()) { + int next = states.nextElement(); + + if (next != start) { + removeDead(next); + + if (live[next]) + live[start] = true; + } + } + + // Out.debug("state "+start+" is live :"+live[start]); + } + + + /** + * Constructs a two state NFA for char class regexps, + * such that the NFA has + * + * exactly one start state, + * exactly one end state, + * no transitions leading out of the end state + * no transitions leading into the start state + * + * Assumes that regExp.isCharClass(macros) == true + * + * @param regExp the regular expression to construct the + * NFA for + * + * @return a pair of integers denoting the index of start + * and end state of the NFA. + */ + private void insertNFA(RegExp regExp, int start, int end) { + switch (regExp.type) { + + case sym.BAR: + RegExp2 r = (RegExp2) regExp; + insertNFA(r.r1, start, end); + insertNFA(r.r2, start, end); + return; + + case sym.CCLASS: + insertClassNFA( (Vector) ((RegExp1) regExp).content, start, end); + return; + + case sym.CCLASSNOT: + insertNotClassNFA( (Vector) ((RegExp1) regExp).content, start, end); + return; + + case sym.CHAR: + insertLetterNFA( + false, ((Character) ((RegExp1) regExp).content).charValue(), + start, end); + return; + + case sym.CHAR_I: + insertLetterNFA( + true, ((Character) ((RegExp1) regExp).content).charValue(), + start, end); + return; + + case sym.MACROUSE: + insertNFA(macros.getDefinition((String) ((RegExp1) regExp).content), + start, end); + return; + } + + throw new Error("Unknown expression type "+regExp.type+" in NFA construction"); + } + + + /** + * Constructs an NFA for regExp such that the NFA has + * + * exactly one start state, + * exactly one end state, + * no transitions leading out of the end state + * no transitions leading into the start state + * + * @param regExp the regular expression to construct the + * NFA for + * + * @return a pair of integers denoting the index of start + * and end state of the NFA. + */ + public IntPair insertNFA(RegExp regExp) { + + IntPair nfa1, nfa2; + int start, end; + RegExp2 r; + + if (Options.DEBUG) + Out.debug("Inserting RegExp : "+regExp); + + if (regExp.isCharClass(macros)) { + start = numStates; + end = numStates+1; + + ensureCapacity(end+1); + if (end+1 > numStates) numStates = end+1; + + insertNFA(regExp, start, end); + + return new IntPair(start, end); + } + + switch (regExp.type) { + + case sym.BAR: + + r = (RegExp2) regExp; + + nfa1 = insertNFA(r.r1); + nfa2 = insertNFA(r.r2); + + start = nfa2.end+1; + end = nfa2.end+2; + + addEpsilonTransition(start, nfa1.start); + addEpsilonTransition(start, nfa2.start); + addEpsilonTransition(nfa1.end, end); + addEpsilonTransition(nfa2.end, end); + + return new IntPair(start, end); + + case sym.CONCAT: + + r = (RegExp2) regExp; + + nfa1 = insertNFA(r.r1); + nfa2 = insertNFA(r.r2); + + addEpsilonTransition(nfa1.end, nfa2.start); + + return new IntPair(nfa1.start, nfa2.end); + + case sym.STAR: + nfa1 = insertNFA( (RegExp) ((RegExp1) regExp).content ); + + start = nfa1.end+1; + end = nfa1.end+2; + + addEpsilonTransition(nfa1.end, end); + addEpsilonTransition(start, nfa1.start); + + addEpsilonTransition(start, end); + addEpsilonTransition(nfa1.end, nfa1.start); + + return new IntPair(start, end); + + case sym.PLUS: + nfa1 = insertNFA( (RegExp) ((RegExp1) regExp).content ); + + start = nfa1.end+1; + end = nfa1.end+2; + + addEpsilonTransition(nfa1.end, end); + addEpsilonTransition(start, nfa1.start); + + addEpsilonTransition(nfa1.end, nfa1.start); + + return new IntPair(start, end); + + case sym.QUESTION: + nfa1 = insertNFA( (RegExp) ((RegExp1) regExp).content ); + + addEpsilonTransition(nfa1.start, nfa1.end); + + return new IntPair(nfa1.start, nfa1.end); + + case sym.BANG: + return complement(insertNFA((RegExp) ((RegExp1) regExp).content)); + + case sym.TILDE: + nfa1 = insertNFA((RegExp) ((RegExp1) regExp).content); + + start = nfa1.end+1; + int s1 = start+1; + int s2 = s1+1; + end = s2+1; + + for (int i = 0; i < numInput; i++) { + addTransition(s1,i,s1); + addTransition(s2,i,s2); + } + + addEpsilonTransition(start, s1); + addEpsilonTransition(s1, nfa1.start); + addEpsilonTransition(nfa1.end, s2); + addEpsilonTransition(s2, end); + + nfa1 = complement(new IntPair(start,end)); + nfa2 = insertNFA((RegExp) ((RegExp1) regExp).content); + + addEpsilonTransition(nfa1.end, nfa2.start); + + return new IntPair(nfa1.start, nfa2.end); + + case sym.STRING: + return insertStringNFA(false, (String) ((RegExp1) regExp).content ); + + case sym.STRING_I: + return insertStringNFA(true, (String) ((RegExp1) regExp).content ); + + case sym.MACROUSE: + return insertNFA(macros.getDefinition((String) ((RegExp1) regExp).content)); + } + + throw new Error("Unknown expression type "+regExp.type+" in NFA construction"); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Options.java b/tools/lexer/jflex-1.4/src/JFlex/Options.java new file mode 100644 index 000000000000..fa308bb50eb2 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Options.java @@ -0,0 +1,131 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.io.File; + +/** + * Collects all global JFlex options. Can be set from command line parser, + * ant taks, gui, etc. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.10 $, $Date: 2004/11/06 23:03:31 $ + */ +public class Options { + + /** If true, additional verbose debug information is produced + * This is a compile time option */ + public final static boolean DEBUG = false; + + /** code generation method: maximum packing */ + final public static int PACK = 0; + /** code generation method: traditional */ + final public static int TABLE = 1; + /** code generation method: switch statement */ + final public static int SWITCH = 2; + + + /** output directory */ + private static File directory; + /** strict JLex compatibility */ + public static boolean jlex; + /** don't run minimization algorithm if this is true */ + public static boolean no_minimize; + /** don't write backup files if this is true */ + public static boolean no_backup; + /** use charAt function for accessing the zzBuffer */ + public static boolean char_at; + + /** use charAt function for accessing the zzBuffer and [] for zzBufferArray */ + public static boolean sliceAndCharAt; + + /** default code generation method */ + public static int gen_method; + /** If false, only error/warning output will be generated */ + public static boolean verbose; + /** If true, progress dots will be printed */ + public static boolean progress; + /** If true, jflex will print time statistics about the generation process */ + public static boolean time; + /** If true, jflex will write graphviz .dot files for generated automata */ + public static boolean dot; + /** If true, you will be flooded with information (e.g. dfa tables). */ + public static boolean dump; + + static { setDefaults(); } + + + /** + * @return the output directory + */ + public static File getDir() { + return directory; + } + + /** + * Set output directory + * + * @param dirName the name of the directory to write output files to + */ + public static void setDir(String dirName) { + setDir(new File(dirName)); + } + + + /** + * Set output directory + * + * @param d the directory to write output files to + */ + public static void setDir(File d) { + if ( d.isFile() ) { + Out.error("Error: \""+d+"\" is not a directory."); + throw new GeneratorException(); + } + + if ( !d.isDirectory() && !d.mkdirs() ) { + Out.error("Error: couldn't create directory \""+d+"\""); + throw new GeneratorException(); + } + + directory = d; + } + + /** + * Sets all options back to default values. + */ + public static void setDefaults() { + directory = null; + jlex = false; + no_minimize = false; + no_backup = false; + gen_method = Options.PACK; + verbose = true; + progress = true; + time = false; + dot = false; + dump = false; + } + + public static void setSkeleton(File skel) { + Skeleton.readSkelFile(skel); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Out.java b/tools/lexer/jflex-1.4/src/JFlex/Out.java new file mode 100644 index 000000000000..026187fc1e34 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Out.java @@ -0,0 +1,461 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +import java.awt.*; +import java.io.*; + + +/** + * In this class all output to the java console is filtered. + * + * Use the switches verbose, time and DUMP at compile time to determine + * the verbosity of JFlex output. There is no switch for + * suppressing error messages. verbose and time can be overridden + * by command line paramters. + * + * Redirects output to a TextArea in GUI mode. + * + * Counts error and warning messages. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.9 $, $Date: 2004/11/06 23:03:30 $ + */ +public final class Out { + + /** platform dependent newline sequence */ + public static final String NL = System.getProperty("line.separator"); + + /** count total warnings */ + private static int warnings; + + /** count total errors */ + private static int errors; + + /** output device */ + private static StdOutWriter out = new StdOutWriter(); + + + /** + * Switches to GUI mode if text is not null + * + * @param text the message TextArea of the JFlex GUI + */ + public static void setGUIMode(TextArea text) { + out.setGUIMode(text); + } + + /** + * Sets a new output stream and switches to non-gui mode. + * + * @param stream the new output stream + */ + public static void setOutputStream(OutputStream stream) { + out = new StdOutWriter(stream); + out.setGUIMode(null); + } + + /** + * Report time statistic data. + * + * @param message the message to be printed + * @param time elapsed time + */ + public static void time(ErrorMessages message, Timer time) { + if (Options.time) { + String msg = ErrorMessages.get(message, time.toString()); + out.println(msg); + } + } + + /** + * Report time statistic data. + * + * @param message the message to be printed + */ + public static void time(String message) { + if (Options.time) { + out.println(message); + } + } + + /** + * Report generation progress. + * + * @param message the message to be printed + */ + public static void println(String message) { + if (Options.verbose) + out.println(message); + } + + /** + * Report generation progress. + * + * @param message the message to be printed + * @param data data to be inserted into the message + */ + public static void println(ErrorMessages message, String data) { + if (Options.verbose) { + out.println(ErrorMessages.get(message,data)); + } + } + + /** + * Report generation progress. + * + * @param message the message to be printed + * @param data data to be inserted into the message + */ + public static void println(ErrorMessages message, int data) { + if (Options.verbose) { + out.println(ErrorMessages.get(message,data)); + } + } + + /** + * Report generation progress. + * + * @param message the message to be printed + */ + public static void print(String message) { + if (Options.verbose) out.print(message); + } + + /** + * Dump debug information to System.out + * + * Use like this + * + * if (Out.DEBUG) Out.debug(message) + * + * to save performance during normal operation (when DEBUG + * is turned off). + */ + public static void debug(String message) { + if (Options.DEBUG) System.out.println(message); + } + + + /** + * All parts of JFlex, that want to provide dump information + * should use this method for their output. + * + * @message the message to be printed + */ + public static void dump(String message) { + if (Options.dump) out.println(message); + } + + + /** + * All parts of JFlex, that want to report error messages + * should use this method for their output. + * + * @message the message to be printed + */ + private static void err(String message) { + out.println(message); + } + + + /** + * throws a GeneratorException if there are any errors recorded + */ + public static void checkErrors() { + if (errors > 0) throw new GeneratorException(); + } + + + /** + * print error and warning statistics + */ + public static void statistics() { + StringBuffer line = new StringBuffer(errors+" error"); + if (errors != 1) line.append("s"); + + line.append(", "+warnings+" warning"); + if (warnings != 1) line.append("s"); + + line.append("."); + err(line.toString()); + } + + + /** + * reset error and warning counters + */ + public static void resetCounters() { + errors = 0; + warnings = 0; + } + + + /** + * print a warning without position information + * + * @param message the warning message + */ + public static void warning(String message) { + warnings++; + + err(NL+"Warning : "+message); + } + + + /** + * print a warning with line information + * + * @param message code of the warning message + * @param line the line information + * + * @see ErrorMessages + */ + public static void warning(ErrorMessages message, int line) { + warnings++; + + String msg = NL+"Warning"; + if (line > 0) msg = msg+" in line "+(line+1); + + err(msg+": "+ErrorMessages.get(message)); + } + + + /** + * print warning message with location information + * + * @param file the file the warning is issued for + * @param message the code of the message to print + * @param line the line number of the position + * @param column the column of the position + */ + public static void warning(File file, ErrorMessages message, int line, int column) { + + String msg = NL+"Warning"; + if (file != null) msg += " in file \""+file+"\""; + if (line >= 0) msg = msg+" (line "+(line+1)+")"; + + try { + err(msg+": "+NL+ErrorMessages.get(message)); + } + catch (ArrayIndexOutOfBoundsException e) { + err(msg); + } + + warnings++; + + if (line >= 0) { + if (column >= 0) + showPosition(file, line, column); + else + showPosition(file, line); + } + } + + + /** + * print error message (string) + * + * @param message the message to print + */ + public static void error(String message) { + errors++; + err(NL+message); + } + + + /** + * print error message (code) + * + * @param message the code of the error message + * + * @see ErrorMessages + */ + public static void error(ErrorMessages message) { + errors++; + err(NL+"Error: "+ErrorMessages.get(message) ); + } + + + /** + * print error message with data + * + * @param data data to insert into the message + * @param message the code of the error message + * + * @see ErrorMessages + */ + public static void error(ErrorMessages message, String data) { + errors++; + err(NL+"Error: "+ ErrorMessages.get(message,data)); + } + + + /** + * IO error message for a file (displays file + * name in parentheses). + * + * @param message the code of the error message + * @param file the file it occurred for + */ + public static void error(ErrorMessages message, File file) { + errors++; + err(NL+"Error: "+ErrorMessages.get(message)+" ("+file+")"); + } + + + /** + * print error message with location information + * + * @param file the file the error occurred for + * @param message the code of the error message to print + * @param line the line number of error position + * @param column the column of error position + */ + public static void error(File file, ErrorMessages message, int line, int column) { + + String msg = NL+"Error"; + if (file != null) msg += " in file \""+file+"\""; + if (line >= 0) msg = msg+" (line "+(line+1)+")"; + + try { + err(msg+": "+NL+ErrorMessages.get(message)); + } + catch (ArrayIndexOutOfBoundsException e) { + err(msg); + } + + errors++; + + if (line >= 0) { + if (column >= 0) + showPosition(file, line, column); + else + showPosition(file, line); + } + } + + + /** + * prints a line of a file with marked position. + * + * @param file the file of which to show the line + * @param line the line to show + * @param column the column in which to show the marker + */ + public static void showPosition(File file, int line, int column) { + try { + String ln = getLine(file, line); + if (ln != null) { + err( ln ); + + if (column < 0) return; + + String t = "^"; + for (int i = 0; i < column; i++) t = " "+t; + + err(t); + } + } + catch (IOException e) { + /* silently ignore IO errors, don't show anything */ + } + } + + + /** + * print a line of a file + * + * @param file the file to show + * @param line the line number + */ + public static void showPosition(File file, int line) { + try { + String ln = getLine(file, line); + if (ln != null) err(ln); + } + catch (IOException e) { + /* silently ignore IO errors, don't show anything */ + } + } + + + /** + * get one line from a file + * + * @param file the file to read + * @param line the line number to get + * + * @throw IOException if any error occurs + */ + private static String getLine(File file, int line) throws IOException { + BufferedReader reader = new BufferedReader(new FileReader(file)); + + String msg = ""; + + for (int i = 0; i <= line; i++) + msg = reader.readLine(); + + reader.close(); + + return msg; + } + + + /** + * Print system information (e.g. in case of unexpected exceptions) + */ + public static void printSystemInfo() { + err("Java version: "+System.getProperty("java.version")); + err("Runtime name: "+System.getProperty("java.runtime.name")); + err("Vendor: "+System.getProperty("java.vendor")); + err("VM version: "+System.getProperty("java.vm.version")); + err("VM vendor: "+System.getProperty("java.vm.vendor")); + err("VM name: "+System.getProperty("java.vm.name")); + err("VM info: "+System.getProperty("java.vm.info")); + err("OS name: "+System.getProperty("os.name")); + err("OS arch: "+System.getProperty("os.arch")); + err("OS version: "+System.getProperty("os.version")); + err("Encoding: "+System.getProperty("file.encoding")); + err("JFlex version: "+Main.version); + } + + + /** + * Request a bug report for an unexpected Exception/Error. + */ + public static void requestBugReport(Error e) { + err("An unexpected error occurred. Please send a report of this to"); + err(" and include the following information:"); + err(""); + printSystemInfo(); + err("Exception:"); + e.printStackTrace(out); + err(""); + err("Please also include a specification (as small as possible)"); + err("that triggers this error. You may also want to check at"); + err("http://www.jflex.de if there is a newer version available"); + err("that doesn't have this problem"); + err(""); + err("Thanks for your support."); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/PackEmitter.java b/tools/lexer/jflex-1.4/src/JFlex/PackEmitter.java new file mode 100644 index 000000000000..1e98b327f343 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/PackEmitter.java @@ -0,0 +1,230 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * jflex 1.4 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Encodes int arrays as strings. + * + * Also splits up strings when longer than 64K in UTF8 encoding. + * Subclasses emit unpacking code. + * + * Usage protocol: + * p.emitInit();
+ * for each data: p.emitData(data);
+ * p.emitUnpack(); + * + * @author Gerwin Klein + * @version $Revision: 1.6 $, $Date: 2004/04/12 10:07:47 $ + */ +public abstract class PackEmitter { + + /** name of the generated array (mixed case, no yy prefix) */ + protected String name; + + /** current UTF8 length of generated string in current chunk */ + private int UTF8Length; + + /** position in the current line */ + private int linepos; + + /** max number of entries per line */ + private static final int maxEntries = 16; + + /** output buffer */ + protected StringBuffer out = new StringBuffer(); + + /** number of existing string chunks */ + protected int chunks; + + /** maximum size of chunks */ + // String constants are stored as UTF8 with 2 bytes length + // field in class files. One Unicode char can be up to 3 + // UTF8 bytes. 64K max and two chars safety. + private static final int maxSize = 0xFFFF-6; + + /** indent for string lines */ + private static final String indent = " "; + + /** + * Create new emitter for an array. + * + * @param name the name of the generated array + */ + public PackEmitter(String name) { + this.name = name; + } + + /** + * Convert array name into all uppercase internal scanner + * constant name. + * + * @return name as a internal constant name. + * @see PackEmitter#name + */ + protected String constName() { + return "ZZ_" + name.toUpperCase(); + } + + /** + * Return current output buffer. + */ + public String toString() { + return out.toString(); + } + + /** + * Emit declaration of decoded member and open first chunk. + */ + public void emitInit() { + out.append(" private static final int [] "); + out.append(constName()); + out.append(" = zzUnpack"); + out.append(name); + out.append("();"); + nl(); + nextChunk(); + } + + /** + * Emit single unicode character. + * + * Updates length, position, etc. + * + * @param i the character to emit. + * @prec 0 <= i <= 0xFFFF + */ + public void emitUC(int i) { + if (i < 0 || i > 0xFFFF) + throw new IllegalArgumentException("character value expected"); + + // cast ok because of prec + char c = (char) i; + + printUC(c); + UTF8Length += UTF8Length(c); + linepos++; + } + + /** + * Execute line/chunk break if necessary. + * Leave space for at least two chars. + */ + public void breaks() { + if (UTF8Length >= maxSize) { + // close current chunk + out.append("\";"); + nl(); + + nextChunk(); + } + else { + if (linepos >= maxEntries) { + // line break + out.append("\"+"); + nl(); + out.append(indent); + out.append("\""); + linepos = 0; + } + } + } + + /** + * Emit the unpacking code. + */ + public abstract void emitUnpack(); + + /** + * emit next chunk + */ + private void nextChunk() { + nl(); + out.append(" private static final String "); + out.append(constName()); + out.append("_PACKED_"); + out.append(chunks); + out.append(" ="); + nl(); + out.append(indent); + out.append("\""); + + UTF8Length = 0; + linepos = 0; + chunks++; + } + + /** + * emit newline + */ + protected void nl() { + out.append(Out.NL); + } + + /** + * Append a unicode/octal escaped character + * to out buffer. + * + * @param c the character to append + */ + private void printUC(char c) { + if (c > 255) { + out.append("\\u"); + if (c < 0x1000) out.append("0"); + out.append(Integer.toHexString(c)); + } + else { + out.append("\\"); + out.append(Integer.toOctalString(c)); + } + } + + /** + * Calculates the number of bytes a Unicode character + * would have in UTF8 representation in a class file. + * + * @param value the char code of the Unicode character + * @prec 0 <= value <= 0xFFFF + * + * @return length of UTF8 representation. + */ + private int UTF8Length(char value) { + // if (value < 0 || value > 0xFFFF) throw new Error("not a char value ("+value+")"); + + // see JVM spec §4.4.7, p 111 + if (value == 0) return 2; + if (value <= 0x7F) return 1; + + // workaround for javac bug (up to jdk 1.3): + if (value < 0x0400) return 2; + if (value <= 0x07FF) return 3; + + // correct would be: + // if (value <= 0x7FF) return 2; + return 3; + } + + // convenience + protected void println(String s) { + out.append(s); + nl(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/RegExp.java b/tools/lexer/jflex-1.4/src/JFlex/RegExp.java new file mode 100644 index 000000000000..e171b180d092 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/RegExp.java @@ -0,0 +1,172 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Stores a regular expression of rules section in a JFlex-specification. + * + * This base class has no content other than its type. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:32 $ + */ +public class RegExp { + + /** + * The type of the regular expression. This field will be + * filled with values from class sym.java (generated by cup) + */ + int type; + + + /** + * Create a new regular expression of the specified type. + * + * @param type a value from the cup generated class sym. + * + * @see JFlex.sym + */ + public RegExp(int type) { + this.type = type; + } + + + + /** + * Returns a String-representation of this regular expression + * with the specified indentation. + * + * @param tab a String that should contain only space characters and + * that is inserted in front of standard String-representation + * pf this object. + */ + public String print(String tab) { + return tab+toString(); + } + + + /** + * Returns a String-representation of this regular expression + */ + public String toString() { + return "type = "+type; + } + + + /** + * Find out if this regexp is a char class or equivalent to one. + * + * @param macros for macro expansion + * @return true if the regexp is equivalent to a char class. + */ + public boolean isCharClass(Macros macros) { + RegExp1 unary; + RegExp2 binary; + + switch (type) { + case sym.CHAR: + case sym.CHAR_I: + case sym.CCLASS: + case sym.CCLASSNOT: + return true; + + case sym.BAR: + binary = (RegExp2) this; + return binary.r1.isCharClass(macros) && binary.r2.isCharClass(macros); + + case sym.MACROUSE: + unary = (RegExp1) this; + return macros.getDefinition((String) unary.content).isCharClass(macros); + + default: return false; + } + } + + /** + * The approximate number of NFA states this expression will need (only + * works correctly after macro expansion and without negation) + * + * @param macros macro table for expansion + */ + public int size(Macros macros) { + RegExp1 unary; + RegExp2 binary; + RegExp content; + + switch ( type ) { + case sym.BAR: + binary = (RegExp2) this; + return binary.r1.size(macros) + binary.r2.size(macros) + 2; + + case sym.CONCAT: + binary = (RegExp2) this; + return binary.r1.size(macros) + binary.r2.size(macros); + + case sym.STAR: + unary = (RegExp1) this; + content = (RegExp) unary.content; + return content.size(macros) + 2; + + case sym.PLUS: + unary = (RegExp1) this; + content = (RegExp) unary.content; + return content.size(macros) + 2; + + case sym.QUESTION: + unary = (RegExp1) this; + content = (RegExp) unary.content; + return content.size(macros); + + case sym.BANG: + unary = (RegExp1) this; + content = (RegExp) unary.content; + return content.size(macros) * content.size(macros); + // this is only a very rough estimate (worst case 2^n) + // exact size too complicated (propably requires construction) + + case sym.TILDE: + unary = (RegExp1) this; + content = (RegExp) unary.content; + return content.size(macros) * content.size(macros) * 3; + // see sym.BANG + + case sym.STRING: + case sym.STRING_I: + unary = (RegExp1) this; + return ((String) unary.content).length()+1; + + case sym.CHAR: + case sym.CHAR_I: + return 2; + + case sym.CCLASS: + case sym.CCLASSNOT: + return 2; + + case sym.MACROUSE: + unary = (RegExp1) this; + return macros.getDefinition((String) unary.content).size(macros); + } + + throw new Error("unknown regexp type "+type); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/RegExp1.java b/tools/lexer/jflex-1.4/src/JFlex/RegExp1.java new file mode 100644 index 000000000000..fb83ba9c8c55 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/RegExp1.java @@ -0,0 +1,80 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Stores a regular expression from the rules section of a JFlex specification. + * + * This class provides storage for one Object of content. + * It is used for all regular expressions that are constructed from one object. + * + * For instance: a* is new RegExp1(sym.STAR, new Character ('a')); + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $ + */ +public class RegExp1 extends RegExp { + + /** + * The child of this expression node in the syntax tree of a regular expression. + */ + Object content; + + + /** + * Constructs a new regular expression with one child object. + * + * @param type a value from the cup generated class sym, defining the + * kind of this regular expression + * + * @param content the child of this expression + */ + public RegExp1(int type, Object content) { + super(type); + this.content = content; + } + + + /** + * Returns a String-representation of this regular expression + * with the specified indentation. + * + * @param tab a String that should contain only space characters and + * that is inserted in front of standard String-representation + * pf this object. + */ + public String print(String tab) { + if (content instanceof RegExp) { + return tab+"type = "+type+Out.NL+tab+"content :"+Out.NL+((RegExp)content).print(tab+" "); + } + else + return tab+"type = "+type+Out.NL+tab+"content :"+Out.NL+tab+" "+content; + } + + + /** + * Returns a String-representation of this regular expression + */ + public String toString() { + return print(""); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/RegExp2.java b/tools/lexer/jflex-1.4/src/JFlex/RegExp2.java new file mode 100644 index 000000000000..b656b0c6947d --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/RegExp2.java @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +/** + * Regular expression with two children (e.g. a | b) + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:30 $ + */ +public class RegExp2 extends RegExp { + + RegExp r1, r2; + + public RegExp2(int type, RegExp r1, RegExp r2) { + super(type); + this.r1 = r1; + this.r2 = r2; + } + + public String print(String tab) { + return tab+"type = "+type+Out.NL+tab+"child 1 :"+Out.NL+ //$NON-NLS-1$ //$NON-NLS-2$ + r1.print(tab+" ")+Out.NL+tab+"child 2 :"+Out.NL+ //$NON-NLS-1$ //$NON-NLS-2$ + r2.print(tab+" "); //$NON-NLS-1$ + } + + public String toString() { + return print(""); //$NON-NLS-1$ + } +} + diff --git a/tools/lexer/jflex-1.4/src/JFlex/RegExps.java b/tools/lexer/jflex-1.4/src/JFlex/RegExps.java new file mode 100644 index 000000000000..f6ad2be95d0d --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/RegExps.java @@ -0,0 +1,159 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +import java.util.Enumeration; +import java.util.Vector; + + +/** + * Stores all rules of the specification for later access in RegExp -> NFA + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:31 $ + */ +public class RegExps { + + /** the spec line in which a regexp is used */ + Vector /* of Integer */ lines; + + /** the lexical states in wich the regexp is used */ + Vector /* of Vector of Integer */ states; + + /** the regexp */ + Vector /* of RegExp */ regExps; + + /** the action of a regexp */ + Vector /* of Action */ actions; + + /** flag if it is a BOL regexp */ + Vector /* of Boolean */ BOL; + + /** the lookahead expression */ + Vector /* of RegExp */ look; + + public RegExps() { + states = new Vector(); + regExps = new Vector(); + actions = new Vector(); + BOL = new Vector(); + look = new Vector(); + lines = new Vector(); + } + + public int insert(int line, Vector stateList, RegExp regExp, Action action, + Boolean isBOL, RegExp lookAhead) { + if (Options.DEBUG) { + Out.debug("Inserting regular expression with statelist :"+Out.NL+stateList); //$NON-NLS-1$ + Out.debug("and action code :"+Out.NL+action.content+Out.NL); //$NON-NLS-1$ + Out.debug("expression :"+Out.NL+regExp); //$NON-NLS-1$ + } + + states.addElement(stateList); + regExps.addElement(regExp); + actions.addElement(action); + BOL.addElement(isBOL); + look.addElement(lookAhead); + lines.addElement(new Integer(line)); + + return states.size()-1; + } + + public int insert(Vector stateList, Action action) { + + if (Options.DEBUG) { + Out.debug("Inserting eofrule with statelist :"+Out.NL+stateList); //$NON-NLS-1$ + Out.debug("and action code :"+Out.NL+action.content+Out.NL); //$NON-NLS-1$ + } + + states.addElement(stateList); + regExps.addElement(null); + actions.addElement(action); + BOL.addElement(null); + look.addElement(null); + lines.addElement(null); + + return states.size()-1; + } + + public void addStates(int regNum, Vector newStates) { + Enumeration s = newStates.elements(); + + while (s.hasMoreElements()) + ((Vector)states.elementAt(regNum)).addElement(s.nextElement()); + } + + public int getNum() { + return states.size(); + } + + public boolean isBOL(int num) { + return ((Boolean) BOL.elementAt(num)).booleanValue(); + } + + public RegExp getLookAhead(int num) { + return (RegExp) look.elementAt(num); + } + + public boolean isEOF(int num) { + return BOL.elementAt(num) == null; + } + + public Vector getStates(int num) { + return (Vector) states.elementAt(num); + } + + public RegExp getRegExp(int num) { + return (RegExp) regExps.elementAt(num); + } + + public int getLine(int num) { + return ((Integer) lines.elementAt(num)).intValue(); + } + + public void checkActions() { + if ( actions.elementAt(actions.size()-1) == null ) { + Out.error(ErrorMessages.NO_LAST_ACTION); + throw new GeneratorException(); + } + } + + public Action getAction(int num) { + while ( num < actions.size() && actions.elementAt(num) == null ) + num++; + + return (Action) actions.elementAt(num); + } + + public int NFASize(Macros macros) { + int size = 0; + Enumeration e = regExps.elements(); + while (e.hasMoreElements()) { + RegExp r = (RegExp) e.nextElement(); + if (r != null) size += r.size(macros); + } + e = look.elements(); + while (e.hasMoreElements()) { + RegExp r = (RegExp) e.nextElement(); + if (r != null) size += r.size(macros); + } + return size; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/ScannerException.java b/tools/lexer/jflex-1.4/src/JFlex/ScannerException.java new file mode 100644 index 000000000000..004ce886a5af --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/ScannerException.java @@ -0,0 +1,104 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +import java.io.File; + +/** + * This Exception could be thrown while scanning the specification + * (e.g. unmatched input) + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:30 $ + */ +public class ScannerException extends RuntimeException { + + public int line; + public int column; + public ErrorMessages message; + public File file; + + private ScannerException(File file, String text, ErrorMessages message, int line, int column) { + super(text); + this.file = file; + this.message = message; + this.line = line; + this.column = column; + } + + + /** + * Creates a new ScannerException with a message only. + * + * @param message the code for the error description presented to the user. + */ + public ScannerException(ErrorMessages message) { + this( null, ErrorMessages.get(message), message, -1, -1 ); + } + + /** + * Creates a new ScannerException for a file with a message only. + * + * @param file the file in which the error occured + * @param message the code for the error description presented to the user. + */ + public ScannerException(File file, ErrorMessages message) { + this( file, ErrorMessages.get(message), message, -1, -1 ); + } + + + /** + * Creates a new ScannerException with a message and line number. + * + * @param message the code for the error description presented to the user. + * @param line the number of the line in the specification that + * contains the error + */ + public ScannerException(ErrorMessages message, int line) { + this( null, ErrorMessages.get(message), message, line, -1 ); + } + + + /** + * Creates a new ScannerException for a file with a message and line number. + * + * @param message the code for the error description presented to the user. + * @param line the number of the line in the specification that + * contains the error + */ + public ScannerException(File file, ErrorMessages message, int line) { + this( file, ErrorMessages.get(message), message, line, -1 ); + } + + + /** + * Creates a new ScannerException with a message, line number and column. + * + * @param message the code for the error description presented to the user. + * @param line the number of the line in the specification that + * contains the error + * @param column the column where the error starts + */ + public ScannerException(File file, ErrorMessages message, int line, int column) { + this( file, ErrorMessages.get(message), message, line, column ); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/SemCheck.java b/tools/lexer/jflex-1.4/src/JFlex/SemCheck.java new file mode 100644 index 000000000000..04f66477b256 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/SemCheck.java @@ -0,0 +1,145 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +import java.io.File; + +/** + * Performs simple semantic analysis on regular expressions. + * + * (used for checking if trailing contexts are legal) + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.5 $, $Date: 2004/11/06 23:03:32 $ + */ +public final class SemCheck { + + // stored globally since they are used as constants in all checks + private static Macros macros; + private static char maxChar; + + + /** + * Performs semantic analysis for all expressions. + * + * Currently: illegal lookahead check only + * [fixme: more checks possible] + * + * @param rs the reg exps to be checked + * @param m the macro table (in expanded form) + * @param max max character of the used charset (for negation) + * @param f the spec file containing the rules [fixme] + */ + public static void check(RegExps rs, Macros m, char max, File f) { + macros = m; + maxChar = max; + + int num = rs.getNum(); + for (int i = 0; i < num; i++) { + RegExp r = rs.getRegExp(i); + RegExp l = rs.getLookAhead(i); + + if (!checkLookAhead(r,l)) { + Out.warning(f, ErrorMessages.LOOKAHEAD_ERROR, rs.getLine(i), -1); + } + } + } + + + /** + * Checks for illegal lookahead expressions. + * + * Lookahead in JFlex only works when the first expression has fixed + * length or when the intersection of the last set of the first expression + * and the first set of the second expression is empty. + * + * FIXME: this check is much too weak + * + * + * @param r1 first regexp + * @param r2 second regexp (the lookahead) + * + * @return true iff JFlex can generate code for the lookahead expression + */ + private static boolean checkLookAhead(RegExp r1, RegExp r2) { + return r2 == null || length(r1) > 0; + } + + + /** + * Returns length if expression has fixed length, -1 otherwise. + * + * Negation operators are treated as always variable length. + */ + private static int length(RegExp re) { + RegExp2 r; + + switch (re.type) { + + case sym.BAR: { + r = (RegExp2) re; + int l1 = length(r.r1); + if (l1 < 0) return -1; + int l2 = length(r.r2); + + if (l1 == l2) + return l1; + else + return -1; + } + + case sym.CONCAT: { + r = (RegExp2) re; + int l1 = length(r.r1); + if (l1 < 0) return -1; + int l2 = length(r.r2); + if (l2 < 0) return -1; + return l1+l2; + } + + case sym.STAR: + case sym.PLUS: + case sym.QUESTION: + return -1; + + case sym.CCLASS: + case sym.CCLASSNOT: + case sym.CHAR: + case sym.CHAR_I: + return 1; + + case sym.STRING: + case sym.STRING_I: { + String content = (String) ((RegExp1) re).content; + return content.length(); + } + + case sym.TILDE: + case sym.BANG: + // too hard to caculate at this level, use safe approx + return -1; + + case sym.MACROUSE: + return length(macros.getDefinition((String) ((RegExp1) re).content)); + } + + throw new Error("Unkown expression type "+re.type+" in "+re); //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/SilentExit.java b/tools/lexer/jflex-1.4/src/JFlex/SilentExit.java new file mode 100644 index 000000000000..e60affa3338f --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/SilentExit.java @@ -0,0 +1,31 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +/** + * Signals a silent exit (no statistics printout). + * + * @author Gerwin Klein + * @version $Revision: 2.3 $, $Date: 2004/11/06 23:03:32 $ + */ +public class SilentExit extends Exception { + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Skeleton.java b/tools/lexer/jflex-1.4/src/JFlex/Skeleton.java new file mode 100644 index 000000000000..89c519da3433 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Skeleton.java @@ -0,0 +1,207 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +import java.io.*; +import java.net.URL; +import java.util.Vector; + + +/** + * This class stores the skeleton of generated scanners. + * + * The skeleton consists of several parts that can be emitted to + * a file. Usually there is a portion of generated code + * (produced in class Emitter) between every two parts of skeleton code. + * + * There is a static part (the skeleton code) and state based iterator + * part to this class. The iterator part is used to emit consecutive skeleton + * sections to some PrintWriter. + * + * @see JFlex.Emitter + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.13 $, $Date: 2004/11/06 23:03:31 $ + */ +public class Skeleton { + /** expected number of sections in the skeleton file */ + static final private int size = 21; + + /** platform specific newline */ + static final private String NL = System.getProperty("line.separator"); //$NON-NLS-1$ + + /** The skeleton */ + public static String line[]; + + /** initialization */ + static { readDefault(); } + + // the state based, iterator part of Skeleton: + + /** + * The current part of the skeleton (an index of nextStop[]) + */ + private int pos; + + /** + * The writer to write the skeleton-parts to + */ + private PrintWriter out; + + + /** + * Creates a new skeleton (iterator) instance. + * + * @param out the writer to write the skeleton-parts to + */ + public Skeleton(PrintWriter out) { + this.out = out; + } + + + /** + * Emits the next part of the skeleton + */ + public void emitNext() { + out.print( line[pos++] ); + } + + + /** + * Make the skeleton private. + * + * Replaces all occurences of " public " in the skeleton with " private ". + */ + public static void makePrivate() { + for (int i=0; i < line.length; i++) { + line[i] = replace(" public ", " private ", line[i]); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + + /** + * Reads an external skeleton file for later use with this class. + * + * @param skeletonFile the file to read (must be != null and readable) + */ + public static void readSkelFile(File skeletonFile) { + if (skeletonFile == null) + throw new IllegalArgumentException("Skeleton file must not be null"); //$NON-NLS-1$ + + if (!skeletonFile.isFile() || !skeletonFile.canRead()) { + Out.error(ErrorMessages.CANNOT_READ_SKEL, skeletonFile.toString()); + throw new GeneratorException(); + } + + Out.println(ErrorMessages.READING_SKEL, skeletonFile.toString()); + + try { + BufferedReader reader = new BufferedReader(new FileReader(skeletonFile)); + readSkel(reader); + } + catch (IOException e) { + Out.error(ErrorMessages.SKEL_IO_ERROR); + throw new GeneratorException(); + } + } + + + /** + * Reads an external skeleton file from a BufferedReader. + * + * @param reader the reader to read from (must be != null) + * @throws IOException if an IO error occurs + * @throws GeneratorException if the number of skeleton sections does not match + */ + public static void readSkel(BufferedReader reader) throws IOException { + Vector lines = new Vector(); + StringBuffer section = new StringBuffer(); + + String ln; + while ((ln = reader.readLine()) != null) { + if (ln.startsWith("---")) { //$NON-NLS-1$ + lines.addElement(section.toString()); + section.setLength(0); + } else { + section.append(ln); + section.append(NL); + } + } + + if (section.length() > 0) + lines.addElement(section.toString()); + + if (lines.size() != size) { + Out.error(ErrorMessages.WRONG_SKELETON); + throw new GeneratorException(); + } + + line = new String[size]; + for (int i = 0; i < size; i++) + line[i] = (String) lines.elementAt(i); + } + + /** + * Replaces a with b in c. + * + * @param a the String to be replaced + * @param b the replacement + * @param c the String in which to replace a by b + * @return a String object with a replaced by b in c + */ + public static String replace(String a, String b, String c) { + StringBuffer result = new StringBuffer(c.length()); + int i = 0; + int j = c.indexOf(a); + + while (j >= i) { + result.append(c.substring(i,j)); + result.append(b); + i = j+a.length(); + j = c.indexOf(a,i); + } + + result.append(c.substring(i,c.length())); + + return result.toString(); + } + + + /** + * (Re)load the default skeleton. Looks in the current system class path. + */ + public static void readDefault() { + ClassLoader l = Skeleton.class.getClassLoader(); + URL url = l.getResource("JFlex/skeleton.default"); //$NON-NLS-1$ + + if (url == null) { + Out.error(ErrorMessages.SKEL_IO_ERROR_DEFAULT); + throw new GeneratorException(); + } + + try { + InputStreamReader reader = new InputStreamReader(url.openStream()); + readSkel(new BufferedReader(reader)); + } catch (IOException e) { + Out.error(ErrorMessages.SKEL_IO_ERROR_DEFAULT); + throw new GeneratorException(); + } + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/StatePairList.java b/tools/lexer/jflex-1.4/src/JFlex/StatePairList.java new file mode 100644 index 000000000000..d69deae8c56c --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/StatePairList.java @@ -0,0 +1,83 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + +/** + * A list of pairs of states. Used in DFA minimization. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:30 $ + */ +final public class StatePairList { + + // implemented as two arrays of integers. + // java.util classes proved too inefficient. + + int p []; + int q []; + + int num; + + public StatePairList() { + p = new int [8]; + q = new int [8]; + num = 0; + } + + public void addPair(int i, int j) { + for (int x = 0; x < num; x++) + if (p[x] == i && q[x] == j) return; + + if (num >= p.length) increaseSize(num); + + p[num] = i; + q[num] = j; + + num++; + } + + public void markAll(StatePairList [] [] list, boolean [] [] equiv) { + for (int x = 0; x < num; x++) { + int i = p[x]; + int j = q[x]; + + if (equiv[i][j]) { + equiv[i][j] = false; + if (list[i][j] != null) + list[i][j].markAll(list, equiv); + } + } + } + + private void increaseSize(int length) { + length = Math.max(length+1, 4*p.length); + Out.debug("increasing length to "+length); //$NON-NLS-1$ + + int pn [] = new int[length]; + int qn [] = new int[length]; + + System.arraycopy(p, 0, pn, 0, p.length); + System.arraycopy(q, 0, qn, 0, q.length); + + p = pn; + q = qn; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/StateSet.java b/tools/lexer/jflex-1.4/src/JFlex/StateSet.java new file mode 100644 index 000000000000..0fcbc22ee915 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/StateSet.java @@ -0,0 +1,329 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +/** + * A set of NFA states (= integers). + * + * Very similar to java.util.BitSet, but is faster and doesn't crash + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:32 $ + */ +final public class StateSet { + + private final boolean DEBUG = false; + + public final static StateSet EMPTY = new StateSet(); + + + final static int BITS = 6; + final static int MASK = (1<> BITS; + if (index >= bits.length) resize(state); + bits[index] |= (1L << (state & MASK)); + + if (DEBUG) { + Out.dump("StateSet.addState("+state+") end"); //$NON-NLS-1$ //$NON-NLS-2$ + Out.dump("Set is : "+this); //$NON-NLS-1$ + } + } + + + private int size2nbits (int size) { + return ((size >> BITS) + 1); + } + + + private void resize(int size) { + int needed = size2nbits(size); + + // if (needed < bits.length) return; + + long newbits[] = new long[Math.max(bits.length*4,needed)]; + System.arraycopy(bits, 0, newbits, 0, bits.length); + + bits = newbits; + } + + + public void clear() { + int l = bits.length; + for (int i = 0; i < l; i++) bits[i] = 0; + } + + public boolean isElement(int state) { + int index = state >> BITS; + if (index >= bits.length) return false; + return (bits[index] & (1L << (state & MASK))) != 0; + } + + /** + * Returns one element of the set and removes it. + * + * Precondition: the set is not empty. + */ + public int getAndRemoveElement() { + int i = 0; + int o = 0; + long m = 1; + + while (bits[i] == 0) i++; + + while ( (bits[i] & m) == 0 ) { + m<<= 1; + o++; + } + + bits[i]&= ~m; + + return (i << BITS) + o; + } + + public void remove(int state) { + int index = state >> BITS; + if (index >= bits.length) return; + bits[index] &= ~(1L << (state & MASK)); + } + + /** + * Returns the set of elements that contained are in the specified set + * but are not contained in this set. + */ + public StateSet complement(StateSet set) { + + if (set == null) return null; + + StateSet result = new StateSet(); + + result.bits = new long[set.bits.length]; + + int i; + int m = Math.min(bits.length, set.bits.length); + + for (i = 0; i < m; i++) { + result.bits[i] = ~bits[i] & set.bits[i]; + } + + if (bits.length < set.bits.length) + System.arraycopy(set.bits, m, result.bits, m, result.bits.length-m); + + if (DEBUG) + Out.dump("Complement of "+this+Out.NL+"and "+set+Out.NL+" is :"+result); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + return result; + } + + public void add(StateSet set) { + + if (DEBUG) Out.dump("StateSet.add("+set+") start"); //$NON-NLS-1$ //$NON-NLS-2$ + + if (set == null) return; + + long tbits[]; + long sbits[] = set.bits; + int sbitsl = sbits.length; + + if (bits.length < sbitsl) { + tbits = new long[sbitsl]; + System.arraycopy(bits, 0, tbits, 0, bits.length); + } + else { + tbits = this.bits; + } + + for (int i = 0; i < sbitsl; i++) { + tbits[i] |= sbits[i]; + } + + this.bits = tbits; + + if (DEBUG) { + Out.dump("StateSet.add("+set+") end"); //$NON-NLS-1$ //$NON-NLS-2$ + Out.dump("Set is : "+this); //$NON-NLS-1$ + } + } + + + + public boolean containsSet(StateSet set) { + + if (DEBUG) + Out.dump("StateSet.containsSet("+set+"), this="+this); //$NON-NLS-1$ //$NON-NLS-2$ + + int i; + int min = Math.min(bits.length, set.bits.length); + + for (i = 0; i < min; i++) + if ( (bits[i] & set.bits[i]) != set.bits[i] ) return false; + + for (i = min; i < set.bits.length; i++) + if ( set.bits[i] != 0 ) return false; + + return true; + } + + + + /** + * @throws ClassCastException if b is not a StateSet + * @throws NullPointerException if b is null + */ + public boolean equals(Object b) { + + int i = 0; + int l1,l2; + StateSet set = (StateSet) b; + + if (DEBUG) Out.dump("StateSet.equals("+set+"), this="+this); //$NON-NLS-1$ //$NON-NLS-2$ + + l1 = bits.length; + l2 = set.bits.length; + + if (l1 <= l2) { + while (i < l1) { + if (bits[i] != set.bits[i]) return false; + i++; + } + + while (i < l2) + if (set.bits[i++] != 0) return false; + } + else { + while (i < l2) { + if (bits[i] != set.bits[i]) return false; + i++; + } + + while (i < l1) + if (bits[i++] != 0) return false; + } + + return true; + } + + public int hashCode() { + long h = 1234; + long [] _bits = bits; + int i = bits.length-1; + + // ignore zero high bits + while (i >= 0 && _bits[i] == 0) i--; + + while (i >= 0) + h ^= _bits[i--] * i; + + return (int)((h >> 32) ^ h); + } + + + public StateSetEnumerator states() { + return new StateSetEnumerator(this); + } + + + public boolean containsElements() { + for (int i = 0; i < bits.length; i++) + if (bits[i] != 0) return true; + + return false; + } + + + public StateSet copy() { + StateSet set = new StateSet(); + set.bits = new long[bits.length]; + System.arraycopy(bits, 0, set.bits, 0, bits.length); + return set; + } + + + public void copy(StateSet set) { + + if (DEBUG) + Out.dump("StateSet.copy("+set+") start"); //$NON-NLS-1$ //$NON-NLS-2$ + + if (set == null) { + for (int i = 0; i < bits.length; i++) bits[i] = 0; + return; + } + + if (bits.length < set.bits.length) { + bits = new long[set.bits.length]; + } + else { + for (int i = set.bits.length; i < bits.length; i++) bits[i] = 0; + } + + System.arraycopy(set.bits, 0, bits, 0, bits.length); + + if (DEBUG) { + Out.dump("StateSet.copy("+set+") end"); //$NON-NLS-1$ //$NON-NLS-2$ + Out.dump("Set is : "+this); //$NON-NLS-1$ + } + } + + + public String toString() { + StateSetEnumerator set = states(); + + StringBuffer result = new StringBuffer("{"); //$NON-NLS-1$ + + if ( set.hasMoreElements() ) result.append(""+set.nextElement()); //$NON-NLS-1$ + + while ( set.hasMoreElements() ) { + int i = set.nextElement(); + result.append( ", "+i); //$NON-NLS-1$ + } + + result.append("}"); //$NON-NLS-1$ + + return result.toString(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/StateSetEnumerator.java b/tools/lexer/jflex-1.4/src/JFlex/StateSetEnumerator.java new file mode 100644 index 000000000000..5e5ac7b147b9 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/StateSetEnumerator.java @@ -0,0 +1,127 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +/** + * Enumerates the states of a StateSet. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:32 $ + */ +final public class StateSetEnumerator { + + private final static boolean DEBUG = false; + + private int index; + private int offset; + private long mask; + + private int current; + private long [] bits; + + /** + * creates a new StateSetEnumerator that is not yet associated + * with a StateSet. hasMoreElements() and nextElement() will + * throw NullPointerException when used before reset() + */ + public StateSetEnumerator() { + } + + public StateSetEnumerator(StateSet states) { + reset(states); + } + + public void reset(StateSet states) { + bits = states.bits; + index = 0; + offset = 0; + mask = 1; + current = 0; + + while (index < bits.length && bits[index] == 0) + index++; + + if (index >= bits.length) return; + + while (offset <= StateSet.MASK && ((bits[index] & mask) == 0)) { + mask<<= 1; + offset++; + } + } + + private void advance() { + + if (DEBUG) Out.dump("Advancing, at start, index = "+index+", offset = "+offset); //$NON-NLS-1$ //$NON-NLS-2$ + + // cache fields in local variable for faster access + int _index = this.index; + int _offset = this.offset; + long _mask = this.mask; + long [] _bits = this.bits; + + long bi = _bits[_index]; + + do { + _offset++; + _mask<<= 1; + } while (_offset <= StateSet.MASK && ((bi & _mask) == 0)); + + if (_offset > StateSet.MASK) { + int length = _bits.length; + + do + _index++; + while (_index < length && _bits[_index] == 0); + + if (_index >= length) { + this.index = length; // indicates "no more elements" + return; + } + + _offset = 0; + _mask = 1; + bi = _bits[_index]; + + // terminates, because bi != 0 + while ((bi & _mask) == 0) { + _mask<<= 1; + _offset++; + } + } + + // write back cached values + this.index = _index; + this.mask = _mask; + this.offset = _offset; + } + + public boolean hasMoreElements() { + if (DEBUG) Out.dump("hasMoreElements, index = "+index+", offset = "+offset); //$NON-NLS-1$ //$NON-NLS-2$ + return index < bits.length; + } + + public int nextElement() { + if (DEBUG) Out.dump("nextElement, index = "+index+", offset = "+offset); //$NON-NLS-1$ //$NON-NLS-2$ + int x = (index << StateSet.BITS) + offset; + advance(); + return x; + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/StdOutWriter.java b/tools/lexer/jflex-1.4/src/JFlex/StdOutWriter.java new file mode 100644 index 000000000000..572a756c64bc --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/StdOutWriter.java @@ -0,0 +1,114 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex; + + +import java.awt.*; +import java.io.OutputStream; +import java.io.PrintWriter; + + +/** + * Convenience class for JFlex stdout, redirects output to a TextArea + * if in GUI mode. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:30 $ + */ +public final class StdOutWriter extends PrintWriter { + + /** text area to write to if in gui mode, gui mode = (text != null) */ + private TextArea text; + + /** + * approximation of the current column in the text area + * for auto wrapping at wrap characters + **/ + private int col; + + /** auto wrap lines in gui mode at this value */ + private final static int wrap = 78; + + /** A StdOutWriter, attached to System.out, no gui mode */ + public StdOutWriter() { + super(System.out,true); + } + + /** A StdOutWrite, attached to the specified output stream, no gui mode */ + public StdOutWriter(OutputStream out) { + super(out,true); + } + + /** + * Set the TextArea to write text to. Will continue + * to write to System.out if text is null. + * + * @param text the TextArea to write to + */ + public void setGUIMode(TextArea text) { + this.text = text; + } + + /** Write a single character. */ + public void write(int c) { + if (text != null) { + text.append(String.valueOf((char) c)); + if (++col > wrap) println(); + } + else + super.write(c); + } + + /** Write a portion of an array of characters. */ + public void write(char buf[], int off, int len) { + if (text != null) { + text.append(new String(buf,off,len)); + if ((col+=len) > wrap) println(); + } + else + super.write(buf, off, len); + } + + /** Write a portion of a string. */ + public void write(String s, int off, int len) { + if (text != null) { + text.append(s.substring(off,off+len)); + if ((col+=len) > wrap) println(); + } + else { + super.write(s,off,len); + flush(); + } + } + + /** + * Begin a new line. Which actual character/s is/are written + * depends on the runtime platform. + */ + public void println() { + if (text != null) { + text.append(Out.NL); + col = 0; + } + else + super.println(); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/Timer.java b/tools/lexer/jflex-1.4/src/JFlex/Timer.java new file mode 100644 index 000000000000..3cead204cfe2 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/Timer.java @@ -0,0 +1,110 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex; + +/** + * Very simple timer for code generation time statistics. + * + * Not very exact, measures user time, not processor time. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:32 $ + */ +public class Timer { + + /* the timer stores start and stop time from currentTimeMillis() */ + private long startTime, stopTime; + + /* flag if the timer is running (if stop time is valid) */ + private boolean running; + + + /** + * Construct a new timer that starts immediatly. + */ + public Timer() { + startTime = System.currentTimeMillis(); + running = true; + } + + + /** + * Start the timer. If it is already running, the old start + * time is lost. + */ + public void start() { + startTime = System.currentTimeMillis(); + running = true; + } + + + /** + * Stop the timer. + */ + public void stop() { + stopTime = System.currentTimeMillis(); + running = false; + } + + + /** + * Return the number of milliseconds the timer has been running. + * + * (up till now, if it still runs, up to the stop time if it has been stopped) + */ + public long diff() { + if (running) + return System.currentTimeMillis()-startTime; + else + return stopTime-startTime; + } + + + /** + * Return a string representation of the timer. + * + * @return a string displaying the diff-time in readable format (h m s ms) + * + * @see Timer#diff + */ + public String toString() { + long diff = diff(); + + long millis = diff%1000; + long secs = (diff/1000)%60; + long mins = (diff/(1000*60))%60; + long hs = (diff/(1000*3600))%24; + long days = diff/(1000*3600*24); + + if (days > 0) + return days+"d "+hs+"h "+mins+"m "+secs+"s "+millis+"ms"; + + if (hs > 0) + return hs+"h "+mins+"m "+secs+"s "+millis+"ms"; + + if (mins > 0) + return mins+"m "+secs+"s "+millis+"ms"; + + if (secs > 0) + return secs+"s "+millis+"ms"; + + return millis+"ms"; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/anttask/JFlexTask.java b/tools/lexer/jflex-1.4/src/JFlex/anttask/JFlexTask.java new file mode 100644 index 000000000000..10a95c5652c4 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/anttask/JFlexTask.java @@ -0,0 +1,268 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex Anttask * + * Copyright (C) 2001 Rafal Mantiuk * + * Copyright (C) 2003 changes by Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.anttask; + +import JFlex.Main; +import JFlex.Options; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.LineNumberReader; + +/** + * JFlex task class + * + * @author Rafal Mantiuk + * @version JFlex 1.4.1, $Revision: 2.14 $, $Date: 2004/11/06 23:03:33 $ + */ +public class JFlexTask extends Task { + private File inputFile; + + // found out by looking into .flex file + private String className = null; + private String packageName = null; + + /** for javac-like dest dir behaviour */ + private File destinationDir; + + /** the actual output directory (outputDir = destinationDir + package)) */ + private File outputDir = null; + + public JFlexTask() { + // ant default is different from the rest of JFlex + setVerbose(false); + Options.progress = false; + } + + public void execute() throws BuildException { + try { + if (inputFile == null) + throw new BuildException("Input file needed. Use "); + + if (!inputFile.canRead()) + throw new BuildException("Cannot read input file "+inputFile); + + try { + findPackageAndClass(); + normalizeOutdir(); + File destFile = new File(outputDir, className + ".java"); + + if (inputFile.lastModified() > destFile.lastModified()) { + Main.generate(inputFile); + if (!Options.verbose) + System.out.println("Generated: " + destFile.getName()); + } + } catch (IOException e1) { + throw new BuildException("IOException: " + e1.toString()); + } + } catch (JFlex.GeneratorException e) { + throw new BuildException("JFlex: generation failed!"); + } + } + + /** + * Peek into .flex file to get package and class name + * + * @throws IOException if there is a problem reading the .flex file + */ + public void findPackageAndClass() throws IOException { + // find name of the package and class in jflex source file + packageName = null; + className = null; + + LineNumberReader reader = new LineNumberReader(new FileReader(inputFile)); + + while (className == null || packageName == null) { + String line = reader.readLine(); + if (line == null) break; + + if (packageName == null) { + int index = line.indexOf("package"); + if (index >= 0) { + index += 7; + + int end = line.indexOf(';', index); + if (end >= index) { + packageName = line.substring(index, end); + packageName = packageName.trim(); + } + } + } + + if (className == null) { + int index = line.indexOf("%class"); + if (index >= 0) { + index += 6; + + className = line.substring(index); + className = className.trim(); + } + } + } + + // package name may be null, but class name not + if (className == null) className = "Yylex"; + } + + /** + * Sets the actual output directory if not already set. + * + * Uses javac logic to determine output dir = dest dir + package name + * If not destdir has been set, output dir = parent of input file + * + * Assumes that package name is already set. + */ + public void normalizeOutdir() { + if (outputDir != null) return; + + // find out what the destination directory is. Append packageName to dest dir. + File destDir; + + // this is not the default the jflex logic, but javac-like + if (destinationDir != null) { + if (packageName == null) { + destDir = destinationDir; + } + else { + String path = packageName.replace('.', File.separatorChar); + destDir = new File(destinationDir,path); + } + } else { //save parser to the same dir as .flex + destDir = new File(inputFile.getParent()); + } + + setOutdir(destDir); + } + + /** + * @return package name of input file + * + * @see JFlexTask.findPackageAndClass + */ + public String getPackage() { + return packageName; + } + + /** + * @return class name of input file + * + * @see JFlexTask.findPackageAndClass + */ + public String getClassName() { + return className; + } + + public void setDestdir(File destinationDir) { + this.destinationDir = destinationDir; + } + + public void setOutdir(File outDir) { + this.outputDir = outDir; + Options.setDir(outputDir); + } + + public void setFile(File file) { + this.inputFile = file; + } + + public void setGenerateDot(boolean genDot) { + setDot(genDot); + } + + public void setTimeStatistics(boolean displayTime) { + Options.time = displayTime; + } + + public void setTime(boolean displayTime) { + setTimeStatistics(displayTime); + } + + public void setVerbose(boolean verbose) { + Options.verbose = verbose; + } + + public void setSkeleton(File skeleton) { + Options.setSkeleton(skeleton); + } + + public void setSkel(File skeleton) { + setSkeleton(skeleton); + } + + public void setSkipMinimization(boolean skipMin) { + setNomin(skipMin); + } + + public void setNomin(boolean b) { + Options.no_minimize = b; + } + + public void setNobak(boolean b) { + Options.no_backup = b; + } + + public void setSwitch(boolean b) { + if (b) { + Options.gen_method = Options.SWITCH; + } + else { + Options.gen_method = Options.PACK; + } + } + + public void setTable(boolean b) { + if (b) { + Options.gen_method = Options.TABLE; + } + else { + Options.gen_method = Options.PACK; + } + } + + public void setPack(boolean b) { + if (b) { + Options.gen_method = Options.PACK; + } + else { + Options.gen_method = Options.SWITCH; + } + } + + public void setDot(boolean b) { + Options.dot = b; + } + + public void setDump(boolean b) { + Options.dump = b; + } + + public void setJLex(boolean b) { + Options.jlex = b; + } + + public void setCharAt(boolean b) { + Options.char_at = b; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/GeneratorThread.java b/tools/lexer/jflex-1.4/src/JFlex/gui/GeneratorThread.java new file mode 100644 index 000000000000..40f0fb3a13a5 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/GeneratorThread.java @@ -0,0 +1,93 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.gui; + +import JFlex.*; + +import java.io.File; + + +/** + * Low priority thread for code generation (low priority + * that gui has time for screen updates) + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.6 $, $Date: 2004/11/06 23:03:33 $ + */ +public class GeneratorThread extends Thread { + + /** there must be at most one instance of this Thread running */ + private static volatile boolean running = false; + + /** input file setting from GUI */ + String inputFile; + + /** output directory */ + String outputDir; + + /** main UI component, likes to be notified when generator finishes */ + MainFrame parent; + + /** + * Create a new GeneratorThread, but do not run it yet. + * + * @param parent the frame, main UI component + * @param inputFile input file from UI settings + * @param messages where generator messages should appear + * @param outputDir output directory from UI settings + */ + public GeneratorThread(MainFrame parent, String inputFile, + String outputDir) { + this.parent = parent; + this.inputFile = inputFile; + this.outputDir = outputDir; + } + + + /** + * Run the generator thread. Only one instance of it can run at any time. + */ + public void run() { + if (running) { + Out.error(ErrorMessages.ALREADY_RUNNING); + parent.generationFinished(false); + } + else { + running = true; + setPriority(MIN_PRIORITY); + try { + if (!outputDir.equals("")) { + Options.setDir(outputDir); + } + Main.generate(new File(inputFile)); + Out.statistics(); + parent.generationFinished(true); + } + catch (GeneratorException e) { + Out.statistics(); + parent.generationFinished(false); + } + finally { + running = false; + } + } + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanel.java b/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanel.java new file mode 100644 index 000000000000..e18a6320a670 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanel.java @@ -0,0 +1,161 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.gui; + +import java.awt.*; +import java.util.Vector; + +/** + * Grid layout manager like GridLayout but with predefinable + * grid size. + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:33 $ + */ +public class GridPanel extends Panel implements Handles { + + private int cols; + private int rows; + + private int hgap; + private int vgap; + + private Vector constraints = new Vector(); + private Insets insets = new Insets(0,0,0,0); + + public GridPanel(int cols, int rows) { + this(cols, rows, 0, 0); + } + + public GridPanel(int cols, int rows, int hgap, int vgap) { + this.cols = cols; + this.rows = rows; + this.hgap = hgap; + this.vgap = vgap; + } + + public void doLayout() { + Dimension size = getSize(); + size.height -= insets.top+insets.bottom; + size.width -= insets.left+insets.right; + + float cellWidth = size.width/cols; + float cellHeight = size.height/rows; + + for (int i = 0; i < constraints.size(); i++) { + GridPanelConstraint c = (GridPanelConstraint) constraints.elementAt(i); + + float x = cellWidth * c.x + insets.left + hgap/2; + float y = cellHeight * c.y + insets.right + vgap/2; + + float width, height; + + if (c.handle == FILL) { + width = (cellWidth-hgap) * c.width; + height = (cellHeight-vgap) * c.height; + } + else { + Dimension d = c.component.getPreferredSize(); + width = d.width; + height = d.height; + } + + switch (c.handle) { + case TOP_CENTER: + x+= (cellWidth+width)/2; + break; + case TOP_RIGHT: + x+= cellWidth-width; + break; + case CENTER_LEFT: + y+= (cellHeight+height)/2; + break; + case CENTER: + x+= (cellWidth+width)/2; + y+= (cellHeight+height)/2; + break; + case CENTER_RIGHT: + y+= (cellHeight+height)/2; + x+= cellWidth-width; + break; + case BOTTOM: + y+= cellHeight-height; + break; + case BOTTOM_CENTER: + x+= (cellWidth+width)/2; + y+= cellHeight-height; + break; + case BOTTOM_RIGHT: + y+= cellHeight-height; + x+= cellWidth-width; + break; + } + + c.component.setBounds(new Rectangle((int)x, (int)y, (int)width, (int)height)); + } + } + + public Dimension getPreferredSize() { + float dy = 0; + float dx = 0; + + for (int i = 0; i < constraints.size(); i++) { + GridPanelConstraint c = (GridPanelConstraint) constraints.elementAt(i); + + Dimension d = c.component.getPreferredSize(); + + dx = Math.max(dx, d.width/c.width); + dy = Math.max(dy, d.height/c.height); + } + + dx+= hgap; + dy+= vgap; + + dx*= cols; + dy*= rows; + + dx+= insets.left+insets.right; + dy+= insets.top+insets.bottom; + + return new Dimension((int)dx,(int)dy); + } + + public void setInsets(Insets insets) { + this.insets = insets; + } + + public void add(int x, int y, Component c) { + add(x,y,1,1,FILL,c); + } + + public void add(int x, int y, int handle, Component c) { + add(x,y,1,1,handle,c); + } + + public void add(int x, int y, int dx, int dy, Component c) { + add(x,y,dx,dy,FILL,c); + } + + public void add(int x, int y, int dx, int dy, int handle, Component c) { + super.add(c); + constraints.addElement(new GridPanelConstraint(x,y,dx,dy,handle,c)); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanelConstraint.java b/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanelConstraint.java new file mode 100644 index 000000000000..2bbcba719771 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/GridPanelConstraint.java @@ -0,0 +1,44 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex.gui; + +import java.awt.*; + +/** + * Constraints for layout elements of GridLayout + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:33 $ + */ +public class GridPanelConstraint { + + int x, y, width, height, handle; + Component component; + + public GridPanelConstraint(int x, int y, int width, int height, + int handle, Component component) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.handle = handle; + this.component = component; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/Handles.java b/tools/lexer/jflex-1.4/src/JFlex/gui/Handles.java new file mode 100644 index 000000000000..46cddc1c7205 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/Handles.java @@ -0,0 +1,49 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.gui; + +/** + * Constants used for GridLayout + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:33 $ + */ +public interface Handles { + + int FILL = 0; + + int TOP = 1; + int TOP_LEFT = TOP; + int TOP_CENTER = 2; + int TOP_RIGHT = 3; + + int CENTER_LEFT = 4; + int CENTER = 5; + int CENTER_CENTER = CENTER; + int CENTER_RIGHT = 6; + + int BOTTOM = 7; + int BOTTOM_LEFT = BOTTOM; + int BOTTOM_CENTER = 8; + int BOTTOM_RIGHT = 9; + +} + diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/MainFrame.java b/tools/lexer/jflex-1.4/src/JFlex/gui/MainFrame.java new file mode 100644 index 000000000000..31be4d10d06d --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/MainFrame.java @@ -0,0 +1,275 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.gui; + +import JFlex.Main; +import JFlex.Out; + +import java.awt.*; +import java.awt.event.*; +import java.io.File; + +/** + * JFlex main application frame (GUI mode only) + * + * @author Gerwin Klein + * @version JFlex 1.4.1, $Revision: 2.7 $, $Date: 2004/11/06 23:03:33 $ + */ +final public class MainFrame extends Frame implements Handles { + + private volatile boolean choosing; + + private String fileName = ""; + private String dirName = ""; + + private Button quit; + private Button options; + private Button generate; + private Button stop; + private Button specChoose; + private Button dirChoose; + + private TextField spec; + private TextField dir; + + private TextArea messages; + + private GeneratorThread thread; + + private OptionsDialog dialog; + + + public MainFrame() { + super("JFlex "+Main.version); + buildContent(); + + addWindowListener( new WindowAdapter() { + public void windowClosing(WindowEvent e) { + quit(); + } + }); + + pack(); + show(); + } + + + private void buildContent() { + setBackground(SystemColor.control); + + generate = new Button("Generate"); + quit = new Button("Quit"); + options = new Button("Options"); + stop = new Button("Stop"); + dirChoose = new Button("Browse"); + dir = new TextField(10); + specChoose = new Button("Browse"); + spec = new TextField(10); + messages = new TextArea(10,80); + + messages.setEditable(false); + Font font = messages.getFont(); + if (font != null) + messages.setFont(new Font("Monospaced", font.getStyle(), font.getSize())); + else + messages.setFont(new Font("Monospaced", Font.PLAIN, 12)); + + Out.setGUIMode(messages); + + generate.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + generate(); + } + } ); + + options.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + showOptions(); + } + } ); + + quit.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + quit(); + } + } ); + + stop.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + stop(); + } + } ); + + specChoose.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + specChoose(); + } + } ); + + dirChoose.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + dirChoose(); + } + } ); + + spec.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + fileName = spec.getText(); + generate(); + } + } ); + + spec.addTextListener( new TextListener() { + public void textValueChanged(TextEvent e) { + fileName = spec.getText(); + } + } ); + + dir.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + dirName = dir.getText(); + generate(); + } + } ); + + dir.addTextListener( new TextListener() { + public void textValueChanged(TextEvent e) { + dirName = dir.getText(); + } + } ); + + GridPanel north = new GridPanel(5,4,10,10); + north.setInsets( new Insets(10,5,5,10) ); + + north.add( 4,0, quit); + north.add( 4,1, generate); + north.add( 4,2, options); + north.add( 4,3, stop); + + north.add( 0,0, BOTTOM, new Label("Lexical specification:")); + north.add( 0,1, 2,1, spec); + north.add( 2,1, specChoose); + + north.add( 0,2, BOTTOM, new Label("Output directory:")); + north.add( 0,3, 2,1, dir); + north.add( 2,3, dirChoose); + + Panel center = new Panel(new BorderLayout()); + center.add("North", new Label("Messages:")); + center.add("Center", messages); + + add("North", north); + add("Center", center); + + setEnabledAll(false); + } + + protected void showOptions() { + if (dialog == null) { + dialog = new OptionsDialog(this); + } + dialog.show(); + } + + + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + d.width = messages.getPreferredSize().width; + return d; + } + + private void setEnabledAll(boolean generating) { + stop.setEnabled( generating ); + quit.setEnabled( !generating ); + generate.setEnabled( !generating ); + dirChoose.setEnabled( !generating ); + dir.setEnabled( !generating ); + specChoose.setEnabled( !generating ); + spec.setEnabled( !generating ); + } + + private void generate() { + // workaround for a weird AWT bug + if (choosing) return; + + setEnabledAll(true); + + thread = new GeneratorThread(this, fileName, dirName); + thread.start(); + } + + public void generationFinished(boolean success) { + setEnabledAll(false); + + if (success) + messages.append(Out.NL+"Generation finished successfully."+Out.NL); + else + messages.append(Out.NL+"Generation aborted."+Out.NL); + } + + private void stop() { + if (thread != null) { + /* stop ok here despite deprecation (?) + I don't know any good way to abort generation without changing the + generator code */ + thread.stop(); + thread = null; + } + generationFinished(false); + } + + private void quit() { + setVisible(false); + System.exit(0); + } + + private void dirChoose() { + choosing = true; + + FileDialog d = new FileDialog(this, "Choose directory", FileDialog.LOAD); + + d.show(); + + if (d.getDirectory() != null) { + dir.setText( (new File(d.getDirectory())).getAbsolutePath() ); + } + + choosing = false; + } + + private void specChoose() { + choosing = true; + + FileDialog d = new FileDialog(this, "Choose file", FileDialog.LOAD); + + d.setFile("*.flex"); + d.show(); + + if (d.getFile() != null) { + fileName = d.getDirectory()+d.getFile(); + dir.setText(d.getDirectory()); + spec.setText(fileName); + } + + choosing = false; + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/gui/OptionsDialog.java b/tools/lexer/jflex-1.4/src/JFlex/gui/OptionsDialog.java new file mode 100644 index 000000000000..5338f7c5a8b7 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/gui/OptionsDialog.java @@ -0,0 +1,258 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.gui; + +import JFlex.GeneratorException; +import JFlex.Options; +import JFlex.Skeleton; + +import java.awt.*; +import java.awt.event.*; +import java.io.File; + +/** + * A dialog for setting JFlex options + * + * @author Gerwin Klein + * @version $Revision: 1.7 $, $Date: 2004/11/06 23:03:33 $ + */ +public class OptionsDialog extends Dialog { + + private Frame owner; + + private Button skelBrowse; + private TextField skelFile; + + private Button ok; + private Button defaults; + + private Checkbox dump; + private Checkbox verbose; + private Checkbox jlex; + private Checkbox no_minimize; + private Checkbox no_backup; + private Checkbox time; + private Checkbox dot; + + private Checkbox tableG; + private Checkbox switchG; + private Checkbox packG; + + + /** + * Create a new options dialog + * + * @param owner + */ + public OptionsDialog(Frame owner) { + super(owner, "Options"); + + this.owner = owner; + + setup(); + pack(); + + addWindowListener( new WindowAdapter() { + public void windowClosing(WindowEvent e) { + close(); + } + }); + } + + public void setup() { + // create components + ok = new Button("Ok"); + defaults = new Button("Defaults"); + skelBrowse = new Button(" Browse"); + skelFile = new TextField(); + skelFile.setEditable(false); + dump = new Checkbox(" dump"); + verbose = new Checkbox(" verbose"); + + jlex = new Checkbox(" JLex compatibility"); + no_minimize = new Checkbox(" skip minimization"); + no_backup = new Checkbox(" no backup file"); + time = new Checkbox(" time statistics"); + dot = new Checkbox(" dot graph files"); + + CheckboxGroup codeG = new CheckboxGroup(); + tableG = new Checkbox(" table",Options.gen_method == Options.TABLE, codeG); + switchG = new Checkbox(" switch",Options.gen_method == Options.SWITCH, codeG); + packG = new Checkbox(" pack",Options.gen_method == Options.PACK, codeG); + + // setup interaction + ok.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + close(); + } + } ); + + defaults.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + setDefaults(); + } + } ); + + skelBrowse.addActionListener( new ActionListener() { + public void actionPerformed(ActionEvent e) { + skelBrowse(); + } + } ); + + tableG.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + setGenMethod(); + } + } ); + + verbose.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.verbose = verbose.getState(); + } + } ); + + dump.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.dump = dump.getState(); + } + } ); + + jlex.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.jlex = jlex.getState(); + } + } ); + + no_minimize.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.no_minimize = no_minimize.getState(); + } + } ); + + no_backup.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.no_backup = no_backup.getState(); + } + } ); + + dot.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.dot = dot.getState(); + } + } ); + + time.addItemListener( new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Options.time = time.getState(); + } + } ); + + // setup layout + GridPanel panel = new GridPanel(4,7,10,10); + panel.setInsets( new Insets(10,5,5,10) ); + + panel.add(3,0,ok); + panel.add(3,1,defaults); + + panel.add(0,0,2,1,Handles.BOTTOM,new Label("skeleton file:")); + panel.add(0,1,2,1,skelFile); + panel.add(2,1,1,1,Handles.TOP, skelBrowse); + + panel.add(0,2,1,1,Handles.BOTTOM,new Label("code:")); + panel.add(0,3,1,1,tableG); + panel.add(0,4,1,1,switchG); + panel.add(0,5,1,1,packG); + + panel.add(1,3,1,1,dump); + panel.add(1,4,1,1,verbose); + panel.add(1,5,1,1,time); + + + panel.add(2,3,1,1,no_minimize); + panel.add(2,4,1,1,no_backup); + + panel.add(3,3,1,1,jlex); + panel.add(3,4,1,1,dot); + + add("Center",panel); + + updateState(); + } + + private void skelBrowse() { + FileDialog d = new FileDialog(owner , "Choose file", FileDialog.LOAD); + d.show(); + + if (d.getFile() != null) { + File skel = new File(d.getDirectory()+d.getFile()); + try { + Skeleton.readSkelFile(skel); + skelFile.setText(skel.toString()); + } + catch (GeneratorException e) { + // do nothing + } + } + } + + private void setGenMethod() { + if ( tableG.getState() ) { + Options.gen_method = Options.TABLE; + return; + } + + if ( switchG.getState() ) { + Options.gen_method = Options.SWITCH; + return; + } + + if ( packG.getState() ) { + Options.gen_method = Options.PACK; + return; + } + } + + private void updateState() { + dump.setState(Options.dump); + verbose.setState(Options.verbose); + jlex.setState(Options.jlex); + no_minimize.setState(Options.no_minimize); + no_backup.setState(Options.no_backup); + time.setState(Options.time); + dot.setState(Options.dot); + + tableG.setState(Options.gen_method == Options.TABLE); + switchG.setState(Options.gen_method == Options.SWITCH); + packG.setState(Options.gen_method == Options.PACK); + } + + private void setDefaults() { + Options.setDefaults(); + Skeleton.readDefault(); + skelFile.setText(""); + updateState(); + } + + public void close() { + hide(); + } + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/skeleton.default b/tools/lexer/jflex-1.4/src/JFlex/skeleton.default new file mode 100644 index 000000000000..c2a807820775 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/skeleton.default @@ -0,0 +1,317 @@ + + /** 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 = ...; + + /** lexical states */ +--- lexical states, charmap + + /* 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[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + +--- isFinal list + /** 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 textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** 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; + +--- user class code + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ +--- constructor declaration + + + /** + * 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) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzPushbackPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * 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. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * 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 + */ +--- zzScanError declaration + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + +--- throws clause + } + + + /** + * 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()! + */ +--- yypushback decl (contains zzScanError exception) + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + +--- zzDoEOF + /** + * 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 + */ +--- yylex declaration + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + +--- local declarations + + while (true) { + zzMarkedPosL = zzMarkedPos; + +--- start admin (line, char, col count) + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + +--- start admin (lexstate etc) + + zzForAction: { + while (true) { + +--- next input, line, col, char count, next transition, isFinal action + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; +--- line count update + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; +--- char count update + +--- actions + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; +--- eofvalue + } + else { +--- no match + } + } + } + } + +--- main + +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/sym.java b/tools/lexer/jflex-1.4/src/JFlex/sym.java new file mode 100644 index 000000000000..f53d732ba5b6 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/sym.java @@ -0,0 +1,60 @@ + +//---------------------------------------------------- +// The following code was generated by CUP v0.10k +// Sun Nov 07 14:07:52 GMT+10:00 2004 +//---------------------------------------------------- + +package JFlex; + +/** CUP generated interface containing symbol constants. */ +public interface sym { + /* terminals */ + public static final int DELIMITER = 9; + public static final int EOFRULE = 25; + public static final int STRING_I = 45; + public static final int CHAR = 39; + public static final int CONCAT = 44; + public static final int MACROUSE = 41; + public static final int LOWERCLASS = 24; + public static final int EQUALS = 10; + public static final int CCLASSNOT = 43; + public static final int REPEAT = 31; + public static final int TILDE = 38; + public static final int CHAR_I = 46; + public static final int STAR = 32; + public static final int BAR = 34; + public static final int FULL = 16; + public static final int LOOKAHEAD = 27; + public static final int LESSTHAN = 12; + public static final int BANG = 37; + public static final int COMMA = 11; + public static final int JLETTERDIGITCLASS = 20; + public static final int PLUS = 33; + public static final int USERCODE = 30; + public static final int EOF = 0; + public static final int error = 1; + public static final int DASH = 8; + public static final int CLOSEBRACKET = 3; + public static final int HAT = 4; + public static final int JLETTERCLASS = 19; + public static final int IDENT = 29; + public static final int ACTION = 28; + public static final int CLOSECLASS = 7; + public static final int DIGITCLASS = 22; + public static final int LBRACE = 14; + public static final int REGEXPEND = 18; + public static final int OPENCLASS = 6; + public static final int OPENBRACKET = 2; + public static final int POINT = 36; + public static final int LETTERCLASS = 21; + public static final int MORETHAN = 13; + public static final int DOLLAR = 5; + public static final int RBRACE = 15; + public static final int STRING = 40; + public static final int QUESTION = 35; + public static final int UPPERCLASS = 23; + public static final int NOACTION = 26; + public static final int CCLASS = 42; + public static final int UNICODE = 17; +} + diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/AllTests.java b/tools/lexer/jflex-1.4/src/JFlex/tests/AllTests.java new file mode 100644 index 000000000000..4d765234916f --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/AllTests.java @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * jflex * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * AllTests + * + * @author Gerwin Klein + * @version $Revision: 1.4 $, $Date: 2004/04/12 10:07:48 $ + */ +public class AllTests { + + public static void main(String[] args) { + junit.textui.TestRunner.run(AllTests.class); + } + + public static Test suite() { + TestSuite suite = new TestSuite("JFlex tests"); + //$JUnit-BEGIN$ + suite.addTest(new TestSuite(AntTaskTests.class)); + suite.addTest(new TestSuite(CharClassesTest.class)); + suite.addTest(new TestSuite(EmitterTest.class)); + suite.addTest(new TestSuite(RegExpTests.class)); + suite.addTest(new TestSuite(SkeletonTest.class)); + suite.addTest(new TestSuite(PackEmitterTest.class)); + //$JUnit-END$ + return suite; + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/AntTaskTests.java b/tools/lexer/jflex-1.4/src/JFlex/tests/AntTaskTests.java new file mode 100644 index 000000000000..0be2cd20891f --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/AntTaskTests.java @@ -0,0 +1,166 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +package JFlex.tests; + +import JFlex.Options; +import JFlex.anttask.JFlexTask; +import junit.framework.TestCase; + +import java.io.File; +import java.io.IOException; + +/** + * Unit tests for the jflex ant task. + * + * @author Gerwin Klein + * @version $Revision: 1.12 $, $Date: 2004/11/06 23:03:30 $ + */ +public class AntTaskTests extends TestCase { + + private JFlexTask task; + + /** + * Constructor for AntTaskTests. + * + * @param name test case name + */ + public AntTaskTests(String name) { + super(name); + } + + /* + * @see TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + Options.setDefaults(); + task = new JFlexTask(); + } + + public void testPackageAndClass() throws IOException { + task.setFile(new File("src/JFlex/LexScan.flex")); + task.findPackageAndClass(); + assertEquals(task.getPackage(), "JFlex"); + assertEquals(task.getClassName(), "LexScan"); + } + + public void testPackageAndClassDefaults() throws IOException { + task.setFile(new File("examples/simple/simple.flex")); + task.findPackageAndClass(); + assertEquals(task.getPackage(), null); + assertEquals(task.getClassName(), "Yylex"); + } + + public void testDestdir() throws IOException { + task.setFile(new File("src/JFlex/LexScan.flex")); + File dir = new File("src"); + task.setDestdir(dir); + task.findPackageAndClass(); + task.normalizeOutdir(); + // not default jflex logic, but javac (uses package name) + assertEquals(Options.getDir(), new File(dir, "JFlex")); + } + + public void testOutdir() throws IOException { + task.setFile(new File("src/JFlex/LexScan.flex")); + File dir = new File("src"); + task.setOutdir(dir); + task.findPackageAndClass(); + task.normalizeOutdir(); + // this should be default jflex logic + assertEquals(Options.getDir(), dir); + } + + public void testDefaultDir() throws IOException { + task.setFile(new File("src/JFlex/LexScan.flex")); + task.findPackageAndClass(); + task.normalizeOutdir(); + // this should be default jflex logic + assertEquals(Options.getDir(), new File("src/JFlex")); + } + + public void testNomin() { + assertTrue(!Options.no_minimize); + task.setNomin(true); + assertTrue(Options.no_minimize); + } + + public void testSkipMinimization() { + assertTrue(!Options.no_minimize); + task.setSkipMinimization(true); + assertTrue(Options.no_minimize); + } + + public void testNobak() { + assertTrue(!Options.no_backup); + task.setNobak(true); + assertTrue(Options.no_backup); + } + + public void testCodeGen() { + task.setSwitch(true); + assertEquals(Options.gen_method, Options.SWITCH); + task.setTable(true); + assertEquals(Options.gen_method, Options.TABLE); + task.setPack(true); + assertEquals(Options.gen_method, Options.PACK); + } + + public void testSkel() { + task.setVerbose(false); // avoid to java console pop up + task.setSkeleton(new File("src/skeleton.nested")); + assertTrue(JFlex.Skeleton.line[3].indexOf("java.util.Stack") > 0); + } + + public void testVerbose() { + task.setVerbose(false); + assertTrue(!Options.verbose); + task.setVerbose(true); + assertTrue(Options.verbose); + } + + public void testTime() { + assertTrue(!Options.time); + task.setTimeStatistics(true); + assertTrue(Options.time); + task.setTime(false); + assertTrue(!Options.time); + } + + public void testDot() { + assertTrue(!Options.dot); + task.setDot(true); + assertTrue(Options.dot); + task.setGenerateDot(false); + assertTrue(!Options.dot); + } + + public void testDump() { + assertTrue(!Options.dump); + task.setDump(true); + assertTrue(Options.dump); + } + + public void testJlex() { + assertTrue(!Options.jlex); + task.setJLex(true); + assertTrue(Options.jlex); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/CharClassesTest.java b/tools/lexer/jflex-1.4/src/JFlex/tests/CharClassesTest.java new file mode 100644 index 000000000000..a3c283d572b2 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/CharClassesTest.java @@ -0,0 +1,103 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + +import JFlex.IntCharSet; +import JFlex.Interval; +import junit.framework.TestCase; + +/** + * CharClassesTest + * + * @author Gerwin Klein + * @version $Revision: 1.6 $, $Date: 2004/11/06 23:03:30 $ + */ +public class CharClassesTest extends TestCase { + + /** + * Constructor for CharClassesTest. + * @param arg0 + */ + public CharClassesTest(String arg0) { + super(arg0); + } + + public void testAdd1() { + IntCharSet set = new IntCharSet(new Interval('a','h')); + set.add(new Interval('o','z')); + set.add(new Interval('A','Z')); + set.add(new Interval('h','o')); + assertEquals("{ ['A'-'Z']['a'-'z'] }", set.toString()); + } + + public void testAdd2() { + IntCharSet set = new IntCharSet(new Interval('a','h')); + set.add(new Interval('o','z')); + set.add(new Interval('A','Z')); + set.add(new Interval('i','n')); + assertEquals("{ ['A'-'Z']['a'-'z'] }", set.toString()); + } + + public void testAdd3() { + IntCharSet set = new IntCharSet(new Interval('a','h')); + set.add(new Interval('o','z')); + set.add(new Interval('A','Z')); + set.add(new Interval('a','n')); + assertEquals("{ ['A'-'Z']['a'-'z'] }", set.toString()); + } + + public void testMergeLast() { + IntCharSet set = new IntCharSet(new Interval('a','k')); + assertEquals("{ ['a'-'k'] }", set.toString()); + set.add('l'); + assertEquals("{ ['a'-'l'] }", set.toString()); + } + + public void testAddChar() { + IntCharSet set = new IntCharSet(new Interval('a','h')); + set.add(new Interval('o','z')); + set.add('n'); + set.add('k'); + assertEquals("{ ['a'-'h']['k']['n'-'z'] }", set.toString()); + set.add('i'); + assertEquals("{ ['a'-'i']['k']['n'-'z'] }", set.toString()); + set.add('j'); + assertEquals("{ ['a'-'k']['n'-'z'] }", set.toString()); + set.add(new Interval('l','m')); + assertEquals("{ ['a'-'z'] }", set.toString()); + } + + public void testCopy() { + IntCharSet set = new IntCharSet(new Interval('a','z')); + IntCharSet copy = set.copy(); + Interval i = set.getNext(); + i.end = 'h'; + assertEquals("{ ['a'-'h'] }", set.toString()); + assertEquals("{ ['a'-'z'] }", copy.toString()); + } + + public void testCaseless() { + IntCharSet set = new IntCharSet(new Interval('a','c')); + set.add(new Interval('h','o')); + assertEquals("{ ['A'-'C']['H'-'O']['a'-'c']['h'-'o'] }", + set.getCaseless().toString()); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/EmitterTest.java b/tools/lexer/jflex-1.4/src/JFlex/tests/EmitterTest.java new file mode 100644 index 000000000000..61fe03fb737a --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/EmitterTest.java @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + +import JFlex.Emitter; +import junit.framework.TestCase; + +/** + * Some unit tests for the jflex Emitter class + * + * @author Gerwin Klein + * @version $Revision: 1.5 $, $Date: 2004/11/06 23:03:30 $ + */ +public class EmitterTest extends TestCase { + + /** + * Constructor for EmitterTest. + * @param name the test name + */ + public EmitterTest(String name) { + super(name); + } + + public void testJavadoc() { + StringBuffer usercode = new StringBuffer("/* some *** comment */"); + assertTrue(!Emitter.endsWithJavadoc(usercode)); + usercode.append("import bla; /** javadoc /* */ "); + assertTrue(Emitter.endsWithJavadoc(usercode)); + usercode.append("bla"); + assertTrue(!Emitter.endsWithJavadoc(usercode)); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/PackEmitterTest.java b/tools/lexer/jflex-1.4/src/JFlex/tests/PackEmitterTest.java new file mode 100644 index 000000000000..9329c7026c84 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/PackEmitterTest.java @@ -0,0 +1,80 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * jflex * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + +import JFlex.Out; +import JFlex.PackEmitter; +import junit.framework.TestCase; + +/** + * PackEmitterTest + * + * @author Gerwin Klein + * @version $Revision: 1.7 $, $Date: 2004/04/12 10:07:48 $ + */ +public class PackEmitterTest extends TestCase { + + private PackEmitter p; + + + /** + * Constructor for PackEmitterTest. + */ + public PackEmitterTest() { + super("PackEmitter test"); + } + + public void setUp() { + p = new PackEmitter("Bla") { + public void emitUnpack() { } + }; + } + + public void testInit() { + p.emitInit(); + assertEquals( + " private static final int [] ZZ_BLA = zzUnpackBla();" + Out.NL + + Out.NL + + " private static final String ZZ_BLA_PACKED_0 =" + Out.NL + + " \"", + p.toString()); + } + + public void testEmitUCplain() { + p.emitUC(8); + p.emitUC(0xFF00); + + assertEquals("\\10\\uff00", p.toString()); + } + + public void testLineBreak() { + for (int i = 0; i < 36; i++) { + p.breaks(); + p.emitUC(i); + } + System.out.println(p); + assertEquals( + "\\0\\1\\2\\3\\4\\5\\6\\7\\10\\11\\12\\13\\14\\15\\16\\17\"+"+Out.NL+ + " \"\\20\\21\\22\\23\\24\\25\\26\\27\\30\\31\\32\\33\\34\\35\\36\\37\"+"+Out.NL+ + " \"\\40\\41\\42\\43", + p.toString()); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/RegExpTests.java b/tools/lexer/jflex-1.4/src/JFlex/tests/RegExpTests.java new file mode 100644 index 000000000000..652b9bfd7d47 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/RegExpTests.java @@ -0,0 +1,58 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + +import JFlex.*; +import junit.framework.TestCase; + +/** + * Unit tests for JFlex.RegExp + * + * @author Gerwin Klein + * @version $Revision: 1.5 $, $Date: 2004/11/06 23:03:30 $ + */ +public class RegExpTests extends TestCase implements sym { + + /** + * Constructor for RegExpTests. + * + * @param name the test name + */ + public RegExpTests(String name) { + super(name); + } + + public void testCharClass() { + Macros m = new Macros(); + RegExp e1 = new RegExp1(CCLASS, new Interval('a','z')); + RegExp e2 = new RegExp1(CHAR, new Character('Z')); + RegExp e3 = new RegExp1(CCLASS, new Interval('0','9')); + m.insert("macro", e3); + RegExp s = new RegExp1(STAR, e1); + RegExp u = new RegExp1(MACROUSE, "macro"); + RegExp b = new RegExp2(BAR, e2, u); + assertTrue(e1.isCharClass(m)); + assertTrue(e2.isCharClass(m)); + assertTrue(b.isCharClass(m)); + assertTrue(!s.isCharClass(m)); + assertTrue(u.isCharClass(m)); + } +} diff --git a/tools/lexer/jflex-1.4/src/JFlex/tests/SkeletonTest.java b/tools/lexer/jflex-1.4/src/JFlex/tests/SkeletonTest.java new file mode 100644 index 000000000000..f09837275bf0 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/JFlex/tests/SkeletonTest.java @@ -0,0 +1,63 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.4.1 * + * Copyright (C) 1998-2004 Gerwin Klein * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License. See the file * + * COPYRIGHT for more information. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package JFlex.tests; + + +import JFlex.Skeleton; +import junit.framework.TestCase; + +import java.io.File; + +/** + * SkeletonTest + * + * @author Gerwin Klein + * @version $Revision: 1.4 $, $Date: 2004/11/06 23:03:30 $ + */ +public class SkeletonTest extends TestCase { + + /** + * Constructor for SkeletonTest. + * @param arg0 test name + */ + public SkeletonTest(String arg0) { + super(arg0); + } + + public void testReplace() { + assertEquals(Skeleton.replace("bla ", "blub", "bla blub bla "), + "blubblub blub"); + } + + public void testMakePrivate() { + Skeleton.makePrivate(); + for (int i=0; i < Skeleton.line.length; i++) { + assertEquals(Skeleton.line[i].indexOf("public"), -1); + } + } + + public void testDefault() { + Skeleton.readSkelFile(new File("src/skeleton.nested")); + assertTrue(JFlex.Skeleton.line[3].indexOf("java.util.Stack") > 0); + Skeleton.readDefault(); + assertEquals(JFlex.Skeleton.line[3].indexOf("java.util.Stack"), -1); + } +} diff --git a/tools/lexer/jflex-1.4/src/README b/tools/lexer/jflex-1.4/src/README new file mode 100644 index 000000000000..84ec73be8826 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/README @@ -0,0 +1,63 @@ +This directory contains the source code for JFlex. + +For your convenience, the following generated lexer and parser files +are included in the distribution: + +JFlex/LexScan.java (lexer, generated from src/LexScan.flex) +JFlex/LexParse.java (parser, generated from src/LexParse.cup) +JFlex/sym.java (parser symbols, generated from src/LexParse.cup) + + +Dependencies: +If you just want to compile the JFlex sources, no further tools are +necessary. If you want to compile the ant task, you need the ant +classes in you class path, if you want to compile the unit tests, you +need the junit classes in yor class path. + +To build everything from scratch: +In class path: +junit.jar >= 3.8.1 [http://www.junit.org/] +ant.jar >= 1.4 [optional, http://ant.apache.org/] +In ant lib dir: +java_cup.jar >= 0.10l [http://www.cs.princeton.edu/~appel/modern/java/CUP/] +JFlex.jar >= 1.4pre1 [http://www.jflex.de/] + + +Dir contents: +build.xml: + for use with the ant build tool [http://ant.apache.org/] + + Useful targets are: + jar: recompiles all JFlex classes, generates lexer+parser + only if necessary, zips up all compiled classes in + ../lib/JFlex.jar + + build: cleans up everything and does a completely new build + + realclean: deletes generated, temporary and *.class files + +manifest: + jar manifest file for JFlex.jar + +skeleton: + a skeleton file matching exactly the precompiled scanner skeleton. + Can be used together with the --skel option + +skeleton.nested: + a skeleton file that supports nested input streams (see the manual + for the API). Can be used together with the --skel option + +JFlex: + source files of package JFlex + +JFlex/gui: + source files of package JFlex.gui + +JFlex/anttask + source files of the JFlex Ant task (contributed by Rafal Mantiuk) + +JFlex/test + unit tests for JFlex + +java_cup/runtime: + CUP v0.10k runtime classes, used by JFlex \ No newline at end of file diff --git a/tools/lexer/jflex-1.4/src/build.xml b/tools/lexer/jflex-1.4/src/build.xml new file mode 100644 index 000000000000..047cf4138d90 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/build.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/lexer/jflex-1.4/src/changelog b/tools/lexer/jflex-1.4/src/changelog new file mode 100644 index 000000000000..fafbbea8f8de --- /dev/null +++ b/tools/lexer/jflex-1.4/src/changelog @@ -0,0 +1,255 @@ +* JFlex 1.4.1 (November 7, 2004) +- merged in patch by Don Brown (fixes #1049791 Uses Old JUnit method assertFalse) +- merged in patch by Don Brown (fixes #887821 buffer expansion bug in yy_refill()) + Thanks to Binesh Bannerjee for providing a simpler test case for this problem. +- fixed bug #1035407 (ArrayIndexOutOfBounds in IntCharSet) +- fixed bug #1003569 (Cannot use lookahead with ignorecase) +- converted dangerous lookahead error to warning +- print info for EOF actions as well in %debug mode +- fixed line number count for EOF actions +- internal: removed unused methods in LexScan.flex and IntCharSet + +* JFlex 1.4 (April 12, 2004) +- new, very fast minimization algorithm (also fixes memory issues) +- new --jlex option for strict compatibility to JLex. Currently it + changes %ignorecase to JLex semantics, that is, character classes + are interpreted in a caseless way, too. + (fixes bus #751757, %ignorecase ignored by char classes). + Thanks to Edward D. Willink for spotting the incompatibility. +- support for even larger scanners (up to 64K DFA states). + Thanks to Karin Vespoor. +- removed eclipse compiler warnings for generated classes + (feature request #778747) +- implemented faster character classes (feature request #604589). + Expressions like [a-z] | [A-Z] are interpreted as one atomic class + [a-zA-Z], reducing NFA states and generation time significantly + for some specifications. This affects the generation process only, + generated scanners remain the same. +- new %apiprivate switch (feature request #513500/1) that causes all + generated and skeleton methods to be made private. Exceptions to this + are user defined functions and the constructor. Thanks to Stephen + Ostermiller for the suggestion. +- allow user defined javadoc class comments (feature request #513500/2) + If the user code section ends with a javadoc comment, JFlex takes this + instead of the generated comment. Thanks to Stephen Ostermiller for + the suggestion. +- fixed bug #491095 (undefined macros in complement expressions do + not throw exception in generator). Thanks to Stephen Ostermiller + for the bug report. +- fixed bug #495422 (yypushStream/yypopStream in skeleton.nested + work as advertised) +- fixed bug #611118 (no wrong macro warnings on regexp negation) +- fixed bug #655528 (%cupsym now also affects %cupdebug) + Thanks to Eric Schweitz for the fix. +- fixed bug #510010 (single-line %initthrow works now + in case of extra whitespace before newline) +- yyreset() does no longer close the associated reader (use yyclose() + explicitly for that). Makes some reader objects reusable (feature + request #513492). Thanks to Stephen Ostermiller for the suggestion. +- fixed modifier order in generated code, removes jikes compiler warnings + Thanks to Michael Wildpaner for the fix. +- ant task now also works with ant >= 1.4 (fixes bug #526905) +- yyreset() does not declare an execption any more (fixes bug #913132) +- %cup does not include %eofclose in JLex mode (--jlex). (Fixes bug #910562) +- optional parameter to %eofclose: "%eofclose false" turns off %eofclose if + it was turned on previously (e.g. by %cup). (Fixes bug #910562) +- jflex build script switched to ant +- internal: central Options class for better integration with + build tools and IDEs +- internal: change naming scheme for generated internal variables from + yy_ to zz to comply with Java naming standard. Thanks to Max Gilead + for the patch. + + +* JFlex 1.3.5 (October 8, 2001) +- fixed all bugs reported for version 1.3.4. Thanks to + Amin Ahmad and Fred Wehrhahn for their excellent bug reports. +- implemented feature request #459014: vim syntax file. + Thanks to Michael Brailsford for his help and suggestions. +- JFlex should run with JDK 1.1 out-of-the-box again. + + +* JFlex 1.3.4 (October 1, 2001) +- fixed all bugs reported for version 1.3.3. Thanks to Mike Akerman + for his excellent bug reports and his help. +- implemented feature request #459355: exclusive start states. + Thanks to Ed Beroset for the suggestion. +- introduced %s and %x shorthands for state declarations + + +* JFlex 1.3.3 (September 21, 2001) +- fixed all reported bugs except #39 (lookahead check at generation + time may fail). Thanks to Axel Schwolow, Karl Meissner, Angelo + Borsotti, and Paolo Di Francesco for their excellent bug reports. +- enhanced %debug output. JFlex scanners in debug mode now print line, + column, matched text, and executed action (with line number in spec) + for each processed token. Thanks to + Karl Meissner for the + suggestion. +- introduced %cupdebug directive for readable CUP debugging. Generated + scanners print line, column, matched text, and CUP symbol name for + each returned token. Again thanks to Karl Meissner for tips and + contributed Java reflection code. +- new %cupsym to customize CUP generated symbols class name. Thanks + to Karl Meissner and Paolo Di Francesco. +- new %throws as shorthand for %yylexthrow +- code generation now customizable at command line with --table, + --pack, and --switch +- command line switch --info prints system and JVM information (useful + for bug reports) +- command line switch --nobak for not generating backup files +- an Ant task for the Ant build tool http://jakarta.apache.org/ant/ + contributed by Rafal Mantiuk. Many thanks to him. +- better error message for missing ] in char class. Thanks to Karl + Meissner. +- performance enhancements in the runtime system. The engine is now + 10%-50% faster. These are only the first implementations of a few of + the many suggestions from Angelo Borsotti. Thanks to Angelo for many + insights, tips, and fruitful discussions. +- a new warning if a rule can never be matched +- macros and regular expression can now span multiple lines (note + that | at the end of a line in a rule is a special action, + not the | operator) +- updated the manual to contain more information about the generated + class, clarified the description of lexical states. Thanks to Michael + Binz, Angelo Borsotti, Vasily Karyaev and for the suggestions. +- Simplified java example lexer, and allow // style comments at EOF. + Thanks to Thomas Mulcahy. +- Byacc/J example updated to version 1.1 +- New interpreter example using CUP. Thanks to Bernhard Rumpe for + the code. + + +* JFlex 1.3.2 (February 24, 2001) +- fixed bug #32 (this time for real). Thanks to Thilo Goetz for + his quick report. +- updated the binary scanning example with the more comprehensive and + usable class StraightStreamReader by Stephen Ostermiller. Thanks go to + him for his contribution. The original version of this class is at + http://www.smo.f2s.com/utils/ +- added a link to a Japanese translation of the JFlex manual (it's in Japanese + Shift_JIS encoding). The translation is for an older release (1.1.2), but + most of the text still applies to the current version. See the change log + for the differences between 1.1.2 and the current version. Many thanks to + Yuichi Nakajima, Yukio Ikeda, Katsuhiko Yamazaki, and Koji Ooya for + their efforts. + If you would like to translate the JFlex manual into another language, or + if you already have done so, please let me know. I will include a link to + it on the documentation page. I can also give you access to the latex + sources of the manual, so that printable versions of your translation can + be generated, too. + + +* JFlex 1.3.1 (February 20, 2001) +- fixed all JFlex bugs reported for 1.3 (bugs #32-#36) + Thanks to Hans Kratz, Vasily Karyaev, Alexey Yakovets, and Tom Moog for + their excellent reports. +- added two new example scanners: + . a demonstration how to scan binary files + . a small calculator example for Cup, based on the example in the Linux + Gazette by Richard A. Sevenich and Christopher Lopes. See also + http://www.linuxgazette.com/issue39/sevenich.html + http://www.linuxgazette.com/issue41/sevenich.html + http://www.linuxgazette.com/issue41/lopes/lopes.html +- manual section about encodings, platforms and Unicode. + Thanks to Stephen Ostermiller for his valuable input. +- switch for skipping the minimization step in DFA generation (--nomin). + This feature is still in alpha status and not yet extensively tested. It + might be useful when you have very large scanners and not much memory + available. +- switch for generating graphviz dot files for graphical representation (ps + or gif) of generated NFA, DFA and minimized DFA (--dot). Might be useful for + teaching. This feature is also still in alpha status and not fully finished + yet. It is included as preview, comments are welcome, please try it out and + tell me what you think. For information on graphviz see + http://www.research.att.com:80/sw/tools/graphviz/ +- changed to --style long command line switches (single - still recognized). +- moved part of the project to http://sourceforge.net/projects/jflex/ + + +* JFlex 1.3 (October 21, 2000) + +- Fixed all bugs reported for 1.2.2 (bugs #23-#27). +- Better start script for Linux. +- Customize for internal error handling in yy_ScanError. +- Empty charclass [], and any (=negated empty) charclass [^]. +- New negation operator ! for regexps. +- New upto operator ~ for regexps. +- Customizable buffer size (%buffer). +- New char yycharat(int) for efficient access to single characters in matched text. +- Split up of too large lex tables for even larger scanner sizes. +- New additional external skeleton with support for nested input streams. +- JLex compatibility: BOL ^ and EOL $ use unicode line separators as in + http://www.unicode.org/unicode/reports/tr18/tr18-5.1.html. +- New resetStream method for reusing scanner objects. +_ BYacc/J support (%byaccj) + BYacc/J example. +- Include files in lexer specs (%include). +- New --dump switch for a dump of the generated charclasses, NFA, DFA, and minimized DFA tables. + + +* JFlex 1.2.2 (August 23, 1999) +- Updated JFlex to the new CUP version 0.10j. +- Eliminated some remaining platform dependent newlines in the generated source code + (affecting the readabilty of the generated code only, no functional changes). +- Minor improvements in error reporting (out of memory). +- Added a --version command line option for printing the current jflex version. +- Updated the Java 1.2 lexer/parser example to CUP 0.10j. + + +* JFlex 1.2.1 (June 25, 1999) +- Fixed all bugs reported for version 1.2 (#19-#22). +- Webpage redesigned and moved to http://www.jflex.de. +- Example java lexer/parser switched to Java 1.2. + + +* JFlex 1.2 (March 21, 1999) +- Fixed all bugs for 1.1.2. +- JFlex now works again with Solaris JIT. +- Significant Unicode optimizations in scanning and generation performance, +- changed the empty string match wrt. EOF behavior to the one that is commonly expected. +- added command line switches for more customization +- external skeleton files +- new GUI without any console output +- <> as in lex/flex +- better error messages +- better generation speed +- better generation memory efficiency +- | Action, trailing context (/ operator) +- new %final, %abstract and %extends directives +- uses jar file +- included makefile for JFlex, +- %pack now uses string packing, +- %pack now default code generation method, +- new %switch directive for old default code generation method, +- more convenient declaration of exceptions, +- new %int switch, +- manual now written in latex, available as html and in printable .ps.gz and pdf file formats. + + +* JFlex 1.1.2 +- All bugs reported for version 1.1.1 (#8-#10) have been fixed. + + +* JFlex 1.1.1 +- All bugs reported for version 1.1 (i.e. bug #7 and feature request #6) have been fixed. +- Scanning speed was optimized further. + + +* JFlex 1.1 adds new features and fixes all known bugs of 1.0 +- Revised directory structure. +- Fixed all reported bugs (#1-#5 and some unreported ones). +- Fixed thousands of typos in the manual. +- whitespace characters in regular expressions, +- flex style repeat expressions, +- %caseless switch, +- %eofclose switch, +- method for closing the input stream, +- method for the current lexical state, +- method for rereading matched text, +- backup of files that are overwitten in the generation process, +- improved error reporting, +- graphical UI when no filename is provided on the commandline + + +* JFlex 1.0 (May 1998) was the first public release of JFlex. + It was developed using Sun's JDK 1.1, JFlex (bootstrapped) and the parser generator CUP \ No newline at end of file diff --git a/tools/lexer/jflex-1.4/src/java_cup/runtime/Scanner.java b/tools/lexer/jflex-1.4/src/java_cup/runtime/Scanner.java new file mode 100644 index 000000000000..32335516f082 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/java_cup/runtime/Scanner.java @@ -0,0 +1,25 @@ +package java_cup.runtime; + +/** + * Defines the Scanner interface, which CUP uses in the default + * implementation of lr_parser.scan(). Integration + * of scanners implementing Scanner is facilitated. + * + * @version last updated 23-Jul-1999 + * @author David MacMahon + */ + +/* ************************************************* + Interface Scanner + + Declares the next_token() method that should be + implemented by scanners. This method is typically + called by lr_parser.scan(). End-of-file can be + indicated either by returning + new Symbol(lr_parser.EOF_sym()) or + null. + ***************************************************/ +public interface Scanner { + /** Return the next token, or null on end-of-file. */ + public Symbol next_token() throws java.lang.Exception; +} diff --git a/tools/lexer/jflex-1.4/src/java_cup/runtime/Symbol.java b/tools/lexer/jflex-1.4/src/java_cup/runtime/Symbol.java new file mode 100644 index 000000000000..eeb6a0b4c6d6 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/java_cup/runtime/Symbol.java @@ -0,0 +1,105 @@ +package java_cup.runtime; + +/** + * Defines the Symbol class, which is used to represent all terminals + * and nonterminals while parsing. The lexer should pass CUP Symbols + * and CUP returns a Symbol. + * + * @version last updated: 7/3/96 + * @author Frank Flannery + */ + +/* **************************************************************** + Class Symbol + what the parser expects to receive from the lexer. + the token is identified as follows: + sym: the symbol type + parse_state: the parse state. + value: is the lexical value of type Object + left : is the left position in the original input file + right: is the right position in the original input file +******************************************************************/ + +public class Symbol { + +/******************************* + Constructor for l,r values + *******************************/ + + public Symbol(int id, int l, int r, Object o) { + this(id); + left = l; + right = r; + value = o; + } + +/******************************* + Constructor for no l,r values +********************************/ + + public Symbol(int id, Object o) { + this(id, -1, -1, o); + } + +/***************************** + Constructor for no value + ***************************/ + + public Symbol(int id, int l, int r) { + this(id, l, r, null); + } + +/*********************************** + Constructor for no value or l,r +***********************************/ + + public Symbol(int sym_num) { + this(sym_num, -1); + left = -1; + right = -1; + value = null; + } + +/*********************************** + Constructor to give a start state +***********************************/ + Symbol(int sym_num, int state) + { + sym = sym_num; + parse_state = state; + } + +/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The symbol number of the terminal or non terminal being represented */ + public int sym; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The parse state to be recorded on the parse stack with this symbol. + * This field is for the convenience of the parser and shouldn't be + * modified except by the parser. + */ + public int parse_state; + /** This allows us to catch some errors caused by scanners recycling + * symbols. For the use of the parser only. [CSA, 23-Jul-1999] */ + boolean used_by_parser = false; + +/******************************* + The data passed to parser + *******************************/ + + public int left, right; + public Object value; + + /***************************** + Printing this token out. (Override for pretty-print). + ****************************/ + public String toString() { return "#"+sym; } +} + + + + + + diff --git a/tools/lexer/jflex-1.4/src/java_cup/runtime/lr_parser.java b/tools/lexer/jflex-1.4/src/java_cup/runtime/lr_parser.java new file mode 100644 index 000000000000..3c8335cb2524 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/java_cup/runtime/lr_parser.java @@ -0,0 +1,1238 @@ + +package java_cup.runtime; + +import java.util.Stack; + +/** This class implements a skeleton table driven LR parser. In general, + * LR parsers are a form of bottom up shift-reduce parsers. Shift-reduce + * parsers act by shifting input onto a parse stack until the Symbols + * matching the right hand side of a production appear on the top of the + * stack. Once this occurs, a reduce is performed. This involves removing + * the Symbols corresponding to the right hand side of the production + * (the so called "handle") and replacing them with the non-terminal from + * the left hand side of the production.

+ * + * To control the decision of whether to shift or reduce at any given point, + * the parser uses a state machine (the "viable prefix recognition machine" + * built by the parser generator). The current state of the machine is placed + * on top of the parse stack (stored as part of a Symbol object representing + * a terminal or non terminal). The parse action table is consulted + * (using the current state and the current lookahead Symbol as indexes) to + * determine whether to shift or to reduce. When the parser shifts, it + * changes to a new state by pushing a new Symbol (containing a new state) + * onto the stack. When the parser reduces, it pops the handle (right hand + * side of a production) off the stack. This leaves the parser in the state + * it was in before any of those Symbols were matched. Next the reduce-goto + * table is consulted (using the new state and current lookahead Symbol as + * indexes) to determine a new state to go to. The parser then shifts to + * this goto state by pushing the left hand side Symbol of the production + * (also containing the new state) onto the stack.

+ * + * This class actually provides four LR parsers. The methods parse() and + * debug_parse() provide two versions of the main parser (the only difference + * being that debug_parse() emits debugging trace messages as it parses). + * In addition to these main parsers, the error recovery mechanism uses two + * more. One of these is used to simulate "parsing ahead" in the input + * without carrying out actions (to verify that a potential error recovery + * has worked), and the other is used to parse through buffered "parse ahead" + * input in order to execute all actions and re-synchronize the actual parser + * configuration.

+ * + * This is an abstract class which is normally filled out by a subclass + * generated by the JavaCup parser generator. In addition to supplying + * the actual parse tables, generated code also supplies methods which + * invoke various pieces of user supplied code, provide access to certain + * special Symbols (e.g., EOF and error), etc. Specifically, the following + * abstract methods are normally supplied by generated code: + *

+ *
short[][] production_table() + *
Provides a reference to the production table (indicating the index of + * the left hand side non terminal and the length of the right hand side + * for each production in the grammar). + *
short[][] action_table() + *
Provides a reference to the parse action table. + *
short[][] reduce_table() + *
Provides a reference to the reduce-goto table. + *
int start_state() + *
Indicates the index of the start state. + *
int start_production() + *
Indicates the index of the starting production. + *
int EOF_sym() + *
Indicates the index of the EOF Symbol. + *
int error_sym() + *
Indicates the index of the error Symbol. + *
Symbol do_action() + *
Executes a piece of user supplied action code. This always comes at + * the point of a reduce in the parse, so this code also allocates and + * fills in the left hand side non terminal Symbol object that is to be + * pushed onto the stack for the reduce. + *
void init_actions() + *
Code to initialize a special object that encapsulates user supplied + * actions (this object is used by do_action() to actually carry out the + * actions). + *
+ * + * In addition to these routines that must be supplied by the + * generated subclass there are also a series of routines that may + * be supplied. These include: + *
+ *
Symbol scan() + *
Used to get the next input Symbol from the scanner. + *
Scanner getScanner() + *
Used to provide a scanner for the default implementation of + * scan(). + *
int error_sync_size() + *
This determines how many Symbols past the point of an error + * must be parsed without error in order to consider a recovery to + * be valid. This defaults to 3. Values less than 2 are not + * recommended. + *
void report_error(String message, Object info) + *
This method is called to report an error. The default implementation + * simply prints a message to System.err and where the error occurred. + * This method is often replaced in order to provide a more sophisticated + * error reporting mechanism. + *
void report_fatal_error(String message, Object info) + *
This method is called when a fatal error that cannot be recovered from + * is encountered. In the default implementation, it calls + * report_error() to emit a message, then throws an exception. + *
void syntax_error(Symbol cur_token) + *
This method is called as soon as syntax error is detected (but + * before recovery is attempted). In the default implementation it + * invokes: report_error("Syntax error", null); + *
void unrecovered_syntax_error(Symbol cur_token) + *
This method is called if syntax error recovery fails. In the default + * implementation it invokes:
+ * report_fatal_error("Couldn't repair and continue parse", null); + *
+ * + * @see java_cup.runtime.Symbol + * @see java_cup.runtime.Symbol + * @see java_cup.runtime.virtual_parse_stack + * @version last updated: 7/3/96 + * @author Frank Flannery + */ + +public abstract class lr_parser { + + /*-----------------------------------------------------------*/ + /*--- Constructor(s) ----------------------------------------*/ + /*-----------------------------------------------------------*/ + + /** Simple constructor. */ + public lr_parser() + { + /* nothing to do here */ + } + + /** Constructor that sets the default scanner. [CSA/davidm] */ + public lr_parser(Scanner s) { + this(); /* in case default constructor someday does something */ + setScanner(s); + } + + /*-----------------------------------------------------------*/ + /*--- (Access to) Static (Class) Variables ------------------*/ + /*-----------------------------------------------------------*/ + + /** The default number of Symbols after an error we much match to consider + * it recovered from. + */ + protected final static int _error_sync_size = 3; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The number of Symbols after an error we much match to consider it + * recovered from. + */ + protected int error_sync_size() {return _error_sync_size; } + + /*-----------------------------------------------------------*/ + /*--- (Access to) Instance Variables ------------------------*/ + /*-----------------------------------------------------------*/ + + /** Table of production information (supplied by generated subclass). + * This table contains one entry per production and is indexed by + * the negative-encoded values (reduce actions) in the action_table. + * Each entry has two parts, the index of the non-terminal on the + * left hand side of the production, and the number of Symbols + * on the right hand side. + */ + public abstract short[][] production_table(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The action table (supplied by generated subclass). This table is + * indexed by state and terminal number indicating what action is to + * be taken when the parser is in the given state (i.e., the given state + * is on top of the stack) and the given terminal is next on the input. + * States are indexed using the first dimension, however, the entries for + * a given state are compacted and stored in adjacent index, value pairs + * which are searched for rather than accessed directly (see get_action()). + * The actions stored in the table will be either shifts, reduces, or + * errors. Shifts are encoded as positive values (one greater than the + * state shifted to). Reduces are encoded as negative values (one less + * than the production reduced by). Error entries are denoted by zero. + * + * @see java_cup.runtime.lr_parser#get_action + */ + public abstract short[][] action_table(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The reduce-goto table (supplied by generated subclass). This + * table is indexed by state and non-terminal number and contains + * state numbers. States are indexed using the first dimension, however, + * the entries for a given state are compacted and stored in adjacent + * index, value pairs which are searched for rather than accessed + * directly (see get_reduce()). When a reduce occurs, the handle + * (corresponding to the RHS of the matched production) is popped off + * the stack. The new top of stack indicates a state. This table is + * then indexed by that state and the LHS of the reducing production to + * indicate where to "shift" to. + * + * @see java_cup.runtime.lr_parser#get_reduce + */ + public abstract short[][] reduce_table(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the start state (supplied by generated subclass). */ + public abstract int start_state(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the start production (supplied by generated subclass). */ + public abstract int start_production(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the end of file terminal Symbol (supplied by generated + * subclass). + */ + public abstract int EOF_sym(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the special error Symbol (supplied by generated subclass). */ + public abstract int error_sym(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Internal flag to indicate when parser should quit. */ + protected boolean _done_parsing = false; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method is called to indicate that the parser should quit. This is + * normally called by an accept action, but can be used to cancel parsing + * early in other circumstances if desired. + */ + public void done_parsing() + { + _done_parsing = true; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + /* Global parse state shared by parse(), error recovery, and + * debugging routines */ + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Indication of the index for top of stack (for use by actions). */ + protected int tos; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The current lookahead Symbol. */ + protected Symbol cur_token; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The parse stack itself. */ + protected Stack stack = new Stack(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Direct reference to the production table. */ + protected short[][] production_tab; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Direct reference to the action table. */ + protected short[][] action_tab; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Direct reference to the reduce-goto table. */ + protected short[][] reduce_tab; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This is the scanner object used by the default implementation + * of scan() to get Symbols. To avoid name conflicts with existing + * code, this field is private. [CSA/davidm] */ + private Scanner _scanner; + + /** + * Simple accessor method to set the default scanner. + */ + public void setScanner(Scanner s) { _scanner = s; } + + /** + * Simple accessor method to get the default scanner. + */ + public Scanner getScanner() { return _scanner; } + + /*-----------------------------------------------------------*/ + /*--- General Methods ---------------------------------------*/ + /*-----------------------------------------------------------*/ + + /** Perform a bit of user supplied action code (supplied by generated + * subclass). Actions are indexed by an internal action number assigned + * at parser generation time. + * + * @param act_num the internal index of the action to be performed. + * @param parser the parser object we are acting for. + * @param stack the parse stack of that object. + * @param top the index of the top element of the parse stack. + */ + public abstract Symbol do_action( + int act_num, + lr_parser parser, + Stack stack, + int top) + throws java.lang.Exception; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** User code for initialization inside the parser. Typically this + * initializes the scanner. This is called before the parser requests + * the first Symbol. Here this is just a placeholder for subclasses that + * might need this and we perform no action. This method is normally + * overridden by the generated code using this contents of the "init with" + * clause as its body. + */ + public void user_init() throws java.lang.Exception { } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Initialize the action object. This is called before the parser does + * any parse actions. This is filled in by generated code to create + * an object that encapsulates all action code. + */ + protected abstract void init_actions() throws java.lang.Exception; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Get the next Symbol from the input (supplied by generated subclass). + * Once end of file has been reached, all subsequent calls to scan + * should return an EOF Symbol (which is Symbol number 0). By default + * this method returns getScanner().next_token(); this implementation + * can be overriden by the generated parser using the code declared in + * the "scan with" clause. Do not recycle objects; every call to + * scan() should return a fresh object. + */ + public Symbol scan() throws java.lang.Exception { + Symbol sym = getScanner().next_token(); + return (sym!=null) ? sym : new Symbol(EOF_sym()); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Report a fatal error. This method takes a message string and an + * additional object (to be used by specializations implemented in + * subclasses). Here in the base class a very simple implementation + * is provided which reports the error then throws an exception. + * + * @param message an error message. + * @param info an extra object reserved for use by specialized subclasses. + */ + public void report_fatal_error( + String message, + Object info) + throws java.lang.Exception + { + /* stop parsing (not really necessary since we throw an exception, but) */ + done_parsing(); + + /* use the normal error message reporting to put out the message */ + report_error(message, info); + + /* throw an exception */ + throw new Exception("Can't recover from previous error(s)"); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Report a non fatal error (or warning). This method takes a message + * string and an additional object (to be used by specializations + * implemented in subclasses). Here in the base class a very simple + * implementation is provided which simply prints the message to + * System.err. + * + * @param message an error message. + * @param info an extra object reserved for use by specialized subclasses. + */ + public void report_error(String message, Object info) + { + System.err.print(message); + if (info instanceof Symbol) + if (((Symbol)info).left != -1) + System.err.println(" at character " + ((Symbol)info).left + + " of input"); + else System.err.println(""); + else System.err.println(""); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method is called when a syntax error has been detected and recovery + * is about to be invoked. Here in the base class we just emit a + * "Syntax error" error message. + * + * @param cur_token the current lookahead Symbol. + */ + public void syntax_error(Symbol cur_token) + { + report_error("Syntax error", cur_token); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method is called if it is determined that syntax error recovery + * has been unsuccessful. Here in the base class we report a fatal error. + * + * @param cur_token the current lookahead Symbol. + */ + public void unrecovered_syntax_error(Symbol cur_token) + throws java.lang.Exception + { + report_fatal_error("Couldn't repair and continue parse", cur_token); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Fetch an action from the action table. The table is broken up into + * rows, one per state (rows are indexed directly by state number). + * Within each row, a list of index, value pairs are given (as sequential + * entries in the table), and the list is terminated by a default entry + * (denoted with a Symbol index of -1). To find the proper entry in a row + * we do a linear or binary search (depending on the size of the row). + * + * @param state the state index of the action being accessed. + * @param sym the Symbol index of the action being accessed. + */ + protected final short get_action(int state, int sym) + { + short tag; + int first, last, probe; + short[] row = action_tab[state]; + + /* linear search if we are < 10 entries */ + if (row.length < 20) + for (probe = 0; probe < row.length; probe++) + { + /* is this entry labeled with our Symbol or the default? */ + tag = row[probe++]; + if (tag == sym || tag == -1) + { + /* return the next entry */ + return row[probe]; + } + } + /* otherwise binary search */ + else + { + first = 0; + last = (row.length-1)/2 - 1; /* leave out trailing default entry */ + while (first <= last) + { + probe = (first+last)/2; + if (sym == row[probe*2]) + return row[probe*2+1]; + else if (sym > row[probe*2]) + first = probe+1; + else + last = probe-1; + } + + /* not found, use the default at the end */ + return row[row.length-1]; + } + + /* shouldn't happened, but if we run off the end we return the + default (error == 0) */ + return 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Fetch a state from the reduce-goto table. The table is broken up into + * rows, one per state (rows are indexed directly by state number). + * Within each row, a list of index, value pairs are given (as sequential + * entries in the table), and the list is terminated by a default entry + * (denoted with a Symbol index of -1). To find the proper entry in a row + * we do a linear search. + * + * @param state the state index of the entry being accessed. + * @param sym the Symbol index of the entry being accessed. + */ + protected final short get_reduce(int state, int sym) + { + short tag; + short[] row = reduce_tab[state]; + + /* if we have a null row we go with the default */ + if (row == null) + return -1; + + for (int probe = 0; probe < row.length; probe++) + { + /* is this entry labeled with our Symbol or the default? */ + tag = row[probe++]; + if (tag == sym || tag == -1) + { + /* return the next entry */ + return row[probe]; + } + } + /* if we run off the end we return the default (error == -1) */ + return -1; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method provides the main parsing routine. It returns only when + * done_parsing() has been called (typically because the parser has + * accepted, or a fatal error has been reported). See the header + * documentation for the class regarding how shift/reduce parsers operate + * and how the various tables are used. + */ + public Symbol parse() throws java.lang.Exception + { + /* the current action code */ + int act; + + /* the Symbol/stack element returned by a reduce */ + Symbol lhs_sym = null; + + /* information about production being reduced with */ + short handle_size, lhs_sym_num; + + /* set up direct reference to tables to drive the parser */ + + production_tab = production_table(); + action_tab = action_table(); + reduce_tab = reduce_table(); + + /* initialize the action encapsulation object */ + init_actions(); + + /* do user initialization */ + user_init(); + + /* get the first token */ + cur_token = scan(); + + /* push dummy Symbol with start state to get us underway */ + stack.removeAllElements(); + stack.push(new Symbol(0, start_state())); + tos = 0; + + /* continue until we are told to stop */ + for (_done_parsing = false; !_done_parsing; ) + { + /* Check current token for freshness. */ + if (cur_token.used_by_parser) + throw new Error("Symbol recycling detected (fix your scanner)."); + + /* current state is always on the top of the stack */ + + /* look up action out of the current state with the current input */ + act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym); + + /* decode the action -- > 0 encodes shift */ + if (act > 0) + { + /* shift to the encoded state by pushing it on the stack */ + cur_token.parse_state = act-1; + cur_token.used_by_parser = true; + stack.push(cur_token); + tos++; + + /* advance to the next Symbol */ + cur_token = scan(); + } + /* if its less than zero, then it encodes a reduce action */ + else if (act < 0) + { + /* perform the action for the reduce */ + lhs_sym = do_action((-act)-1, this, stack, tos); + + /* look up information about the production */ + lhs_sym_num = production_tab[(-act)-1][0]; + handle_size = production_tab[(-act)-1][1]; + + /* pop the handle off the stack */ + for (int i = 0; i < handle_size; i++) + { + stack.pop(); + tos--; + } + + /* look up the state to go to from the one popped back to */ + act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); + + /* shift to that state */ + lhs_sym.parse_state = act; + lhs_sym.used_by_parser = true; + stack.push(lhs_sym); + tos++; + } + /* finally if the entry is zero, we have an error */ + else if (act == 0) + { + /* call user syntax error reporting routine */ + syntax_error(cur_token); + + /* try to error recover */ + if (!error_recovery(false)) + { + /* if that fails give up with a fatal syntax error */ + unrecovered_syntax_error(cur_token); + + /* just in case that wasn't fatal enough, end parse */ + done_parsing(); + } else { + lhs_sym = (Symbol)stack.peek(); + } + } + } + return lhs_sym; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Write a debugging message to System.err for the debugging version + * of the parser. + * + * @param mess the text of the debugging message. + */ + public void debug_message(String mess) + { + System.err.println(mess); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Dump the parse stack for debugging purposes. */ + public void dump_stack() + { + if (stack == null) + { + debug_message("# Stack dump requested, but stack is null"); + return; + } + + debug_message("============ Parse Stack Dump ============"); + + /* dump the stack */ + for (int i=0; i"); + if ((i%3)==2 || (i==(stack.size()-1))) { + debug_message(sb.toString()); + sb = new StringBuffer(" "); + } + } + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Perform a parse with debugging output. This does exactly the + * same things as parse(), except that it calls debug_shift() and + * debug_reduce() when shift and reduce moves are taken by the parser + * and produces various other debugging messages. + */ + public Symbol debug_parse() + throws java.lang.Exception + { + /* the current action code */ + int act; + + /* the Symbol/stack element returned by a reduce */ + Symbol lhs_sym = null; + + /* information about production being reduced with */ + short handle_size, lhs_sym_num; + + /* set up direct reference to tables to drive the parser */ + production_tab = production_table(); + action_tab = action_table(); + reduce_tab = reduce_table(); + + debug_message("# Initializing parser"); + + /* initialize the action encapsulation object */ + init_actions(); + + /* do user initialization */ + user_init(); + + /* the current Symbol */ + cur_token = scan(); + + debug_message("# Current Symbol is #" + cur_token.sym); + + /* push dummy Symbol with start state to get us underway */ + stack.removeAllElements(); + stack.push(new Symbol(0, start_state())); + tos = 0; + + /* continue until we are told to stop */ + for (_done_parsing = false; !_done_parsing; ) + { + /* Check current token for freshness. */ + if (cur_token.used_by_parser) + throw new Error("Symbol recycling detected (fix your scanner)."); + + /* current state is always on the top of the stack */ + //debug_stack(); + + /* look up action out of the current state with the current input */ + act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym); + + /* decode the action -- > 0 encodes shift */ + if (act > 0) + { + /* shift to the encoded state by pushing it on the stack */ + cur_token.parse_state = act-1; + cur_token.used_by_parser = true; + debug_shift(cur_token); + stack.push(cur_token); + tos++; + + /* advance to the next Symbol */ + cur_token = scan(); + debug_message("# Current token is " + cur_token); + } + /* if its less than zero, then it encodes a reduce action */ + else if (act < 0) + { + /* perform the action for the reduce */ + lhs_sym = do_action((-act)-1, this, stack, tos); + + /* look up information about the production */ + lhs_sym_num = production_tab[(-act)-1][0]; + handle_size = production_tab[(-act)-1][1]; + + debug_reduce((-act)-1, lhs_sym_num, handle_size); + + /* pop the handle off the stack */ + for (int i = 0; i < handle_size; i++) + { + stack.pop(); + tos--; + } + + /* look up the state to go to from the one popped back to */ + act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); + debug_message("# Reduce rule: top state " + + ((Symbol)stack.peek()).parse_state + + ", lhs sym " + lhs_sym_num + " -> state " + act); + + /* shift to that state */ + lhs_sym.parse_state = act; + lhs_sym.used_by_parser = true; + stack.push(lhs_sym); + tos++; + + debug_message("# Goto state #" + act); + } + /* finally if the entry is zero, we have an error */ + else if (act == 0) + { + /* call user syntax error reporting routine */ + syntax_error(cur_token); + + /* try to error recover */ + if (!error_recovery(true)) + { + /* if that fails give up with a fatal syntax error */ + unrecovered_syntax_error(cur_token); + + /* just in case that wasn't fatal enough, end parse */ + done_parsing(); + } else { + lhs_sym = (Symbol)stack.peek(); + } + } + } + return lhs_sym; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + /* Error recovery code */ + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Attempt to recover from a syntax error. This returns false if recovery + * fails, true if it succeeds. Recovery happens in 4 steps. First we + * pop the parse stack down to a point at which we have a shift out + * of the top-most state on the error Symbol. This represents the + * initial error recovery configuration. If no such configuration is + * found, then we fail. Next a small number of "lookahead" or "parse + * ahead" Symbols are read into a buffer. The size of this buffer is + * determined by error_sync_size() and determines how many Symbols beyond + * the error must be matched to consider the recovery a success. Next, + * we begin to discard Symbols in attempt to get past the point of error + * to a point where we can continue parsing. After each Symbol, we attempt + * to "parse ahead" though the buffered lookahead Symbols. The "parse ahead" + * process simulates that actual parse, but does not modify the real + * parser's configuration, nor execute any actions. If we can parse all + * the stored Symbols without error, then the recovery is considered a + * success. Once a successful recovery point is determined, we do an + * actual parse over the stored input -- modifying the real parse + * configuration and executing all actions. Finally, we return the the + * normal parser to continue with the overall parse. + * + * @param debug should we produce debugging messages as we parse. + */ + protected boolean error_recovery(boolean debug) + throws java.lang.Exception + { + if (debug) debug_message("# Attempting error recovery"); + + /* first pop the stack back into a state that can shift on error and + do that shift (if that fails, we fail) */ + if (!find_recovery_config(debug)) + { + if (debug) debug_message("# Error recovery fails"); + return false; + } + + /* read ahead to create lookahead we can parse multiple times */ + read_lookahead(); + + /* repeatedly try to parse forward until we make it the required dist */ + for (;;) + { + /* try to parse forward, if it makes it, bail out of loop */ + if (debug) debug_message("# Trying to parse ahead"); + if (try_parse_ahead(debug)) + { + break; + } + + /* if we are now at EOF, we have failed */ + if (lookahead[0].sym == EOF_sym()) + { + if (debug) debug_message("# Error recovery fails at EOF"); + return false; + } + + /* otherwise, we consume another Symbol and try again */ + // BUG FIX by Bruce Hutton + // Computer Science Department, University of Auckland, + // Auckland, New Zealand. + // It is the first token that is being consumed, not the one + // we were up to parsing + if (debug) + debug_message("# Consuming Symbol #" + lookahead[ 0 ].sym); + restart_lookahead(); + } + + /* we have consumed to a point where we can parse forward */ + if (debug) debug_message("# Parse-ahead ok, going back to normal parse"); + + /* do the real parse (including actions) across the lookahead */ + parse_lookahead(debug); + + /* we have success */ + return true; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Determine if we can shift under the special error Symbol out of the + * state currently on the top of the (real) parse stack. + */ + protected boolean shift_under_error() + { + /* is there a shift under error Symbol */ + return get_action(((Symbol)stack.peek()).parse_state, error_sym()) > 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Put the (real) parse stack into error recovery configuration by + * popping the stack down to a state that can shift on the special + * error Symbol, then doing the shift. If no suitable state exists on + * the stack we return false + * + * @param debug should we produce debugging messages as we parse. + */ + protected boolean find_recovery_config(boolean debug) + { + Symbol error_token; + int act; + + if (debug) debug_message("# Finding recovery state on stack"); + + /* Remember the right-position of the top symbol on the stack */ + int right_pos = ((Symbol)stack.peek()).right; + int left_pos = ((Symbol)stack.peek()).left; + + /* pop down until we can shift under error Symbol */ + while (!shift_under_error()) + { + /* pop the stack */ + if (debug) + debug_message("# Pop stack by one, state was # " + + ((Symbol)stack.peek()).parse_state); + left_pos = ((Symbol)stack.pop()).left; + tos--; + + /* if we have hit bottom, we fail */ + if (stack.empty()) + { + if (debug) debug_message("# No recovery state found on stack"); + return false; + } + } + + /* state on top of the stack can shift under error, find the shift */ + act = get_action(((Symbol)stack.peek()).parse_state, error_sym()); + if (debug) + { + debug_message("# Recover state found (#" + + ((Symbol)stack.peek()).parse_state + ")"); + debug_message("# Shifting on error to state #" + (act-1)); + } + + /* build and shift a special error Symbol */ + error_token = new Symbol(error_sym(), left_pos, right_pos); + error_token.parse_state = act-1; + error_token.used_by_parser = true; + stack.push(error_token); + tos++; + + return true; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Lookahead Symbols used for attempting error recovery "parse aheads". */ + protected Symbol lookahead[]; + + /** Position in lookahead input buffer used for "parse ahead". */ + protected int lookahead_pos; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Read from input to establish our buffer of "parse ahead" lookahead + * Symbols. + */ + protected void read_lookahead() throws java.lang.Exception + { + /* create the lookahead array */ + lookahead = new Symbol[error_sync_size()]; + + /* fill in the array */ + for (int i = 0; i < error_sync_size(); i++) + { + lookahead[i] = cur_token; + cur_token = scan(); + } + + /* start at the beginning */ + lookahead_pos = 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Return the current lookahead in our error "parse ahead" buffer. */ + protected Symbol cur_err_token() { return lookahead[lookahead_pos]; } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Advance to next "parse ahead" input Symbol. Return true if we have + * input to advance to, false otherwise. + */ + protected boolean advance_lookahead() + { + /* advance the input location */ + lookahead_pos++; + + /* return true if we didn't go off the end */ + return lookahead_pos < error_sync_size(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Reset the parse ahead input to one Symbol past where we started error + * recovery (this consumes one new Symbol from the real input). + */ + protected void restart_lookahead() throws java.lang.Exception + { + /* move all the existing input over */ + for (int i = 1; i < error_sync_size(); i++) + lookahead[i-1] = lookahead[i]; + + /* read a new Symbol into the last spot */ + // BUG Fix by Bruce Hutton + // Computer Science Department, University of Auckland, + // Auckland, New Zealand. [applied 5-sep-1999 by csa] + // The following two lines were out of order!! + lookahead[error_sync_size()-1] = cur_token; + cur_token = scan(); + + /* reset our internal position marker */ + lookahead_pos = 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Do a simulated parse forward (a "parse ahead") from the current + * stack configuration using stored lookahead input and a virtual parse + * stack. Return true if we make it all the way through the stored + * lookahead input without error. This basically simulates the action of + * parse() using only our saved "parse ahead" input, and not executing any + * actions. + * + * @param debug should we produce debugging messages as we parse. + */ + protected boolean try_parse_ahead(boolean debug) + throws java.lang.Exception + { + int act; + short lhs, rhs_size; + + /* create a virtual stack from the real parse stack */ + virtual_parse_stack vstack = new virtual_parse_stack(stack); + + /* parse until we fail or get past the lookahead input */ + for (;;) + { + /* look up the action from the current state (on top of stack) */ + act = get_action(vstack.top(), cur_err_token().sym); + + /* if its an error, we fail */ + if (act == 0) return false; + + /* > 0 encodes a shift */ + if (act > 0) + { + /* push the new state on the stack */ + vstack.push(act-1); + + if (debug) debug_message("# Parse-ahead shifts Symbol #" + + cur_err_token().sym + " into state #" + (act-1)); + + /* advance simulated input, if we run off the end, we are done */ + if (!advance_lookahead()) return true; + } + /* < 0 encodes a reduce */ + else + { + /* if this is a reduce with the start production we are done */ + if ((-act)-1 == start_production()) + { + if (debug) debug_message("# Parse-ahead accepts"); + return true; + } + + /* get the lhs Symbol and the rhs size */ + lhs = production_tab[(-act)-1][0]; + rhs_size = production_tab[(-act)-1][1]; + + /* pop handle off the stack */ + for (int i = 0; i < rhs_size; i++) + vstack.pop(); + + if (debug) + debug_message("# Parse-ahead reduces: handle size = " + + rhs_size + " lhs = #" + lhs + " from state #" + vstack.top()); + + /* look up goto and push it onto the stack */ + vstack.push(get_reduce(vstack.top(), lhs)); + if (debug) + debug_message("# Goto state #" + vstack.top()); + } + } + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Parse forward using stored lookahead Symbols. In this case we have + * already verified that parsing will make it through the stored lookahead + * Symbols and we are now getting back to the point at which we can hand + * control back to the normal parser. Consequently, this version of the + * parser performs all actions and modifies the real parse configuration. + * This returns once we have consumed all the stored input or we accept. + * + * @param debug should we produce debugging messages as we parse. + */ + protected void parse_lookahead(boolean debug) + throws java.lang.Exception + { + /* the current action code */ + int act; + + /* the Symbol/stack element returned by a reduce */ + Symbol lhs_sym = null; + + /* information about production being reduced with */ + short handle_size, lhs_sym_num; + + /* restart the saved input at the beginning */ + lookahead_pos = 0; + + if (debug) + { + debug_message("# Reparsing saved input with actions"); + debug_message("# Current Symbol is #" + cur_err_token().sym); + debug_message("# Current state is #" + + ((Symbol)stack.peek()).parse_state); + } + + /* continue until we accept or have read all lookahead input */ + while(!_done_parsing) + { + /* current state is always on the top of the stack */ + + /* look up action out of the current state with the current input */ + act = + get_action(((Symbol)stack.peek()).parse_state, cur_err_token().sym); + + /* decode the action -- > 0 encodes shift */ + if (act > 0) + { + /* shift to the encoded state by pushing it on the stack */ + cur_err_token().parse_state = act-1; + cur_err_token().used_by_parser = true; + if (debug) debug_shift(cur_err_token()); + stack.push(cur_err_token()); + tos++; + + /* advance to the next Symbol, if there is none, we are done */ + if (!advance_lookahead()) + { + if (debug) debug_message("# Completed reparse"); + + /* scan next Symbol so we can continue parse */ + // BUGFIX by Chris Harris : + // correct a one-off error by commenting out + // this next line. + /*cur_token = scan();*/ + + /* go back to normal parser */ + return; + } + + if (debug) + debug_message("# Current Symbol is #" + cur_err_token().sym); + } + /* if its less than zero, then it encodes a reduce action */ + else if (act < 0) + { + /* perform the action for the reduce */ + lhs_sym = do_action((-act)-1, this, stack, tos); + + /* look up information about the production */ + lhs_sym_num = production_tab[(-act)-1][0]; + handle_size = production_tab[(-act)-1][1]; + + if (debug) debug_reduce((-act)-1, lhs_sym_num, handle_size); + + /* pop the handle off the stack */ + for (int i = 0; i < handle_size; i++) + { + stack.pop(); + tos--; + } + + /* look up the state to go to from the one popped back to */ + act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); + + /* shift to that state */ + lhs_sym.parse_state = act; + lhs_sym.used_by_parser = true; + stack.push(lhs_sym); + tos++; + + if (debug) debug_message("# Goto state #" + act); + + } + /* finally if the entry is zero, we have an error + (shouldn't happen here, but...)*/ + else if (act == 0) + { + report_fatal_error("Syntax error", lhs_sym); + return; + } + } + + + } + + /*-----------------------------------------------------------*/ + + /** Utility function: unpacks parse tables from strings */ + protected static short[][] unpackFromStrings(String[] sa) + { + // Concatanate initialization strings. + StringBuffer sb = new StringBuffer(sa[0]); + for (int i=1; i= real_stack.size()) return; + + /* get a copy of the first Symbol we have not transfered */ + stack_sym = (Symbol)real_stack.elementAt(real_stack.size()-1-real_next); + + /* record the transfer */ + real_next++; + + /* put the state number from the Symbol onto the virtual stack */ + vstack.push(new Integer(stack_sym.parse_state)); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Indicate whether the stack is empty. */ + public boolean empty() + { + /* if vstack is empty then we were unable to transfer onto it and + the whole thing is empty. */ + return vstack.empty(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Return value on the top of the stack (without popping it). */ + public int top() throws java.lang.Exception + { + if (vstack.empty()) + throw new Exception( + "Internal parser error: top() called on empty virtual stack"); + + return ((Integer)vstack.peek()).intValue(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Pop the stack. */ + public void pop() throws java.lang.Exception + { + if (vstack.empty()) + throw new Exception( + "Internal parser error: pop from empty virtual stack"); + + /* pop it */ + vstack.pop(); + + /* if we are now empty transfer an element (if there is one) */ + if (vstack.empty()) + get_from_real(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Push a state number onto the stack. */ + public void push(int state_num) + { + vstack.push(new Integer(state_num)); + } + + /*-----------------------------------------------------------*/ + +} diff --git a/tools/lexer/jflex-1.4/src/manifest b/tools/lexer/jflex-1.4/src/manifest new file mode 100644 index 000000000000..1e139295c20c --- /dev/null +++ b/tools/lexer/jflex-1.4/src/manifest @@ -0,0 +1 @@ +Main-Class: JFlex.Main diff --git a/tools/lexer/jflex-1.4/src/skeleton.default b/tools/lexer/jflex-1.4/src/skeleton.default new file mode 100644 index 000000000000..c2a807820775 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/skeleton.default @@ -0,0 +1,317 @@ + + /** 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 = ...; + + /** lexical states */ +--- lexical states, charmap + + /* 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[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + +--- isFinal list + /** 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 textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** 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; + +--- user class code + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ +--- constructor declaration + + + /** + * 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) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzPushbackPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * 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. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * 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 + */ +--- zzScanError declaration + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + +--- throws clause + } + + + /** + * 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()! + */ +--- yypushback decl (contains zzScanError exception) + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + +--- zzDoEOF + /** + * 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 + */ +--- yylex declaration + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + +--- local declarations + + while (true) { + zzMarkedPosL = zzMarkedPos; + +--- start admin (line, char, col count) + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + +--- start admin (lexstate etc) + + zzForAction: { + while (true) { + +--- next input, line, col, char count, next transition, isFinal action + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; +--- line count update + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; +--- char count update + +--- actions + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; +--- eofvalue + } + else { +--- no match + } + } + } + } + +--- main + +} diff --git a/tools/lexer/jflex-1.4/src/skeleton.nested b/tools/lexer/jflex-1.4/src/skeleton.nested new file mode 100644 index 000000000000..08350f14c353 --- /dev/null +++ b/tools/lexer/jflex-1.4/src/skeleton.nested @@ -0,0 +1,419 @@ + + /** 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 = ...; + + /** lexical states */ +--- lexical states, charmap + + /* 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[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + +--- isFinal list + /** 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 textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** 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; + + + /** the stack of open (nested) input streams to read from */ + private java.util.Stack zzStreams = new java.util.Stack(); + + /** + * inner class used to store info for nested + * input streams + */ + private static final class ZzFlexStreamInfo { + java.io.Reader zzReader; + int zzEndRead; + int zzStartRead; + int zzCurrentPos; + int zzMarkedPos; + int zzPushbackPos; + int yyline; + int yycolumn; + char [] zzBuffer; + boolean zzAtEOF; + + /** sets all values stored in this class */ + ZzFlexStreamInfo(java.io.Reader zzReader, int zzEndRead, int zzStartRead, + int zzCurrentPos, int zzMarkedPos, int zzPushbackPos, + char [] zzBuffer, boolean zzAtEOF, int yyline, int yycolumn) { + this.zzReader = zzReader; + this.zzEndRead = zzEndRead; + this.zzStartRead = zzStartRead; + this.zzCurrentPos = zzCurrentPos; + this.zzMarkedPos = zzMarkedPos; + this.zzPushbackPos = zzPushbackPos; + this.zzBuffer = zzBuffer; + this.zzAtEOF = zzAtEOF; + this.yyline = yyline; + this.yycolumn = yycolumn; + } + } + +--- user class code + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ +--- constructor declaration + + + /** + * 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) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzPushbackPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * 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(); + } + + + /** + * Stores the current input stream on a stack, and + * reads from a new stream. Lexical state, line, + * char, and column counting remain untouched. + * + * The current input stream can be restored with + * yypopstream (usually in an <> action). + * + * @param reader the new input stream to read from + * + * @see #yypopStream() + */ + public final void yypushStream(java.io.Reader reader) { + zzStreams.push( + new ZzFlexStreamInfo(zzReader, zzEndRead, zzStartRead, zzCurrentPos, + zzMarkedPos, zzPushbackPos, zzBuffer, zzAtEOF, + yyline, yycolumn) + ); + zzAtEOF = false; + zzBuffer = new char[ZZ_BUFFERSIZE]; + zzReader = reader; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yycolumn = 0; + } + + + /** + * Closes the current input stream and continues to + * read from the one on top of the stream stack. + * + * @throws java.util.EmptyStackException + * if there is no further stream to read from. + * + * @throws java.io.IOException + * if there was an error in closing the stream. + * + * @see #yypushStream(java.io.Reader) + */ + public final void yypopStream() throws java.io.IOException { + zzReader.close(); + ZzFlexStreamInfo s = (ZzFlexStreamInfo) zzStreams.pop(); + zzBuffer = s.zzBuffer; + zzReader = s.zzReader; + zzEndRead = s.zzEndRead; + zzStartRead = s.zzStartRead; + zzCurrentPos = s.zzCurrentPos; + zzMarkedPos = s.zzMarkedPos ; + zzPushbackPos = s.zzPushbackPos; + zzAtEOF = s.zzAtEOF; + yyline = s.yyline; + yycolumn = s.yycolumn; + } + + + /** + * Returns true iff there are still streams left + * to read from on the stream stack. + */ + public final boolean yymoreStreams() { + return !zzStreams.isEmpty(); + } + + + /** + * 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. + * + * @param reader the new input stream + * + * @see #yypushStream(java.io.Reader) + * @see #yypopStream() + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * 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 + */ +--- zzScanError declaration + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + +--- throws clause + } + + + /** + * 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()! + */ +--- yypushback decl (contains zzScanError exception) + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + +--- zzDoEOF + /** + * 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 + */ +--- yylex declaration + int zzInput; + int zzAction; + +--- local declarations + + while (true) { + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL = zzMarkedPos; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + +--- start admin (line, char, col count) + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + +--- start admin (lexstate etc) + + zzForAction: { + while (true) { + +--- next input, line, col, char count, next transition, isFinal action + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; +--- line count update + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; +--- char count update + +--- actions + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; +--- eofvalue + } + else { +--- no match + } + } + } + } + +--- main + +}