--- /dev/null
--- /dev/null
++# @interface (annotation) related messages
++annotation.unknown.method=Cannot resolve method ''{0}''
++annotation.missing.method=Cannot find method ''{0}''
++annotation.incompatible.types=Incompatible types. Found: ''{0}'', required: ''{1}''
++annotation.illegal.array.initializer=Illegal initializer for ''{0}''
++annotation.duplicate.annotation=Duplicate annotation
++annotation.duplicate.attribute=Duplicate attribute ''{0}''
++annotation.missing.attribute={0} missing though required
++annotation.not.applicable=''@{0}'' not applicable to {1}
++annotation.nonconstant.attribute.value=Attribute value must be constant
++annotation.invalid.annotation.member.type=Invalid type for annotation member
++annotation.cyclic.element.type=Cyclic annotation element type
++annotation.annotation.type.expected=Annotation type expected
++annotation.members.may.not.have.throws.list=@interface members may not have throws list
++annotation.may.not.have.extends.list=@interface may not have extends list
++annotation.name.is.missing=Annotation attribute must be of the form 'name=value'
++
++# These aren't unused.
++# suppress inspection "unused property"
++annotation.target.ANNOTATION_TYPE=annotation type
++# suppress inspection "unused property"
++annotation.target.TYPE=type
++# suppress inspection "unused property"
++annotation.target.TYPE_USE=type use
++# suppress inspection "unused property"
++annotation.target.TYPE_PARAMETER=type parameter
++# suppress inspection "unused property"
++annotation.target.CONSTRUCTOR=constructor
++# suppress inspection "unused property"
++annotation.target.METHOD=method
++# suppress inspection "unused property"
++annotation.target.FIELD=field
++# suppress inspection "unused property"
++annotation.target.PARAMETER=parameter
++# suppress inspection "unused property"
++annotation.target.LOCAL_VARIABLE=local variable
++# suppress inspection "unused property"
++annotation.target.PACKAGE=package
++
++# generics related messages
++generics.holder.type=Type
++generics.holder.method=Method
++
++generics.are.not.supported=Generics are not supported at this language level
++generics.inferred.type.for.type.parameter.is.not.within.its.bound.extend=Inferred type ''{2}'' for type parameter ''{0}'' is not within its bound; should extend ''{1}''
++generics.inferred.type.for.type.parameter.is.not.within.its.bound.implement=Inferred type ''{2}'' for type parameter ''{0}'' is not within its bound; should implement ''{1}''
++generics.type.parameter.is.not.within.its.bound.extend=Type parameter ''{0}'' is not within its bound; should extend ''{1}''
++generics.type.parameter.is.not.within.its.bound.implement=Type parameter ''{0}'' is not within its bound; should implement ''{1}''
++
++# {0} - Type (class) or Method
++generics.type.or.method.does.not.have.type.parameters={0} ''{1}'' does not have type parameters
++generics.wrong.number.of.type.arguments=Wrong number of type arguments: {0}; required: {1}
++generics.cannot.be.inherited.with.different.type.arguments=''{0}'' cannot be inherited with different type arguments: ''{1}'' and ''{2}''
++generics.select.static.class.from.parameterized.type=Cannot select static class ''{0}'' from parameterized type
++generics.methods.have.same.erasure={0}; both methods have same erasure
++generics.methods.have.same.erasure.override={0}; both methods have same erasure, yet neither overrides the other
++generics.type.parameter.cannot.be.instantiated=Type parameter ''{0}'' cannot be instantiated directly
++wildcard.type.cannot.be.instantiated=Wildcard type ''{0}'' cannot be instantiated directly
++generics.wildcard.not.expected=No wildcard expected
++generics.wildcards.may.be.used.only.as.reference.parameters=Wildcards may be used only as reference parameters
++generics.type.argument.cannot.be.of.primitive.type=Type argument cannot be of primitive type
++generics.unchecked.assignment=Unchecked assignment: ''{0}'' to ''{1}''
++generics.unchecked.cast=Unchecked cast: ''{0}'' to ''{1}''
++generics.unchecked.call.to.member.of.raw.type=Unchecked call to ''{0}'' as a member of raw type ''{1}''
++foreach.not.applicable=foreach not applicable to type ''{0}''.
++illegal.to.access.static.member.from.enum.constructor.or.instance.initializer=It is illegal to access static member ''{0}'' from enum constructor or instance initializer
++enum.types.cannot.be.instantiated=Enum types cannot be instantiated
++generic.array.creation=Generic array creation
++generics.enum.may.not.have.type.parameters=Enum may not have type parameters
++generics.annotation.members.may.not.have.type.parameters=@interface members may not have type parameters
++annotation.may.not.have.type.parameters=@interface may not have type parameters
++generics.duplicate.type.parameter=Duplicate type parameter: ''{0}''
++generics.cannot.catch.type.parameters=Cannot catch type parameters
++generics.cannot.instanceof.type.parameters=Class or array expected
++illegal.generic.type.for.instanceof=Illegal generic type for instanceof
++cannot.select.dot.class.from.type.variable=Cannot select from a type variable
++method.doesnot.override.super=Method does not override method from its superclass
++call.to.super.is.not.allowed.in.enum.constructor=Call to super is not allowed in enum constructor
++vararg.not.last.parameter=Vararg parameter must be the last in the list
++modifiers.for.enum.constants=No modifiers allowed for enum constants
++generics.type.arguments.on.raw.type=Type arguments given on a raw type
++generics.type.arguments.on.raw.method=Type arguments given on a raw method
++classes.extends.enum=Classes cannot directly extend 'java.lang.Enum'
++unchecked.overriding.incompatible.return.type=Unchecked overriding: return type requires unchecked conversion. Found ''{0}'', required ''{1}''
++unchecked.overriding=Unchecked overriding
++local.enum=Enum must not be local
++
++interface.expected=Interface expected here
++class.expected=No interface expected here
++implements.after.interface=No implements clause allowed for interface
++static.declaration.in.inner.class=Inner classes cannot have static declarations
++class.must.be.abstract=Class ''{0}'' must either be declared abstract or implement abstract method ''{1}'' in ''{2}''
++abstract.cannot.be.instantiated=''{0}'' is abstract; cannot be instantiated
++duplicate.class.in.other.file=Duplicate class found in the file ''{0}''
++duplicate.class=Duplicate class: ''{0}''
++public.class.should.be.named.after.file=Class ''{0}'' is public, should be declared in a file named ''{0}.java''
++inheritance.from.final.class=Cannot inherit from final ''{0}''
++package.name.file.path.mismatch=Package name ''{0}'' does not correspond to the file path ''{1}''
++missing.package.statement=Missing package statement: ''{0}''
++interface.cannot.be.local=Modifier 'interface' not allowed here
++cyclic.inheritance=Cyclic inheritance involving ''{0}''
++class.already.imported=''{0}'' is already defined in this compilation unit
++class.cannot.extend.multiple.classes=Class cannot extend multiple classes
++not.allowed.in.interface=Not allowed in interface
++qualified.new.of.static.class=Qualified new of static class
++invalid.qualified.new=Invalid qualified new
++class.name.expected=Class name expected
++no.enclosing.instance.in.scope=No enclosing instance of type ''{0}'' is in scope
++externalizable.class.should.have.public.constructor=Externalizable class should have public no-args constructor
++is.not.an.enclosing.class=''{0}'' is not an enclosing class
++cannot.be.referenced.from.static.context=''{0}'' cannot be referenced from a static context
++no.default.constructor.available=There is no default constructor available in ''{0}''
++missing.return.statement=Missing return statement
++unreachable.statement=Unreachable statement
++variable.not.initialized=Variable ''{0}'' might not have been initialized
++variable.already.assigned=Variable ''{0}'' might already have been assigned to
++variable.assigned.in.loop=Variable ''{0}'' might be assigned in loop
++assignment.to.final.variable=Cannot assign a value to final variable ''{0}''
++variable.must.be.final=Variable ''{0}'' is accessed from within inner class. Needs to be declared final.
++initializer.must.be.able.to.complete.normally=Initializer must be able to complete normally
++weaker.privileges={0}; attempting to assign weaker access privileges (''{1}''); was ''{2}''
++incompatible.return.type=attempting to use incompatible return type
++final.method.override=''{0}'' cannot override ''{1}'' in ''{2}''; overridden method is final
++overridden.method.does.not.throw={0}; overridden method does not throw ''{1}''
++exception.is.never.thrown=Exception ''{0}'' is never thrown in the method
++wrong.method.arguments=''{0}'' in ''{1}'' cannot be applied to ''{2}''
++method.call.expected=Method call expected
++ambiguous.method.call=Ambiguous method call: both ''{0}'' and ''{1}'' match
++cannot.resolve.method=Cannot resolve method ''{0}''
++missing.method.body=Missing method body, or declare abstract
++abstract.method.in.non.abstract.class=Abstract method in non-abstract class
++missing.return.type=Invalid method declaration; return type required
++duplicate.method=''{0}'' is already defined in ''{1}''
++constructor.call.must.be.first.statement=Call to ''{0}'' must be first statement in constructor body
++direct.abstract.method.access=Abstract method ''{0}'' cannot be accessed directly
++unrelated.overriding.methods.return.types=methods have unrelated return types
++overrides.deprecated.method=Overrides deprecated method in ''{0}''
++recursive.constructor.invocation=Recursive constructor invocation
++wrong.constructor.arguments=''{0}'' cannot be applied to ''{1}''
++cannot.resolve.constructor=Cannot resolve constructor ''{0}''
++invalid.package.annotation.containing.file=Package annotations should be in file package-info.java
++repeated.annotation.target=Repeated annotation target
++
++clash.methods.message=''{0}'' clashes with ''{1}''
++clash.methods.message.show.classes=''{0}'' in ''{2}'' clashes with ''{1}'' in ''{3}''
++
++# {0} - colspan, {1} - method1, {2} - class1, {3} - method2, {4} - class2
++ambiguous.method.html.tooltip=\
++ <html><body><table border=0>\
++ <tr><td colspan={0}>Ambiguous method call. Both</td></tr>\
++ <tr>{1}<td>in <b>{2}</b>\\ and</td></tr>\
++ <tr>{3}<td>in <b>{4}</b>\\ match.</td></tr>\
++ </table></body></html>
++
++
++# {0} - colspan, {1} - method name, {2} - class name, {3} - formal parameters row, {4} - arguments row
++argument.mismatch.html.tooltip=\
++ <html><body><table border=0>\
++ <tr><td><b>{1}</b></td>{3}<td colspan={0}>in <b>{2}</b>\\ cannot be applied</td></tr>\
++ <tr><td>to</td>{4}</tr>\
++ </table></body></html>
++
++# {0} - left raw type, {1} - required row, {2} - right raw type, {3} - found row
++incompatible.types.html.tooltip=\
++ <html><body>Incompatible types.<table>\
++ <tr><td>Required:</td><td>{0}</td>{1}</tr>\
++ <tr><td>Found:</td><td>{2}</td>{3}</tr>\
++ </table></body></html>
++
++interface.methods.cannot.have.body=Interface methods cannot have body
++abstract.methods.cannot.have.a.body=Abstract methods cannot have a body
++native.methods.cannot.have.a.body=Native methods cannot have a body
++
++instance.method.cannot.override.static.method=Instance method ''{0}'' in ''{1}'' cannot override static method ''{2}'' in ''{3}''
++static.method.cannot.override.instance.method=Static method ''{0}'' in ''{1}'' cannot override instance method ''{2}'' in ''{3}''
++inconvertible.type.cast=Inconvertible types; cannot cast ''{0}'' to ''{1}''
++variable.expected=Variable expected
++binary.operator.not.applicable=Operator ''{0}'' cannot be applied to ''{1}'',''{2}''
++unary.operator.not.applicable=Operator ''{0}'' cannot be applied to ''{1}''
++return.outside.method=Return outside method
++return.from.void.method=Cannot return a value from a method with void result type
++missing.return.value=Missing return value
++
++#{0] - exceptions list (comma separated). {1} - exceptions count in the list
++unhandled.exceptions=Unhandled {1, choice, 0#exception|2#exceptions}: {0}
++variable.already.defined=Variable ''{0}'' is already defined in the scope
++break.outside.switch.or.loop=Break outside switch or loop
++continue.outside.loop=Continue outside of loop
++not.loop.label=Not a loop label: ''{0}''
++incompatible.modifiers=Illegal combination of modifiers: ''{0}'' and ''{1}''
++modifier.not.allowed=Modifier ''{0}'' not allowed here
++exception.never.thrown.try=Exception ''{0}'' is never thrown in the corresponding try block
++not.a.statement=Not a statement
++incompatible.types=Incompatible types. Found: ''{1}'', required: ''{0}''
++valid.switch.selector.types=byte, char, short or int
++dot.expected.after.super.or.this='.' expected
++
++non.static.symbol.referenced.from.static.context=Non-static {0} ''{1}'' cannot be referenced from a static context
++private.symbol=''{0}'' has private access in ''{1}''
++protected.symbol=''{0}'' has protected access in ''{1}''
++package.local.symbol=''{0}'' is not public in ''{1}''. Cannot be accessed from outside package
++visibility.access.problem=Cannot access ''{0}'' in ''{1}''
++array.type.expected=Array type expected; found: ''{0}''
++expression.expected=Expression expected
++case.statement.outside.switch=Case statement outside switch
++qualified.enum.constant.in.switch=An enum switch case label must be the unqualified name of an enumeration constant
++constant.expression.required=Constant expression required
++duplicate.default.switch.label=Duplicate default label
++duplicate.switch.label=Duplicate label ''{0}''
++switch.colon.expected.after.case.label=':' expected
++
++#See JLS 8.3.2.3
++illegal.forward.reference=Illegal forward reference
++
++unknown.class=Unknown class: ''{0}''
++illegal.type.void=Illegal type: 'void'
++member.referenced.before.constructor.called=Cannot reference ''{0}'' before supertype constructor has been called
++label.without.statement=Label without statement
++duplicate.label=Label ''{0}'' already in use
++nonterminated.comment=Unclosed comment
++assignment.to.itself=Variable is assigned to itself
++assignment.to.declared.variable=Variable ''{0}'' is initialized with self assignment
++exception.already.caught=Exception ''{0}'' has already been caught
++statement.must.be.prepended.with.case.label=Statement must be prepended with case label
++void.type.is.not.allowed='void' type is not allowed here
++single.import.class.conflict=''{0}'' is already defined in a single-type import
++numeric.overflow.in.expression=Numeric overflow in expression
++static.member.accessed.via.instance.reference=Static member ''{0}.{1}'' accessed via instance reference
++unresolved.label=Undefined label: ''{0}''
++deprecated.symbol=''{0}'' is deprecated
++cannot.resolve.symbol=Cannot resolve symbol ''{0}''
++static.imports.prior.15=Static imports are not supported at this language level
++varargs.prior.15=Variable arity methods are not supported at this language level
++foreach.prior.15=Foreach loops are not supported at this language level
++annotations.prior.15=Annotations are not supported at this language level
++class.is.already.defined.in.single.type.import=class ''{0}'' is already defined in a single-type import
++field.is.already.defined.in.single.type.import=field ''{0}'' is already defined in a single-type import
++annotation.interface.members.may.not.have.parameters=@interface members may not have parameters
++
++local.variable.is.never.used=Variable ''{0}'' is never used
++local.variable.is.not.used.for.reading=Variable ''{0}'' is assigned but never accessed
++local.variable.is.not.assigned=Variable ''{0}'' is never assigned
++private.field.is.not.used=Private field ''{0}'' is never used
++field.is.not.used=Field ''{0}'' is never used
++private.field.is.not.used.for.reading=Private field ''{0}'' is assigned but never accessed
++private.field.is.not.assigned=Private field ''{0}'' is never assigned
++parameter.is.not.used=Parameter ''{0}'' is never used
++private.method.is.not.used=Private method ''{0}'' is never used
++method.is.not.used=Method ''{0}'' is never used
++constructor.is.not.used=Constructor ''{0}'' is never used
++private.constructor.is.not.used=Private constructor ''{0}'' is never used
++private.inner.class.is.not.used=Private inner class ''{0}'' is never used
++private.inner.interface.is.not.used=Private inner interface ''{0}'' is never used
++type.parameter.is.not.used=Type parameter ''{0}'' is never used
++local.class.is.not.used=Local class ''{0}'' is never used
++class.is.not.used=Class ''{0}'' is never used
++uidesigned.field.is.overwritten.by.generated.code=Field ''{0}'' is overwritten by generated code
++uidesigner.bound.field.type.mismatch=Types of GUI component (''{0}'') and bound field (''{1}'') do not match
++
++hexadecimal.numbers.must.contain.at.least.one.hexadecimal.digit=Hexadecimal numbers must contain at least one hexadecimal digit
++integer.number.too.large=Integer number too large
++long.number.too.large=Long number too large
++malformed.floating.point.literal=Malformed floating point literal
++illegal.line.end.in.character.literal=Illegal line end in character literal
++illegal.escape.character.in.character.literal=Illegal escape character in character literal
++too.many.characters.in.character.literal=Too many characters in character literal
++empty.character.literal=Empty character literal
++illegal.line.end.in.string.literal=Illegal line end in string literal
++illegal.escape.character.in.string.literal=Illegal escape character in string literal
++floating.point.number.too.large=Floating point number too large
++floating.point.number.too.small=Floating point number too small
++
++import.statement.identifier.or.asterisk.expected.=Identifier or '*' expected
++
++javadoc.exception.tag.exception.class.expected=Exception class expected
++javadoc.exception.tag.wrong.tag.value=Wrong tag value
++javadoc.exception.tag.class.is.not.throwable=Class {0} is not a descendant of Throwable
++javadoc.exception.tag.exception.is.not.thrown={0} is not declared to be thrown by method {1}
++javadoc.param.tag.paramter.name.expected=Parameter name expected
++javadoc.param.tag.type.parameter.name.expected=Type parameter name expected
++javadoc.param.tag.type.parameter.gt.expected='>' expected
++javadoc.value.tag.jdk15.required=@value tag may not have any arguments when JDK 1.4 or earlier is used
++javadoc.value.field.required=@value tag must reference a field
++javadoc.value.static.field.required=@value tag must reference a static field
++javadoc.value.field.with.initializer.required=@value tag must reference a field with a constant initializer
++
++expected.identifier=Identifier expected
++expected.comma.or.semicolon=',' or ';' expected
++unexpected.token=Unexpected token
++unexpected.eof=Unexpected end of file
++expected.class.or.interface='class' or 'interface' expected
++expected.identifier.or.type=Identifier or type expected
++expected.rbracket=']' expected
++expected.expression=Expression expected
++expected.semicolon=';' expected
++expected.class.reference=Class reference expected
++expected.lparen='(' expected
++expected.rparen=')' expected
++expected.eq='=' expected
++expected.value=Value expected
++expected.rbrace='}' expected
++expected.lbrace='{' expected
++unexpected.identifier=Unexpected identifier
++expected.gt='>' expected.
++expected.lbrace.or.semicolon='{' or ';' expected
++expected.parameter=Parameter expected
++expected.type.parameter=Type parameter expected
++expected.comma=',' expected
++expected.comma.or.rparen=',' or ')' expected
++unexpected.tokens.beyond.the.end.of.expression=Unexpected token(s) beyond the end of expression
++expected.colon=':' expected
++expected.type=Type expected
++expected.lbracket='[' expected
++expected.lparen.or.lbracket='(' or '[' expected
++expected.array.initializer=Array initializer expected
++unexpected.tokens=Unexpected tokens
++expected.gt.or.comma='>' or ',' expected.
++else.without.if='else' without 'if'
++catch.without.try='catch' without 'try'
++finally.without.try='finally' without 'try'
++expected.statement=Statement expected
++expected.while='while' expected
++expected.catch.or.finally='catch' or 'finally' expected
++expected.boolean.expression=Boolean expression expected
++error.cannot.resolve.class=Cannot resolve class ''{0}''
++error.cannot.resolve.class.or.package=Cannot resolve class or package ''{0}''
++expected.class.or.package=Expected class or package
++suspicious.name.assignment=''{0}'' should probably not be assigned to ''{1}''
++suspicious.name.parameter=''{0}'' should probably not be passed as parameter ''{1}''
++suspicious.name.return=''{0}'' should probably not be returned from method ''{1}''
++type.parameter.cannot.be.followed.by.other.bounds=Type parameter cannot be followed by other bounds
++generic.extend.exception=Generic class may not extend 'java.lang.Throwable'
++illegal.initializer=Illegal initializer for ''{0}''
++class.cannot.inherit.from.its.type.parameter=Class cannot inherit from its type parameter
++cannot.resolve.package=Cannot resolve package {0}
++override.not.allowed.in.interfaces=@Override is not allowed when implementing interface method
}
return files.size() > 0 ? VfsUtil.toVirtualFileArray(files) : null;
}
- if (DataConstantsEx.TARGET_PSI_ELEMENT.equals(dataId)) {
+ if (LangDataKeys.TARGET_PSI_ELEMENT.is(dataId)) {
return null;
}
- if (DataConstants.CUT_PROVIDER.equals(dataId)) {
+ if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) {
return myCopyPasteDelegator.getCutProvider();
}
- if (DataConstants.COPY_PROVIDER.equals(dataId)) {
+ if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) {
return myCopyPasteDelegator.getCopyProvider();
}
- if (DataConstants.PASTE_PROVIDER.equals(dataId)) {
+ if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) {
return myCopyPasteDelegator.getPasteProvider();
}
- if (DataConstants.IDE_VIEW.equals(dataId)) {
+ if (LangDataKeys.IDE_VIEW.is(dataId)) {
return myIdeView;
}
- if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) {
+ if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
- final List<Module> modules = getSelectedElements(Module.class);
- if (!modules.isEmpty()) {
+ final Module[] modules = getSelectedModules();
+ if (modules != null) {
return myDeleteModuleProvider;
}
final LibraryOrderEntry orderEntry = getSelectedLibrary();
}
- public static String removeQuotes(String s) {
+ public static String removeQuotes(@NotNull String s) {
if (s.startsWith(TRIPLE_QUOTES) || s.startsWith(TRIPLE_DOUBLE_QUOTES)) {
- if (s.length() >= 6 && s.endsWith(s.substring(0, 3))) {
+ if (s.endsWith(s.substring(0, 3))) {
return s.substring(3, s.length() - 3);
}
else {
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vcs.changes.ui.ChangesViewBalloonProblemNotifier;
import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.vcs.changes.ui.ChangesViewBalloonProblemNotifier;
+ import com.intellij.util.containers.SoftHashMap;
import com.intellij.util.net.HttpConfigurable;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
package org.jetbrains.idea.svn.dialogs;
import com.intellij.openapi.application.ApplicationManager;
+ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Pair;
import com.intellij.ui.GuiUtils;
import com.intellij.util.SystemProperties;
import org.jetbrains.idea.svn.SvnAuthenticationNotifier;
import java.security.cert.X509Certificate;
/**
- * Created by IntelliJ IDEA.
- * User: alex
- * Date: 25.06.2005
- * Time: 17:00:17
- * To change this template use File | Settings | File Templates.
+ * @author alex
*/
public class SvnAuthenticationProvider implements ISVNAuthenticationProvider {
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.dialogs.SvnAuthenticationProvider");
private final Project myProject;
private final SvnAuthenticationNotifier myAuthenticationNotifier;
+ private final SvnInteractiveAuthenticationProvider mySvnInteractiveAuthenticationProvider;
public SvnAuthenticationProvider(final SvnVcs svnVcs) {
myProject = svnVcs.getProject();
class.cannot.inherit.from.its.type.parameter=Class cannot inherit from its type parameter
cannot.resolve.package=Cannot resolve package {0}
override.not.allowed.in.interfaces=@Override is not allowed when implementing interface method
++<<<<<<< HEAD
+
++=======
++>>>>>>> idea90
--- /dev/null
- The following changes to JFlex 1.4.1 have been done by JetBrains developers:
++The following changes to JFlex 1.4.3 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.
++
++December 21, 2009
++ * Applied jflex-1.4.3-unicode-character-category.patch
++
--- /dev/null
- # JFlex start script $Revision: 2.0 $
+#! /bin/bash
+#
- PRG=${PRG##* }
++# JFlex start script $Revision$
+#
+# 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`
- newprg=${newprg##*-> }
- [ ${newprg} = ${newprg#/} ] && newprg=${PRG%/*}/${newprg}
++PRG="${PRG##* }"
+
+# If PRG is a symlink, trace it to the real home directory
+
+while [ -L "$PRG" ]
+do
+ newprg=$(ls -l ${PRG})
- PRG=${PRG%/*}
- JFLEX_HOME=${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 $@
--- /dev/null
- set JFLEX_HOME=..
+@echo off
+REM Please adjust the paths JFLEX_HOME and JAVA_HOME to suit your needs
+REM (please do not add a trailing backslash)
+
- REM %JAVA_HOME%\bin\java -classpath %CLPATH% JFlex.Main %1 %2 %3 %4 %5 %6 %7 %8 %9
++set JFLEX_HOME=C:\JFLEX
+
+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
- java -Xmx128m -jar %JFLEX_HOME%\lib\JFlex.jar %1 %2 %3 %4 %5 %6 %7 %8 %9
++%JAVA_HOME%\bin\java -classpath %CLPATH% JFlex.Main %1 %2 %3 %4 %5 %6 %7 %8 %9
+
+REM for JDK 1.2
++rem java -Xmx128m -jar %JFLEX_HOME%\lib\JFlex.jar %1 %2 %3 %4 %5 %6 %7 %8 %9
--- /dev/null
- JFlex can be easily integrated with <a HREF="http://jakarta.apache.org/ant/index.html"
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<title>JFlex Ant Task</title>
+</head>
+
+<body>
+
+<h2><a name="JFlex">JFlex Ant Task</a></h2>
+<p>
++ JFlex can be easily integrated with <a HREF="http://ant.apache.org/"
+ target="_top">Ant</a> build tool.
+ To use JFlex with Ant, simply copy JFlex.jar to <i>$ANT_HOME/lib/</i> directory.
+</p>
+<h3>Description</h3>
+<p>
+ The JFlex Ant Task invokes the <a HREF="http://jflex.de/" target="_top">JFlex</a> lexical
+ analyzer generator on a grammar file.
+</p>
+<p>
+ To use the JFlex task, the following line must be placed in the Ant build file:
+</p>
+<pre><taskdef classname="JFlex.anttask.JFlexTask" name="jflex" /></pre>
+
+<p>
+ The JFlex task requires the <i>file</i> attribute to be set to the source grammar file (*.flex).
+ Unless the target directory is specified with the <i>destdir</i> option,
+ the generated class will be saved to the same directory where grammar file resides.
+ Like javac, the JFlex task creates subdirectories in <i>destdir</i> according to the
+ generated class package.
+</p>
+<p>
+ This task only invokes JFlex if the grammar file is newer than the generated
+ files.
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0" width="80%">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ <td align="center" valign="top"><b>Default</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file="file"</td>
+ <td valign="top">The grammar file to process.</td>
+ <td valign="top" align="center">Yes</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td valign="top">destdir="dir"</td>
+ <td valign="top">
+ 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, <i>destdir</i> causes the generated file to be written to
+ {destdir}/<b>{package name}</b>. This behaviour is similar to <i>javac -d dir</i>.
+ </td>
+ <td valign="top" align="center">No</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td valign="top">outdir="dir"</td>
+ <td valign="top">
+ 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 <i>dir</i> regardless of the package name.
+ </td>
+ <td valign="top" align="center">No</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Display generation process messages.</td>
+ <td align="center" valign="top">No</td>
+ <td align="center" valign="top">"off"</td>
+ </tr>
+ <tr>
+ <td valign="top">dump</td>
+ <td valign="top">Dump character classes, NFA and DFA tables.</td>
+ <td align="center" valign="top">No</td>
+ <td align="center" valign="top">"off"</td>
+ </tr>
+ <tr>
+ <td valign="top">time or<p>timeStatistics</td>
+ <td valign="top">Display generation time statistics.</td>
+ <td align="center" valign="top">No</td>
+ <td align="center" valign="top">"off"</td>
+ </tr>
+ <tr>
+ <td valign="top">nomin or<p>skipMinimization</td>
+ <td valign="top">Skip minimization step.</td>
+ <td align="center" valign="top">No</td>
+ <td align="center" valign="top">"off"</td>
+ </tr>
+ <tr>
+ <td valign="top">skel="file" or<p>skeleton="file"</td>
+ <td valign="top">Use external skeleton file.</td>
+ <td align="center" valign="top">No</td>
+ <td align="center" valign="top">"off"</td>
+ </tr>
+ <tr>
+ <td valign="top">dot or<p>generateDot</td>
+ <td valign="top">Write graphviz .dot files for the generated automata (alpha).</td>
+ <td align="center" valign="top">No</td>
+ <td align="center" valign="top">"off"</td>
+ </tr>
+ <tr>
+ <td valign="top">nobak</td>
+ <td valign="top">Do not make a backup if the generated file exists.</td>
+ <td align="center" valign="top">No</td>
+ <td align="center" valign="top">"off"</td>
+ </tr>
+ <tr>
+ <td valign="top">switch</td>
+ <td valign="top">Use code generation method <i>switch</t>.</td>
+ <td align="center" valign="top">No</td>
+ <td align="center" valign="top">"off"</td>
+ </tr>
+ <tr>
+ <td valign="top">table</td>
+ <td valign="top">Use code generation method <i>table</t>.</td>
+ <td align="center" valign="top">No</td>
+ <td align="center" valign="top">"off"</td>
+ </tr>
+ <tr>
+ <td valign="top">pack</td>
+ <td valign="top">Use code generation method <i>pack</t>.</td>
+ <td align="center" valign="top">No</td>
+ <td align="center" valign="top">"on"</td>
+ </tr>
+
+</table>
+<h3>Example</h3>
+<blockquote><pre>
+<jflex
+ file="src/parser/Parser.flex"
+ destdir="build/generated/"
+/>
+</pre></blockquote>
+<p>
+ JFlex generates the lexical analyzer for <tt>src/parser/Parser.flex</tt> and saves the result
+ to <tt>build/generated/parser/</tt>, providing <tt>Parser.flex</tt> declares to be in package <tt>parser</tt>.
+</p>
+
+<blockquote><pre>
+<jflex
+ file="src/parser/Parser.flex"
+ destdir="build/generated/"
+/>
+<javac
+ srcdir="build/generated/"
+ destdir="build/classes/"
+/>
+</pre></blockquote>
+<p>
+ The same as above plus compile generated classes to <i>build/classes</i>
+</p>
+<hr>
+
+</body>
+</html>
+
--- /dev/null
- ;;; $Revision: 2.1 $, $Date: 2003/06/08 11:01:12 $
+; -*- Mode: Emacs-Lisp; -*-
+
+;;; jflex-mode
+
+;;; author: Gerwin Klein <lsf@jflex.de>
++;;; $Revision$, $Date$
+
+(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
+ "<<EOF>>" ; special <<EOF>> 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)
--- /dev/null
- " Last Change: $Revision: 2.1 $, $Date: 2003/06/08 11:01:12 $
+" Vim syntax file
+" Language: JFlex
+" Maintainer: Gerwin Klein <lsf@jflex.de>
++" Last Change: $Revision$, $Date$
+
+" 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 <state>)
+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 "<<EOF>>" 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"
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * @version JFlex 1.4.1, $Revision: 2.6 $, $Date: 2004/11/06 23:03:30 $
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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 $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+final public class Action {
+
- * True iff the action belongs to an lookahead expresstion
- * (<code>a/b</code> or <code>r$</code>)
++ /** A normal action */
++ public final static int NORMAL = 0;
++ /** Action of a lookahead expression r1/r2 with fixed length r1 */
++ public final static int FIXED_BASE = 1;
++ /** Action of a lookahead expression r1/r2 with fixed length r2 */
++ public final static int FIXED_LOOK = 2;
++ /** Action of a lookahead expression r1/r2 with a finite choice of
++ * fixed lengths in r2 */
++ public final static int FINITE_CHOICE = 3;
++ /** Action of a general lookahead expression */
++ public final static int GENERAL_LOOK = 4;
++ /** Action of the 2nd forward pass for lookahead */
++ public final static int FORWARD_ACTION = 5;
++ /** Action of the backward pass for lookahead */
++ public final static int BACKWARD_ACTION = 6;
++
+ /**
+ * The Java code this Action represents
+ */
+ String content;
+
+ /**
+ * The priority (i.e. line number in the specification) of this Action.
+ */
+ int priority;
+
+ /**
- private boolean isLookAction;
++ * Which kind of action this is.
++ * (normal, <code>a/b</code> with fixed length a, fixed length b, etc)
+ */
- return "Action (priority "+priority+", lookahead "+isLookAction+") :"+Out.NL+content; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
++ private int kind = NORMAL;
+
++ /** The length of the lookahead (if fixed) */
++ private int len;
++
++ /** The entry state of the corresponding forward DFA (if general lookahead) */
++ private int entryState;
+
+ /**
+ * 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;
+ }
+
++ /**
++ * Creates a new Action object of the specified kind. Only
++ * accepts FORWARD_ACTION or BACKWARD_ACTION.
++ *
++ * @param kind the kind of action
++ *
++ * @see #FORWARD_ACTION
++ * @see #BACKWARD_ACTION
++ */
++ public Action(int kind) {
++ if (kind != FORWARD_ACTION && kind != BACKWARD_ACTION)
++ throw new GeneratorException();
++ this.content = "";
++ this.priority = Integer.MAX_VALUE;
++ this.kind = kind;
++ }
+
+ /**
+ * 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 this == a || this.content.equals(a.content);
++ return "Action (priority "+priority+", lookahead "+kind+") :" +
++ Out.NL+content; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+
+ /**
+ * Returns <code>true</code> 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 look ahead flag.
++ return this == a ||
++ (this.content.equals(a.content) &&
++ this.kind == a.kind &&
++ this.len == a.len &&
++ this.entryState == a.entryState);
+ }
+
+
+ /**
+ * 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 true if this actions belongs to a lookahead rule
++ * Return true iff this is action belongs to a general lookahead rule.
++ *
++ * @return true if this actions belongs to a general lookahead rule.
++ */
++ public boolean isGenLookAction() {
++ return kind == GENERAL_LOOK;
++ }
++
++ /**
++ * Return true if code for this is action should be emitted, false
++ * if it is a BACK/FORWARD lookahead action.
++ *
++ * @return true if code should be emitted for this action.
++ */
++ public boolean isEmittable() {
++ return kind != BACKWARD_ACTION && kind != FORWARD_ACTION;
++ }
++
++ /**
++ * Return kind of lookahead.
++ */
++ public int lookAhead() {
++ return kind;
++ }
++
++ /**
++ * Sets the lookahead kind and data for this action
++ *
++ * @param kind which kind of lookahead it is
++ * @param data the length for fixed length look aheads.
++ *
++ */
++ public void setLookAction(int kind, int data) {
++ this.kind = kind;
++ this.len = data;
++ }
++
++ /**
++ * The length of the lookahead or base if this is a fixed length
++ * lookahead action.
++ */
++ public int getLookLength() {
++ return len;
++ }
++
++ /**
++ * Return the corresponding entry state for the forward DFA (if this
++ * is a general lookahead expression)
+ *
- public boolean isLookAction() {
- return isLookAction;
++ * @return the forward DFA entry state (+1 is the backward DFA)
+ */
- * Sets the look ahead flag for this action
++ public int getEntryState() {
++ return entryState;
+ }
+
+ /**
- * @param b set to true if this action belongs to a look ahead rule
++ * Set the corresponding entry state for the forward DFA of this action
++ * (if this is a general lookahead expression)
+ *
- public void setLookAction(boolean b) {
- isLookAction = b;
++ * @param the entry state for the forward DFA of this action
+ */
++ public void setEntryState(int entryState) {
++ this.entryState = entryState;
++ }
++
++ public Action copyChoice(int length) {
++ Action a = new Action(this.content, this.priority);
++ a.setLookAction(FINITE_CHOICE, length);
++ return a;
+ }
+
++ /**
++ * String representation of the lookahead kind of this action.
++ *
++ * @return the string representation
++ */
++ public String lookString() {
++ switch (kind) {
++ case NORMAL: return "";
++ case BACKWARD_ACTION: return "LOOK_BACK";
++ case FIXED_BASE: return "FIXED_BASE";
++ case FIXED_LOOK: return "FIXED_LOOK";
++ case FINITE_CHOICE: return "FINITE_CHOICE";
++ case FORWARD_ACTION: return "LOOK_FORWARD";
++ case GENERAL_LOOK: return "LOOK_ACTION";
++ default: return "unknown lookahead type";
++ }
++ }
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:30 $
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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 $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+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);
+ }
+
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:30 $
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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 <CODE>start</code> and smaller than or euqal to the Unicode
+ * value of <CODE>end</code>.
+ *
+ * All characters of the interval must belong to the same character class.
+ *
+ * @author Gerwin Klein
++ * @version $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+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 <CODE>start</code> to <CODE>end</code>
+ * that belongs to character class <CODE>charClass</code>.
+ *
+ * @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+"]";
+ }
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- import java.util.Vector;
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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;
+
- * @version JFlex 1.4.1, $Revision: 2.6 $, $Date: 2004/11/06 23:03:32 $
++import java.util.*;
+
+
+/**
+ *
+ * @author Gerwin Klein
- * Sets the larges Unicode value of the current input character set.
++ * @version $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+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;
+ }
+
+
+ /**
- * the union of all intervalls in the Vector.
++ * Sets the largest 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 <code>set</code> are not in the same
+ * equivalence class with characters that are not elements of <code>set</code>.
+ *
+ * @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 <code>singleChar</code>.
+ *
+ * @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 <code>v</code> are not in the same
+ * equivalence class with characters that are not elements of the set <code>v</code>.
+ *
+ * @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.
++ * the union of all intervals 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 <code>v</code> are not in the same
+ * equivalence class with characters that are not elements of the set <code>v</code>.
+ *
+ * This method is equivalent to <code>makeClass(v)</code>
+ *
+ * @param v a Vector of Interval objects.
+ * This Vector represents a set of characters. The set of characters is
- * @param intervallVec a Vector of Intervalls, the set of characters to get
++ * the union of all intervals 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 complement of the
++ * @param intervallVec a Vector of Intervals, 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 <strong>not</strong> in the specified set of input characters.
+ *
- public CharClassInterval [] getIntervalls() {
++ * @param intervallVec a Vector of Intervals, 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.
+ * <code>result[i+1].start = result[i].end+1</code>
+ *
+ * Each CharClassInterval contains the number of the
+ * char class it belongs to.
+ */
++ public CharClassInterval [] getIntervals() {
+ 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;
+ }
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:31 $
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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
- result.append( ", "+(int)i);
++ * @version $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+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; // modulus
+
+ long bits[];
+
+ private int numElements;
+
+
+ public CharSet() {
+ bits = new long[1];
+ }
+
+
+ public CharSet(int initialSize, int character) {
+ bits = new long[(initialSize >> 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( ", "+i);
+ }
+
+ result.append("}");
+
+ return result.toString();
+ }
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * @version JFlex 1.4.1, $Revision: 2.3 $, $Date: 2004/11/06 23:03:30 $
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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 $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+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;
+ }
+
+}
+
--- /dev/null
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * jflex 1.4 *
- * @version $Revision: 1.6 $, $Date: 2004/04/12 10:07:48 $
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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.4.3 $, $Date: 2009/12/21 15:58: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: <code>i = 1</code> allows values in [-1, 0xFFFE].
+ */
+ public void setValTranslation(int i) {
+ this.translate = i;
+ }
+
+ /**
+ * Emit one count/value pair.
+ *
+ * Automatically translates value by the <code>translate</code> value.
+ *
+ * @param count
+ * @param value
+ *
+ * @see CountEmitter#setValTranslation(int)
+ */
+ public void emit(int count, int value) {
+ numEntries+= count;
+ breaks();
+ emitUC(count);
+ emitUC(value+translate);
+ }
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- import java.io.File;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.Enumeration;
- import java.util.Hashtable;
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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;
+
+
- * @version JFlex 1.4.1, $Revision: 2.7 $, $Date: 2004/11/06 23:03:31 $
++import java.io.*;
++import java.util.*;
+
+
+/**
+ * DFA representation in JFlex.
+ * Contains minimization algorithm.
+ *
+ * @author Gerwin Klein
- /**
- * <code>isPushback[state] == true</code> <=> the state <code>state</code> is
- * a final state of an expression that can only be matched when followed by
- * a certain lookaead.
- */
- boolean [] isPushback;
-
-
- /**
- * <code>isLookEnd[state] == true</code> <=> the state <code>state</code> is
- * a final state of a lookahead expression.
- */
- boolean [] isLookEnd;
-
-
++ * @version $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+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 <code>current_state</code>
+ * with input <code>character</code>, <code>NO_TARGET</code> if there is no transition for
+ * this input in <code>current_state</code>
+ */
+ int [][] table;
+
+
+ /**
+ * <code>isFinal[state] == true</code> <=> the state <code>state</code> is
+ * a final state.
+ */
+ boolean [] isFinal;
+
- * lexState[i] is the start-state of lexical state i
++
+ /**
+ * <code>action[state]</code> is the action that is to be carried out in
+ * state <code>state</code>, <code>null</code> if there is no action.
+ */
+ Action [] action;
+
+ /**
- int lexState [];
++ * entryState[i] is the start-state of lexical state i or
++ * lookahead DFA i
+ */
-
++ int entryState [];
+
+ /**
+ * The number of states in this DFA
+ */
+ int numStates;
+
- public DFA(int numLexStates, int numInp) {
+ /**
+ * The current maximum number of input characters
+ */
+ int numInput;
+
++ /**
++ * The number of lexical states (2*numLexStates <= entryState.length)
++ */
++ int numLexStates;
+
+ /**
+ * all actions that are used in this DFA
+ */
+ Hashtable usedActions = new Hashtable();
+
- int statesNeeded = Math.max(numLexStates, STATES);
++ /** True iff this DFA contains general lookahead */
++ boolean lookaheadUsed;
++
++ public DFA(int numEntryStates, int numInp, int numLexStates) {
+ numInput = numInp;
+
- isPushback = new boolean [statesNeeded];
- isLookEnd = new boolean [statesNeeded];
- lexState = new int [numLexStates];
++ int statesNeeded = Math.max(numEntryStates, STATES);
+
+ table = new int [statesNeeded] [numInput];
+ action = new Action [statesNeeded];
+ isFinal = new boolean [statesNeeded];
- public void setLexState(int lState, int trueState) {
- lexState[lState] = trueState;
++ entryState = new int [numEntryStates];
+ numStates = 0;
+
++ this.numLexStates = numLexStates;
++
+ for (int i = 0; i < statesNeeded; i++) {
+ for (char j = 0; j < numInput; j++)
+ table [i][j] = NO_TARGET;
+ }
+ }
+
+
- boolean [] newLookEnd = new boolean [newLength];
++ public void setEntryState(int eState, int trueState) {
++ entryState[eState] = 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];
- System.arraycopy(isPushback,0,newPushback,0,numStates);
- System.arraycopy(isLookEnd,0,newLookEnd,0,numStates);
+ Action [] newAction = new Action [newLength];
+ int [] [] newTable = new int [newLength] [numInput];
+
+ System.arraycopy(isFinal,0,newFinal,0,numStates);
- isPushback = newPushback;
- isLookEnd = newLookEnd;
+ 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;
- isLookEnd[state] = stateAction.isLookAction();
+ action = newAction;
+ table = newTable;
+ }
+
+
+ public void setAction(int state, Action stateAction) {
+ action[state] = stateAction;
+ if (stateAction != null) {
- public void setPushback(int state, boolean isPushbackState) {
- isPushback[state] = isPushbackState;
- }
-
-
+ usedActions.put(stateAction,stateAction);
++ lookaheadUsed |= stateAction.isGenLookAction();
+ }
+ }
+
+ public void setFinal(int state, boolean isFinalState) {
+ isFinal[state] = isFinalState;
+ }
+
-
+ 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;
+ }
+
+
- if ( isFinal[i] ) result.append("[FINAL] "); // (action "+action[i].priority+")] ");
- if ( isPushback[i] ) result.append("[PUSH] ");
+ public String toString() {
+ StringBuffer result = new StringBuffer();
+
+ for (int i=0; i < numStates; i++) {
+ result.append("State ");
- 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);
++ if ( isFinal[i] ) {
++ result.append("[FINAL");
++ String l = action[i].lookString();
++ if (!l.equals("")) {
++ result.append(", ");
++ result.append(l);
++ }
++ result.append("] ");
++ }
+ 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++) {
- // check if all actions can actually be matched in this DFA
++ if ( isFinal[i] ) {
++ result.append(i);
++ result.append(" [shape = doublecircle]");
++ 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();
+ }
+
+
- 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);
++ /**
++ * Check that 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()) {
- 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;
- }
++ Action a = (Action) l.nextElement();
++ if ( !a.equals(usedActions.get(a)) && !eofActions.isEOFAction(a) ) {
++ Out.warning(scanner.file, ErrorMessages.NEVER_MATCH, a.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
- // count how many states of each B_i occuring in D go with a into B_j
++ 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;
+ }
+
- isPushback[j] = isPushback[i];
- isLookEnd[j] = isLookEnd[i];
++ // count how many states of each B_i occurring 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];
- for (i = 0; i < lexState.length; i++) {
- lexState[i] = trans[ lexState[i] ];
- lexState[i]-= move[ lexState[i] ];
+ action[j] = action[i];
+
+ j++;
+ }
+ }
+
+ numStates = j;
+
+ // translate lexical states
- // notequiv[i][j] == true <=> state i and state j are equivalent
++ for (i = 0; i < entryState.length; i++) {
++ entryState[i] = trans[ entryState[i] ];
++ entryState[i]-= move[ entryState[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+"}");
+ }
+
+
++ /**
++ * Much simpler, but slower and less memory efficient minimization algorithm.
++ *
++ * @return the equivalence relation on states.
++ */
+ 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;
+ }
+
- if ( isFinal[i] && isFinal[j] && (isPushback[i] == isPushback[j]) && (isLookEnd[i] == isLookEnd[j]) )
++ // equiv[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
+
- equiv[i][j] = !isFinal[j] && !isFinal[i] && (isPushback[i] == isPushback[j]) && (isLookEnd[i] == isLookEnd[j]);
++ if ( isFinal[i] && isFinal[j] )
+ equiv[i][j] = action[i].isEquiv(action[j]);
+ else
++ equiv[i][j] = !isFinal[j] && !isFinal[i];
+ }
+ }
+
+
+ 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);
+ }
+ }
+
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- import java.util.Enumeration;
- import java.util.Hashtable;
- import java.util.Vector;
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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;
+
- * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $
++import java.util.*;
+
+
+/**
+ * A simple table to store EOF actions for each lexical state.
+ *
+ * @author Gerwin Klein
++ * @version $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+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();
+ }
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Enumeration;
- import java.util.Hashtable;
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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.*;
- * @version JFlex 1.4.1, $Revision: 2.26 $, $Date: 2004/11/07 03:12:46 $
++import java.util.*;
++import java.text.*;
+
+/**
+ * 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
- static final private int PUSHBACK = 2;
- static final private int LOOKEND = 4;
++ * @version $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+final public class Emitter {
+
+ // bit masks for state attributes
+ static final private int FINAL = 1;
- private CharClassInterval [] intervalls;
+ 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();
+
- String name = parser.scanner.className+".java";
++ private CharClassInterval [] intervals;
+
+ private String visibility = "public";
+
+ public Emitter(File inputFile, LexParse parser, DFA dfa) throws IOException {
+
- * @param input fallback location if path = <tt>null</tt>
++ String name = getBaseName(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);
+ }
+
++ /**
++ * Computes base name of the class name. Needs to take into account generics.
++ *
++ * @see LexScan#className
++ * @return the
++ */
++ public static String getBaseName(String className) {
++ int gen = className.indexOf('<');
++ if (gen < 0) {
++ return className;
++ }
++ else {
++ return className.substring(0, gen);
++ }
++ }
++
+
+ /**
+ * 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
- println(" System.out.println(\"Usage : java "+scanner.className+" <inputfile>\");");
++ * @param input fall back location if path = <tt>null</tt>
+ * (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 boolean hasGenLookAhead() {
++ return dfa.lookaheadUsed;
++ }
++
++ private void emitLookBuffer() {
++ if (!hasGenLookAhead()) return;
++
++ println(" /** For the backwards DFA of general lookahead statements */");
++ println(" private boolean [] zzFin = new boolean [ZZ_BUFFERSIZE+1];");
++ println();
++ }
++
+ 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 <meissnersd@yahoo.com>");
+ 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 <meissnersd@yahoo.com>");
+ 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(" */");
+ }
+
++ String className = getBaseName(scanner.className);
++
+ println(" public static void main(String argv[]) {");
+ println(" if (argv.length == 0) {");
- println(" "+scanner.className+" scanner = null;");
++ println(" System.out.println(\"Usage : java "+className+" <inputfile>\");");
+ println(" }");
+ println(" else {");
+ println(" for (int i = 0; i < argv.length; i++) {");
- println(" scanner = new "+scanner.className+"( new java.io.FileReader(argv[i]) );");
++ println(" "+className+" scanner = null;");
+ println(" try {");
- private void emitNoMatch() {
- println(" zzScanError(ZZ_NO_MATCH);");
- }
-
++ println(" scanner = new "+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("");
+ }
+
- return "zzBufferArrayL != null ? zzBufferArrayL[" + idx + "]:zzBufferL.charAt("+idx+")";
+ private String zzBufferLAccess(String idx) {
+ if (Options.sliceAndCharAt) {
- if ( scanner.lookAheadUsed )
- println(" zzPushbackPos = zzPushbackPosL;");
++ return "zzBufferArrayL != null ? zzBufferArrayL[" + idx + "]:zzBufferL.charAt("+idx+")";
+ }
+ if (Options.char_at) {
+ return "zzBufferL.charAt("+idx+")";
+ }
+ return "zzBufferL[" + idx + "]";
+ }
+
++ private void emitNoMatch() {
++ println(" zzScanError(ZZ_NO_MATCH);");
++ }
++
+ 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(" zzPushbackPosL = zzPushbackPos;");
+ println(" boolean eof = zzRefill();");
+ println(" // get translated positions and possibly new buffer");
+ println(" zzCurrentPosL = zzCurrentPos;");
+ println(" zzMarkedPosL = zzMarkedPos;");
+ println(" zzBufferL = zzBuffer;");
+ println(" zzEndReadL = zzEndRead;");
- println(" }");
+ println(" if (eof) {");
+ println(" zzInput = YYEOF;");
+ println(" break zzForAction;");
+ println(" }");
+ println(" else {");
+ println(" zzInput = " + zzBufferLAccess("zzCurrentPosL++") + ";");
+ println(" }");
- println("/* The following code was generated by JFlex "+Main.version+" on "+date+" */");
- println("");
- }
++ println(" }");
+ }
+
+ private void emitHeader() {
- private void emitClassName() {
++ 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(" * on "+date+" from the specification file");
- println(" * <tt>"+path+"</tt>");
++
+ println("/**");
+ println(" * This class is a scanner generated by ");
+ println(" * <a href=\"http://www.jflex.de/\">JFlex</a> "+Main.version);
- }
++ println(" * on "+date+" from the specification file");
++ println(" * <tt>"+path+"</tt>");
+ println(" */");
- if (scanner.bolUsed)
- println(" "+visibility+" static final int "+name+" = "+2*num+";");
- else
- println(" "+visibility+" static final int "+name+" = "+dfa.lexState[2*num]+";");
++ }
+
+ 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("");
- 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(" ");
++ println(" "+visibility+" static final int "+name+" = "+2*num+";");
+ }
- for (i = 0; i < dfa.lexState.length-1; i++) {
- print( dfa.lexState[i], 2 );
+
- print(", ");
++ // can't quite get rid of the indirection, even for non-bol lex states:
++ // their DFA states might be the same, but their EOF actions might be different
++ // (see bug #1540228)
++ 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 < 2*dfa.numLexStates-1; i++) {
++ print( dfa.entryState[i], 2 );
+
- if (++j >= 16) {
- println();
- print(" ");
- j = 0;
- }
++ print(", ");
+
-
- println( dfa.lexState[i] );
- println(" };");
-
++ if (++j >= 16) {
++ println();
++ print(" ");
++ j = 0;
+ }
- println(" while (i < "+2*intervalls.length+") {");
+ }
++
++ println( dfa.entryState[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(" private static final int ZZ_TRANS [] = {"); //XXX
++ println(" while (i < "+2*intervals.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 [] = {");
+
+ 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() {
- intervalls = cl.getIntervalls();
++
+ CharClasses cl = parser.getCharClasses();
- 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;
- }
+
+ 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();
-
- i++;
++
++ // not very efficient, but good enough for <= 255 characters
++ for (char c = 0; c <= max; c++) {
++ print(colMap[cl.getClassCode(c)],2);
++
++ if (c < max) {
++ print(", ");
++ if ( ++n >= 16 ) {
++ println();
++ print(" ");
++ n = 0;
+ }
+ }
-
+ }
- // ignores cl.getMaxCharCode(), emits all intervalls instead
++
+ println();
+ println(" };");
+ println();
+ }
+
+ private void emitCharMapArray() {
+ CharClasses cl = parser.getCharClasses();
+
+ if ( cl.getMaxCharCode() < 256 ) {
+ emitCharMapArrayUnPacked();
+ return;
+ }
+
- intervalls = cl.getIntervalls();
++ // ignores cl.getMaxCharCode(), emits all intervals instead
+
- int i = 0;
- while ( i < intervalls.length-1 ) {
- int count = intervalls[i].end-intervalls[i].start+1;
- int value = colMap[intervalls[i].charClass];
-
++ intervals = cl.getIntervals();
+
+ 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(" \"");
+
- if ( ++n >= 10 ) {
- println("\"+");
- print(" \"");
- n = 0;
++ int i = 0;
++ int count, value;
++ while ( i < intervals.length ) {
++ count = intervals[i].end-intervals[i].start+1;
++ value = colMap[intervals[i].charClass];
++
++ // count could be >= 0x10000
++ while (count > 0xFFFF) {
++ printUC(0xFFFF);
++ printUC(value);
++ count -= 0xFFFF;
++ n++;
++ }
++
+ printUC(count);
+ printUC(value);
+
-
- printUC(intervalls[i].end-intervalls[i].start+1);
- printUC(colMap[intervalls[i].charClass]);
-
++ if (i < intervals.length-1) {
++ if ( ++n >= 10 ) {
++ println("\"+");
++ print(" \"");
++ n = 0;
++ }
+ }
+
+ i++;
+ }
- if ( dfa.isPushback[0] ) value|= PUSHBACK;
- if ( dfa.isLookEnd[0] ) value|= LOOKEND;
++
+ 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 <code>aState</code>");
+ println(" */");
+
+ CountEmitter e = new CountEmitter("Attribute");
+ e.emitInit();
+
+ int count = 1;
+ int value = 0;
+ if ( dfa.isFinal[0] ) value = FINAL;
- if ( dfa.isPushback[i] ) attribute|= PUSHBACK;
- if ( dfa.isLookEnd[i] ) attribute|= LOOKEND;
+ if ( !isTransition[0] ) value|= NOLOOK;
+
+ for (int i = 1; i < dfa.numStates; i++) {
+ int attribute = 0;
+ if ( dfa.isFinal[i] ) attribute = FINAL;
-
+ 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("");
+ }
- print( scanner.className );
- print("(java.io.Reader in)");
++
+ if ( scanner.classCode != null ) {
+ println(" /* user code: */");
+ println(scanner.classCode);
+ }
+ }
+
+ private void emitConstructorDecl() {
++ emitConstructorDecl(true);
++
++ if ((scanner.standalone || scanner.debugOption) &&
++ scanner.ctorArgs.size() > 0) {
++ Out.warning(ErrorMessages.get(ErrorMessages.CTOR_DEBUG));
++ println();
++ emitConstructorDecl(false);
++ }
++ }
++
++ private void emitConstructorDecl(boolean printCtorArgs) {
++
++ String warn =
++ "// WARNING: this is a default constructor for " +
++ "debug/standalone only. Has no custom parameters or init code.";
++
++ if (!printCtorArgs) println(warn);
+
+ print(" ");
+
+ if ( scanner.isPublic ) print("public ");
- if ( scanner.initThrow != null ) {
++ print( getBaseName(scanner.className) );
++ print("(java.io.Reader in");
++ if (printCtorArgs) emitCtorArgs();
++ print(")");
+
- if ( scanner.initCode != null ) {
++ if ( scanner.initThrow != null && printCtorArgs) {
+ print(" throws ");
+ print( scanner.initThrow );
+ }
+
+ println(" {");
+
-
++ if ( scanner.initCode != null && printCtorArgs) {
+ 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( scanner.className );
- print("(java.io.InputStream in)");
++ if (!printCtorArgs) println(warn);
++
+ print(" ");
+ if ( scanner.isPublic ) print("public ");
- if ( scanner.initThrow != null ) {
++ print( getBaseName(scanner.className) );
++ print("(java.io.InputStream in");
++ if (printCtorArgs) emitCtorArgs();
++ print(")");
+
- println(" this(new java.io.InputStreamReader(in));");
++ if ( scanner.initThrow != null && printCtorArgs ) {
+ print(" throws ");
+ print( scanner.initThrow );
+ }
+
+ println(" {");
- if ( scanner.lookAheadUsed ) {
- println(" int zzPushbackPosL = zzPushbackPos = -1;");
- println(" boolean zzWasPushback;");
- }
-
++
++ print(" this(new java.io.InputStreamReader(in)");
++ if (printCtorArgs) {
++ for (int i=0; i < scanner.ctorArgs.size(); i++) {
++ print(", "+scanner.ctorArgs.elementAt(i));
++ }
++ }
++ println(");");
++
+ println(" }");
+ }
+
++ private void emitCtorArgs() {
++ for (int i = 0; i < scanner.ctorArgs.size(); i++) {
++ print(", "+scanner.ctorTypes.elementAt(i));
++ print(" "+scanner.ctorArgs.elementAt(i));
++ }
++ }
+
+ 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;");
+
+ }
+
- println(" zzState = zzLexicalState;");
+ 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 {
- if (scanner.lookAheadUsed)
- println(" zzWasPushback = false;");
-
++ println(" zzState = ZZ_LEXSTATE[zzLexicalState];");
+ println();
+ }
+
- if ( scanner.lookAheadUsed ) {
- println(" if ( (zzAttributes & "+PUSHBACK+") == "+PUSHBACK+" )");
- println(" zzPushbackPosL = zzCurrentPosL;");
- println();
- }
-
+ 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(" zzWasPushback = (zzAttributes & "+LOOKEND+") == "+LOOKEND+";");
+ println(" if ( (zzAttributes & "+FINAL+") == "+FINAL+" ) {");
- if ( scanner.lookAheadUsed )
- println(" boolean zzPushback = false;");
-
+
+ skel.emitNext();
+
+ println(" if ( (zzAttributes & "+NOLOOK+") == "+NOLOOK+" ) break zzForAction;");
+
+ skel.emitNext();
+ }
+
+ private void emitTransitionTable() {
+ transformTransitionTable();
+
+ println(" zzInput = zzCMapL[zzInput];");
+ println();
+
- if ( scanner.lookAheadUsed )
- println(" zzWasPushback = zzPushback;");
-
+ 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 ) {");
+
- int newVal;
+ 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++) {
- Integer stored = (Integer) actionTable.get(action);
- if ( stored == null ) {
- stored = new Integer(lastAction++);
- actionTable.put(action, stored);
++ int newVal = 0;
+ if ( dfa.isFinal[i] ) {
+ Action action = dfa.action[i];
- newVal = stored.intValue();
- }
- else {
- newVal = 0;
++ if (action.isEmittable()) {
++ Integer stored = (Integer) actionTable.get(action);
++ if ( stored == null ) {
++ stored = new Integer(lastAction++);
++ actionTable.put(action, stored);
++ }
++ newVal = stored.intValue();
+ }
- // 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) {
+ }
+
+ 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 (action.lookAhead() == Action.FIXED_BASE) {
++ println(" // lookahead expression with fixed base length");
++ println(" zzMarkedPos = zzStartRead + "+action.getLookLength()+";");
++ }
++
++ if (action.lookAhead() == Action.FIXED_LOOK ||
++ action.lookAhead() == Action.FINITE_CHOICE) {
++ println(" // lookahead expression with fixed lookahead length");
++ println(" yypushback("+action.getLookLength()+");");
++ }
++
++ if (action.lookAhead() == Action.GENERAL_LOOK) {
++ println(" // general lookahead, find correct zzMarkedPos");
++ println(" { int zzFState = "+dfa.entryState[action.getEntryState()]+";");
++ println(" int zzFPos = zzStartRead;");
++ println(" if (zzFin.length <= zzBufferL.length) { zzFin = new boolean[zzBufferL.length+1]; }");
++ println(" boolean zzFinL[] = zzFin;");
++ println(" while (zzFState != -1 && zzFPos < zzMarkedPos) {");
++ println(" if ((zzAttrL[zzFState] & 1) == 1) { zzFinL[zzFPos] = true; } ");
++ println(" zzInput = zzBufferL[zzFPos++];");
++ println(" zzFState = zzTransL[ zzRowMapL[zzFState] + zzCMapL[zzInput] ];");
++ println(" }");
++ println(" if (zzFState != -1 && (zzAttrL[zzFState] & 1) == 1) { zzFinL[zzFPos] = true; } ");
++ println();
++ println(" zzFState = "+dfa.entryState[action.getEntryState()+1]+";");
++ println(" zzFPos = zzMarkedPos;");
++ println(" while (!zzFinL[zzFPos] || (zzAttrL[zzFState] & 1) != 1) {");
++ println(" zzInput = zzBufferL[--zzFPos];");
++ println(" zzFState = zzTransL[ zzRowMapL[zzFState] + zzCMapL[zzInput] ];");
++ println(" };");
++ println(" zzMarkedPos = zzFPos;");
++ println(" }");
++ }
++
+ 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);
+
- else if ( scanner.isInteger )
++ if (action != null) {
+ 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: <<EOF>>\");");
+ 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: <<EOF>>\");");
+ print(" System.out.println(\"action ["+defaultAction.priority+"] { ");
+ print(escapify(defaultAction.content));
+ println(" }\");");
+ }
+ println(" " + defaultAction.content);
+ println(" }");
+ }
+ else if ( scanner.eofVal != null )
+ println(" { " + scanner.eofVal + " }");
- print((int)chars.nextElement());
++ else if ( scanner.isInteger ) {
++ if ( scanner.tokenType != null ) {
++ Out.error(ErrorMessages.INT_AND_TYPE);
++ throw new GeneratorException();
++ }
+ 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(chars.nextElement());
+ print(": ");
+
+ while ( chars.hasMoreElements() ) {
+ println();
+ print(" case ");
- if ( dfa.isPushback[nextState] )
- print("zzPushbackPosL = zzCurrentPosL; ");
-
- if ( dfa.isLookEnd[nextState] )
- print("zzPushback = true; ");
-
++ print(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; ");
+
- private void emitPushback() {
- println(" if (zzWasPushback)");
- println(" zzMarkedPos = zzPushbackPosL;");
- }
-
+ if ( !isTransition[nextState] )
+ print("zzNoLookAhead = true; ");
+
+ if ( nextState == state )
+ println("break zzForNext;");
+ else
+ println("zzState = "+nextState+"; break zzForNext;");
+ }
+ else
+ println( "break zzForAction;" );
+ }
+
- * Set up EOF code sectioin according to scanner.eofcode
+ 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 section 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();
- if (scanner.lookAheadUsed)
- emitPushback();
-
++
+ skel.emitNext();
+
++ emitLookBuffer();
++
+ emitClassCode();
+
+ skel.emitNext();
+
+ emitConstructorDecl();
+
+ emitCharMapInitFunction();
+
+ skel.emitNext();
+
+ emitScanError();
+
+ skel.emitNext();
+
+ emitDoEOF();
+
+ skel.emitNext();
+
+ emitLexFunctHeader();
+
+ emitNextInput();
+
+ if (scanner.useRowMap)
+ emitGetRowMapNext();
+ else
+ emitTransitionTable();
+
+ skel.emitNext();
+
+ emitActions();
+
+ skel.emitNext();
+
+ emitEOFVal();
+
+ skel.emitNext();
+
+ emitNoMatch();
+
+ skel.emitNext();
+
+ emitMain();
+
+ skel.emitNext();
+
+ out.close();
+ }
+
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * @version JFlex 1.4.1, $Revision: 2.8 $, $Date: 2004/11/06 23:03:30 $
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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
- private static final ResourceBundle RESOURCE_BUNDLE =
- ResourceBundle.getBundle("JFlex.Messages");
++ * @version $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+public class ErrorMessages {
+ private String key;
+
- return RESOURCE_BUNDLE.getString(msg.key);
++ /* not final static, because initializing here seems too early
++ * for OS/2 JDK 1.1.8. See bug 1065521.
++ */
++ private static ResourceBundle resourceBundle = null;
+
+ private ErrorMessages(String key) {
+ this.key = key;
+ }
+
+ public static String get(ErrorMessages msg) {
++ if (resourceBundle == null) {
++ resourceBundle = ResourceBundle.getBundle("JFlex.Messages");
++ }
+ try {
- public static ErrorMessages LOOKAHEAD_ERROR = new ErrorMessages("LOOKAHEAD_ERROR");
++ return resourceBundle.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 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");
++ public static ErrorMessages LOOKAHEAD_NEEDS_ACTION = new ErrorMessages("LOOKAHEAD_NEEDS_ACTION");
++ public static ErrorMessages EMPTY_MATCH = new ErrorMessages("EMPTY_MATCH");
++ public static ErrorMessages CTOR_ARG = new ErrorMessages("CTOR_ARG");
++ public static ErrorMessages CTOR_DEBUG = new ErrorMessages("CTOR_DEBUG");
++ public static ErrorMessages INT_AND_TYPE = new ErrorMessages("INT_AND_TYPE");
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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 $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+public class GeneratorException extends RuntimeException {
+
+ public GeneratorException() {
+ super("Generation aborted");
+ }
+
+}
--- /dev/null
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * jflex *
- * @version $Revision: 1.5 $, $Date: 2004/04/12 10:07:48 $
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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.4.3 $, $Date: 2009/12/21 15:58: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);
+ }
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- import java.util.Vector;
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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;
+
- * @version JFlex 1.4.1, $Revision: 2.9 $, $Date: 2004/11/07 00:12:48 $
++import java.util.*;
+
+
+/**
+ * CharSet implemented with intervalls
+ *
+ * [fixme: optimizations possible]
+ *
+ * @author Gerwin Klein
++ * @version $Revision: 1.4.3 $, $Date: 2009/12/21 15:58: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.
+ * <p>
+ * 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;
+ }
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * @version JFlex 1.4.1, $Revision: 2.2 $, $Date: 2004/11/06 23:03:32 $
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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 $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+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+")";
+ }
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * @version JFlex 1.4.1, $Revision: 2.4 $, $Date: 2004/11/06 23:03:30 $
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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 $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
+ */
+public final class Interval {
+
+ /* start and end of the intervall */
+ public char start, end;
+
+
+ /**
+ * Constuct a new intervall from <code>start</code> to <code>end</code>.
+ *
+ * @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 <code>true</code> iff <code>point</code> is contained in this intervall.
+ *
+ * @param point the character to check
+ */
+ public boolean contains(char point) {
+ return start <= point && end >= point;
+ }
+
+
+ /**
+ * Return <code>true</code> 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 <code>true</code> if <code>o</code> 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 <code>"[start-end]"</code> or
+ * <code>"[start]"</code> (if there is only one character in
+ * the intervall) where <code>start</code> and
+ * <code>end</code> are either a number (the character code)
+ * or something of the from <code>'a'</code>.
+ */
+ 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);
+ }
+}
--- /dev/null
- * JFlex 1.4.1 *
- * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- CharClasses charClasses = new CharClasses(127);
++ * JFlex 1.4.3 *
++ * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> *
+ * 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;
- MORETHAN, LBRACE, RBRACE, FULL, UNICODE, REGEXPEND;
++ CharClasses charClasses = new CharClasses(Options.jlex ? 127 : 0xFFFF);
+ 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);
+
++ case sym.UNICODE_UNASSIGNED:
++ return Character.getType(c) == Character.UNASSIGNED;
++
++ case sym.UNICODE_UPPERCASE_LETTER:
++ return Character.getType(c) == Character.UPPERCASE_LETTER;
++
++ case sym.UNICODE_LOWERCASE_LETTER:
++ return Character.getType(c) == Character.LOWERCASE_LETTER;
++
++ case sym.UNICODE_TITLECASE_LETTER:
++ return Character.getType(c) == Character.TITLECASE_LETTER;
++
++ case sym.UNICODE_MODIFIER_LETTER:
++ return Character.getType(c) == Character.MODIFIER_LETTER;
++
++ case sym.UNICODE_OTHER_LETTER:
++ return Character.getType(c) == Character.OTHER_LETTER;
++
++ case sym.UNICODE_NON_SPACING_MARK:
++ return Character.getType(c) == Character.NON_SPACING_MARK;
++
++ case sym.UNICODE_ENCLOSING_MARK:
++ return Character.getType(c) == Character.ENCLOSING_MARK;
++
++ case sym.UNICODE_COMBINING_SPACING_MARK:
++ return Character.getType(c) == Character.COMBINING_SPACING_MARK;
++
++ case sym.UNICODE_DECIMAL_DIGIT_NUMBER:
++ return Character.getType(c) == Character.DECIMAL_DIGIT_NUMBER;
++
++ case sym.UNICODE_LETTER_NUMBER:
++ return Character.getType(c) == Character.LETTER_NUMBER;
++
++ case sym.UNICODE_OTHER_NUMBER:
++ return Character.getType(c) == Character.OTHER_NUMBER;
++
++ case sym.UNICODE_SPACE_SEPARATOR:
++ return Character.getType(c) == Character.SPACE_SEPARATOR;
++
++ case sym.UNICODE_LINE_SEPARATOR:
++ return Character.getType(c) == Character.LINE_SEPARATOR;
++
++ case sym.UNICODE_PARAGRAPH_SEPARATOR:
++ return Character.getType(c) == Character.PARAGRAPH_SEPARATOR;
++
++ case sym.UNICODE_CONTROL:
++ return Character.getType(c) == Character.CONTROL;
++
++ case sym.UNICODE_FORMAT:
++ return Character.getType(c) == Character.FORMAT;
++
++ case sym.UNICODE_PRIVATE_USE:
++ return Character.getType(c) == Character.PRIVATE_USE;
++
++ case sym.UNICODE_SURROGATE:
++ return Character.getType(c) == Character.SURROGATE;
++
++ case sym.UNICODE_DASH_PUNCTUATION:
++ return Character.getType(c) == Character.DASH_PUNCTUATION;
++
++ case sym.UNICODE_START_PUNCTUATION:
++ return Character.getType(c) == Character.START_PUNCTUATION;
++
++ case sym.UNICODE_END_PUNCTUATION:
++ return Character.getType(c) == Character.END_PUNCTUATION;
++
++ case sym.UNICODE_CONNECTOR_PUNCTUATION:
++ return Character.getType(c) == Character.CONNECTOR_PUNCTUATION;
++
++ case sym.UNICODE_OTHER_PUNCTUATION:
++ return Character.getType(c) == Character.OTHER_PUNCTUATION;
++
++ case sym.UNICODE_MATH_SYMBOL:
++ return Character.getType(c) == Character.MATH_SYMBOL;
++
++ case sym.UNICODE_CURRENCY_SYMBOL:
++ return Character.getType(c) == Character.CURRENCY_SYMBOL;
++
++ case sym.UNICODE_MODIFIER_SYMBOL:
++ return Character.getType(c) == Character.MODIFIER_SYMBOL;
++
++ case sym.UNICODE_OTHER_SYMBOL:
++ return Character.getType(c) == Character.OTHER_SYMBOL;
++
++ case sym.UNICODE_INITIAL_QUOTE_PUNCTUATION:
++ return Character.getType(c) == Character.INITIAL_QUOTE_PUNCTUATION;
++
++ case sym.UNICODE_FINAL_QUOTE_PUNCTUATION:
++ return Character.getType(c) == Character.FINAL_QUOTE_PUNCTUATION;
++
+ 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,
- UPPERCLASS, LOWERCLASS, EOFRULE, NOACTION, LOOKAHEAD;
++ MORETHAN, LBRACE, RBRACE, ASCII, FULL, UNICODE, REGEXPEND;
+
+terminal JLETTERCLASS, JLETTERDIGITCLASS, LETTERCLASS, DIGITCLASS,
- non terminal RegExp series, concs, nregexp, regexp, charclass, lookaheadOPT;
- non terminal Interval classcontentelem;
++ UPPERCLASS, LOWERCLASS, EOFRULE, NOACTION, LOOKAHEAD,
++
++ UNICODE_UNASSIGNED, UNICODE_UPPERCASE_LETTER, UNICODE_LOWERCASE_LETTER, UNICODE_TITLECASE_LETTER,
++ UNICODE_MODIFIER_LETTER, UNICODE_OTHER_LETTER, UNICODE_NON_SPACING_MARK, UNICODE_ENCLOSING_MARK,
++ UNICODE_COMBINING_SPACING_MARK, UNICODE_DECIMAL_DIGIT_NUMBER, UNICODE_LETTER_NUMBER, UNICODE_OTHER_NUMBER,
++ UNICODE_SPACE_SEPARATOR, UNICODE_LINE_SEPARATOR, UNICODE_PARAGRAPH_SEPARATOR, UNICODE_CONTROL, UNICODE_FORMAT,
++ UNICODE_PRIVATE_USE, UNICODE_SURROGATE, UNICODE_DASH_PUNCTUATION, UNICODE_START_PUNCTUATION,
++ UNICODE_END_PUNCTUATION, UNICODE_CONNECTOR_PUNCTUATION, UNICODE_OTHER_PUNCTUATION, UNICODE_MATH_SYMBOL,
++ UNICODE_CURRENCY_SYMBOL, UNICODE_MODIFIER_SYMBOL, UNICODE_OTHER_SYMBOL, UNICODE_INITIAL_QUOTE_PUNCTUATION,
++ UNICODE_FINAL_QUOTE_PUNCTUATION;
+
+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 Action actions;
++non terminal RegExp series, concs, nregexp, regexp, charclass, lookahead;
++non terminal Interval classcontentelem;
+non terminal Vector states, statesOPT, classcontent, preclass, rules;
+non terminal Boolean hatOPT;
- SemCheck.check(regExps, macros, charClasses.getMaxCharCode(), scanner.file);
++non terminal Action act, 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.");
+ }
+
- Out.time(ErrorMessages.NFA_TOOK, t);
++ SemCheck.check(regExps, macros, scanner.file);
+
+ regExps.checkActions();
++ regExps.checkLookAheads();
++
++ Out.checkErrors();
+
+ 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("");
- macro ::= FULL
++ 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;
+
- regExps.addStates( elem.intValue(), states );
++macro ::= ASCII
++ {: charClasses.setMaxCharCode(127); :}
++ | 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 );
++ // might be null for error case of "rule"
++ if (elem != null) {
++ 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();
- rule ::= statesOPT:s hatOPT:bol series:r lookaheadOPT:l actions:a
++ // might be null for error case of "rule"
++ if (elem != null) {
++ regExps.addStates( elem.intValue(), states );
++ }
+ }
+ RESULT = rlist;
+ :}
+ | rule:r
+ {: RESULT = new Vector(); RESULT.addElement(r); :}
+ ;
+
- | error
++rule ::= statesOPT:s hatOPT:bol series:r actions:a
++ {: RESULT = new Integer(regExps.insert(rleft, s, r, a, bol, null)); :}
++ | statesOPT:s hatOPT:bol series:r lookahead:l act:a
+ {: RESULT = new Integer(regExps.insert(rleft, s, r, a, bol, l)); :}
++ | statesOPT:s hatOPT:bol series:r lookahead:l NOACTION:a
++ {: syntaxError(ErrorMessages.LOOKAHEAD_NEEDS_ACTION, aleft, aright+1); :}
+ | statesOPT:s EOFRULE ACTION:a
+ {: RESULT = new Integer(regExps.insert(s, a)); :}
- lookaheadOPT ::= DOLLAR
++ | error
+ ;
+
- | /* empty */
- {: RESULT = null; :}
++lookahead ::= DOLLAR
+ {: RESULT = makeNL(); :}
+ | LOOKAHEAD series:r
+ {: RESULT = r; :}
- actions ::= REGEXPEND ACTION:a
+ | LOOKAHEAD series:s DOLLAR
+ {: RESULT = new RegExp2(sym.CONCAT, s, makeNL()); :}
+ ;
+
- {: RESULT = null; :}
++act ::= REGEXPEND ACTION:a
++ {: RESULT = a; :}
++ ;
++
++actions ::= act:a
+ {: RESULT = a; :}
+ | NOACTION
+ ;
+
+
+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); :}
++ | UNICODE_UNASSIGNED
++ {: RESULT = makePreClass(sym.UNICODE_UNASSIGNED); :}
++ | UNICODE_UPPERCASE_LETTER
++ {: RESULT = makePreClass(sym.UNICODE_UPPERCASE_LETTER); :}
++ | UNICODE_LOWERCASE_LETTER
++ {: RESULT = makePreClass(sym.UNICODE_LOWERCASE_LETTER); :}
++ | UNICODE_TITLECASE_LETTER
++ {: RESULT = makePreClass(sym.UNICODE_TITLECASE_LETTER); :}
++ | UNICODE_MODIFIER_LETTER
++ {: RESULT = makePreClass(sym.UNICODE_MODIFIER_LETTER); :}
++ | UNICODE_OTHER_LETTER
++ {: RESULT = makePreClass(sym.UNICODE_OTHER_LETTER); :}
++ | UNICODE_NON_SPACING_MARK
++ {: RESULT = makePreClass(sym.UNICODE_NON_SPACING_MARK); :}
++ | UNICODE_ENCLOSING_MARK
++ {: RESULT = makePreClass(sym.UNICODE_ENCLOSING_MARK); :}
++ | UNICODE_COMBINING_SPACING_MARK
++ {: RESULT = makePreClass(sym.UNICODE_COMBINING_SPACING_MARK); :}
++ | UNICODE_DECIMAL_DIGIT_NUMBER
++ {: RESULT = makePreClass(sym.UNICODE_DECIMAL_DIGIT_NUMBER); :}
++ | UNICODE_LETTER_NUMBER
++ {: RESULT = makePreClass(sym.UNICODE_LETTER_NUMBER); :}
++ | UNICODE_OTHER_NUMBER
++ {: RESULT = makePreClass(sym.UNICODE_OTHER_NUMBER); :}
++ | UNICODE_SPACE_SEPARATOR
++ {: RESULT = makePreClass(sym.UNICODE_SPACE_SEPARATOR); :}
++ | UNICODE_LINE_SEPARATOR
++ {: RESULT = makePreClass(sym.UNICODE_LINE_SEPARATOR); :}
++ | UNICODE_PARAGRAPH_SEPARATOR
++ {: RESULT = makePreClass(sym.UNICODE_PARAGRAPH_SEPARATOR); :}
++ | UNICODE_CONTROL
++ {: RESULT = makePreClass(sym.UNICODE_CONTROL); :}
++ | UNICODE_FORMAT
++ {: RESULT = makePreClass(sym.UNICODE_FORMAT); :}
++ | UNICODE_PRIVATE_USE
++ {: RESULT = makePreClass(sym.UNICODE_PRIVATE_USE); :}
++ | UNICODE_SURROGATE
++ {: RESULT = makePreClass(sym.UNICODE_SURROGATE); :}
++ | UNICODE_DASH_PUNCTUATION
++ {: RESULT = makePreClass(sym.UNICODE_DASH_PUNCTUATION); :}
++ | UNICODE_START_PUNCTUATION
++ {: RESULT = makePreClass(sym.UNICODE_START_PUNCTUATION); :}
++ | UNICODE_END_PUNCTUATION
++ {: RESULT = makePreClass(sym.UNICODE_END_PUNCTUATION); :}
++ | UNICODE_CONNECTOR_PUNCTUATION
++ {: RESULT = makePreClass(sym.UNICODE_CONNECTOR_PUNCTUATION); :}
++ | UNICODE_OTHER_PUNCTUATION
++ {: RESULT = makePreClass(sym.UNICODE_OTHER_PUNCTUATION); :}
++ | UNICODE_MATH_SYMBOL
++ {: RESULT = makePreClass(sym.UNICODE_MATH_SYMBOL); :}
++ | UNICODE_CURRENCY_SYMBOL
++ {: RESULT = makePreClass(sym.UNICODE_CURRENCY_SYMBOL); :}
++ | UNICODE_MODIFIER_SYMBOL
++ {: RESULT = makePreClass(sym.UNICODE_MODIFIER_SYMBOL); :}
++ | UNICODE_OTHER_SYMBOL
++ {: RESULT = makePreClass(sym.UNICODE_OTHER_SYMBOL); :}
++ | UNICODE_INITIAL_QUOTE_PUNCTUATION
++ {: RESULT = makePreClass(sym.UNICODE_INITIAL_QUOTE_PUNCTUATION); :}
++ | UNICODE_FINAL_QUOTE_PUNCTUATION
++ {: RESULT = makePreClass(sym.UNICODE_FINAL_QUOTE_PUNCTUATION); :}
+ ;
--- /dev/null
- // The following code was generated by CUP v0.10k
- // Sun Nov 07 14:07:52 GMT+10:00 2004
+
+//----------------------------------------------------
- import java.util.Enumeration;
- import java.util.Timer;
- import java.util.Vector;
++// The following code was generated by CUP v0.11a beta 20060608