Merge
authorJan Vrany <jan.vrany@fit.cvut.cz>
Mon, 17 Aug 2015 12:56:02 +0100
changeset 516 3b81c9e53352
parent 514 46dd1237b20a (current diff)
parent 515 b5316ef15274 (diff)
child 517 9a7fa841f12e
Merge
compiler/Make.proto
compiler/Make.spec
compiler/PEGFsa.st
compiler/PEGFsaInterpret.st
compiler/PEGFsaState.st
compiler/PEGFsaTransition.st
compiler/PPCASTUtilities.st
compiler/PPCClassBuilder.st
compiler/PPCCodeBlock.st
compiler/PPCCodeGenerator.st
compiler/PPCCompilationError.st
compiler/PPCCompiler.st
compiler/PPCInlinedMethod.st
compiler/PPCInliningVisitor.st
compiler/PPCMethod.st
compiler/PPCNode.st
compiler/PPCScanner.st
compiler/PPCScannerCodeGenerator.st
compiler/PPCSequenceNode.st
compiler/PPCSpecializingVisitor.st
compiler/PPCStarCharSetPredicateNode.st
compiler/PPCTokenCodeGenerator.st
compiler/PPCTokenizingCodeGenerator.st
compiler/PPCTokenizingConfiguration.st
compiler/PPCTokenizingVisitor.st
compiler/abbrev.stc
compiler/bc.mak
compiler/benchmarks/PPCBenchmark.st
compiler/extensions.st
compiler/libInit.cc
compiler/stx_goodies_petitparser_compiler.st
compiler/tests/Make.proto
compiler/tests/PPCCodeGeneratorTest.st
compiler/tests/PPCTokenizingTest.st
compiler/tests/PPCUniversalTest.st
compiler/tests/bc.mak
compiler/tests/extras/Make.proto
compiler/tests/extras/Make.spec
compiler/tests/extras/PPCAbstractParserTest.st
compiler/tests/extras/PPCCompositeParserTest.st
compiler/tests/extras/PPCExpressionGrammarVerificationTest.st
compiler/tests/extras/PPCLRPMachine.st
compiler/tests/extras/PPCLRPParser.st
compiler/tests/extras/PPCLRPParserSmokeTest.st
compiler/tests/extras/PPCLRPSourcesResource.st
compiler/tests/extras/PPCResources.st
compiler/tests/extras/PPCSetUpBeforeTearDownAfterResource.st
compiler/tests/extras/PPCSmalltalkGrammarTests.st
compiler/tests/extras/PPCSmalltalkGrammarVerificationTest.st
compiler/tests/extras/PPCSmalltalkGrammarVerificationTest_Tokenized.st
compiler/tests/extras/PPCSmalltalkParserVerificationTest.st
compiler/tests/extras/PPCSmalltalkTests.st
compiler/tests/extras/PPExpressionGrammarVerificationTest_Tokenized.st
compiler/tests/extras/PPExpressionGrammarVerificationTest_Universal.st
compiler/tests/extras/PPLL1ExpressionGrammar.st
compiler/tests/extras/PPLL1ExpressionGrammarTest.st
compiler/tests/extras/abbrev.stc
compiler/tests/extras/bc.mak
compiler/tests/extras/libInit.cc
compiler/tests/extras/stx_goodies_petitparser_compiler_tests_extras.st
--- a/compiler/FooScanner.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/FooScanner.st	Mon Aug 17 12:56:02 2015 +0100
@@ -4,131 +4,146 @@
 
 PPCScanner subclass:#FooScanner
 	instanceVariableNames:''
-	classVariableNames:''
+	classVariableNames:'MaxSymbolNumber Tokens'
 	poolDictionaries:''
 	category:'PetitCompiler-Scanner'
 !
 
-!FooScanner methodsFor:'as yet unclassified'!
+!FooScanner class methodsFor:'as yet unclassified'!
+
+initialize
+    super initialize.
+    
+    MaxSymbolNumber := 3.
+    Tokens := #(#A1 #A2 #B).
+! !
+
+!FooScanner methodsFor:'distinct'!
 
 nextTokenA
     "a"
+    self resetDistinct.
+    
     self step.
     self peek == $a ifFalse: [ ^ self return ].
 
-    self recordMatch: #a.
+    self recordDistinctMatch: #a.
 
-    ^ self return
+    ^ self returnDistinct
 !
 
 nextTokenAAorA
     "aa / a"
+    self resetDistinct.
+    
     self step.
-    (self peek == $a) ifFalse: [ ^ self return ].
-    self recordMatch: #a priority: -1.	
+    (self peek == $a) ifFalse: [ ^ self returnDistinct ].
+    self recordDistinctMatch: #a.	
 
     self step.
-    (self peek == $a) ifFalse: [ ^ self return ].
-    self recordMatch: #aa priority: 0.	
+    (self peek == $a) ifFalse: [ ^ self returnDistinct ].
+    self recordDistinctMatch: #aa.	
 
-    ^ self return.
+    ^ self returnDistinct.
 !
 
 nextTokenAAplusA
     "(aa)+a"
+    self resetDistinct.
+    
     self step.
-    self peek == $a ifFalse: [ ^ self return ].
+    self peek == $a ifFalse: [ ^ self returnDistinct ].
 
     self step.
-    self peek == $a ifFalse: [ ^ self return. ].
+    self peek == $a ifFalse: [ ^ self returnDistinct. ].
 
     [ 
+        self recordDistinctMatch: nil.
+
         self step.
-        self peek == $a ifFalse: [ ^ self returnPriority: 0 ].
-        self recordMatch: #AAplusA priority: -1.
+        self peek == $a ifFalse: [ ^ self returnDistinct ].
+        self recordDistinctMatch: #AAplusA.
 
         self step.
         self peek == $a.
     ] whileTrue.
 
-    ^ self returnPriority: -1
+    ^ self returnDistinct
 !
 
 nextTokenAAstarA
     "(aa)*a"
+    self resetDistinct.
+    
     self step.
-    self peek == $a ifFalse: [ ^ self return ].
+    self peek == $a ifFalse: [ ^ self returnDistinct ].
 
     [ 
-        self recordMatch: #AAstarA priority: -1.
+        self recordDistinctMatch: #AAstarA.
 
         self step.
-        self peek == $a ifFalse: [ ^ self returnPriority: -1 ].
+        self peek == $a ifFalse: [ ^ self returnDistinct ].
+        self recordDistinctMatch: nil.
+
         self step.
-        
         self peek == $a	
     ] whileTrue.
     
-    ^ self returnPriority: 0
-!
-
-nextTokenAB
-    "ab"
-    self step.
-    self peek == $a ifFalse: [ ^ self return ].
-    
-    self step.
-    self peek == $b ifFalse: [ ^ self return ].
-    self recordMatch: #b.
-    
-    ^ self return.
+    ^ self returnDistinct
 !
 
 nextTokenABorBC
     "a"
+    self resetDistinct.
+    
     self step.
     (self peek == $a) ifTrue: [ 
 
         self step.
-        self peek == $b ifFalse: [ ^ self return ].
-        self recordMatch: #ab.
+        self peek == $b ifFalse: [ ^ self returnDistinct ].
+        self recordDistinctMatch: #ab.
 
-        ^ self return	
+        ^ self returnDistinct
     ].
 
     (self peek == $b) ifTrue: [ 
         self step.
-        self peek == $c ifFalse: [ ^ self return ].
-        self recordMatch: #bc.	
+        self peek == $c ifFalse: [ ^ self returnDistinct ].
+        self recordDistinctMatch: #bc.	
 
-        ^ self return
+        ^ self returnDistinct
     ].
 
-    ^ self return
+    ^ self returnDistinct
 !
 
 nextTokenABstarA
     "(ab)*a"
+    self resetDistinct.
+    
     self step.
-    self peek == $a ifFalse: [ ^ self return ].
+    self peek == $a ifFalse: [ ^ self returnDistinct ].
 
     [ 
-        self recordMatch: #ABstarA priority: -1.
+        self recordDistinctMatch: #ABstarA.
         
         self step.
-        self peek == $b ifFalse: [ ^ self returnPriority: -1 ].
+        self peek == $b ifFalse: [ ^ self returnDistinct ].
+        self recordDistinctMatch: nil.
     
         self step.
         self peek == $a.
     ] whileTrue.
 
-    ^ self returnPriority: 0
+    ^ self returnDistinct
 !
 
 nextTokenA_Bstar_A
     "ab"
+    self resetDistinct.
+    
     self step.
-    self peek == $a ifFalse: [ ^ self return ].
+    self peek == $a ifFalse: [ ^ self returnDistinct ].
 
     [
         self step.
@@ -136,40 +151,44 @@
     ] whileTrue.
 
 
-    self peek == $a ifFalse: [ ^ self return ].
-    self recordMatch: #A_Bstar_A.
+    self peek == $a ifFalse: [ ^ self returnDistinct ].
+    self recordDistinctMatch: #A_Bstar_A.
 
-    ^ self return.
+    ^ self returnDistinct.
 !
 
 nextTokenAorAA
     "aa / a"
+    self resetDistinct.
+    
     self step.
     (self peek == $a) ifTrue: [ 
-        self recordMatch: #a priority: 0.	
-        ^ self return
+        self recordDistinctMatch: #a.	
+        ^ self returnDistinct
     ].
 
     self step.
     (self peek == $a) ifTrue: [ 
-        self recordMatch: #aa priority: -1.	
-        ^ self return
+        self recordDistinctMatch: #aa.	
+        ^ self returnDistinct
     ].
 !
 
 nextTokenAorB
     "a"
+    self resetDistinct.
+    
     self step.
     (self peek == $a) ifTrue: [ 
-        self recordMatch: #a.	
-        ^ self return
+        self recordDistinctMatch: #a.	
+        ^ self returnDistinct
     ].
     (self peek == $b) ifTrue: [ 
-        self recordMatch: #b.	
-        ^ self return
+        self recordDistinctMatch: #b.	
+        ^ self returnDistinct
     ].
 
-    ^ self return
+    ^ self returnDistinct
 !
 
 nextTokenAstarA
@@ -179,32 +198,71 @@
         self peek == $a.
     ] whileTrue.
 
-    self peek == $a ifFalse: [ ^ self return ].
-    self recordMatch: #AstarA.
-    ^ self return
+    self peek == $a ifFalse: [ ^ self returnDistinct ].
+    self recordDistinctMatch: #AstarA.
+    ^ self returnDistinct
 !
 
 nextTokenAstarB
     "a*b"
+    self resetDistinct.
+    
     [ 
         self step.
         self peek == $a.
     ] whileTrue.
 
-    self peek == $b ifFalse: [ ^ self return ].
-    self recordMatch: #AstarB.
-    ^ self return
+    self peek == $b ifFalse: [ ^ self returnDistinct ].
+    self recordDistinctMatch: #AstarB.
+    ^ self returnDistinct
+! !
+
+!FooScanner methodsFor:'initialization'!
+
+initialize
+    super initialize.
+! !
+
+!FooScanner methodsFor:'mutlivalue'!
+
+nextMultiTokenA
+    "a|a"
+    self reset.
+    
+    self step.
+    self peek == $a ifFalse: [ ^ self ].
+    
+    self recordMatch: 1. "A1 in matches"
+    self recordMatch: 2. "A2 in matches"
+!
+
+nextTokenAB
+    "ab"
+    self reset.
+    
+    self step.
+    self peek == $a ifFalse: [ ^ self ].
+    
+    self step.
+    self peek == $b ifFalse: [ ^ self ].
+    self recordMatch: 3. "ID of #B"
+    
+    ^ self
 !
 
 nextTokenAuorA
     "a | a"
+    self reset.
+    
     self step.
     (self peek == $a) ifTrue: [ 
-        self recordMatch: #a1.	
-        self recordMatch: #a2.
-        ^ self return	
+        self recordMatch: 1.	
+        self recordMatch: 2.
+        ^ self
     ].
 
-    ^ self return	
+    ^ self
 ! !
 
+
+FooScanner initialize!
--- a/compiler/Make.proto	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/Make.proto	Mon Aug 17 12:56:02 2015 +0100
@@ -131,10 +131,14 @@
 
 # BEGINMAKEDEPEND --- do not remove this line; make depend needs it
 $(OUTDIR)PEGFsa.$(O) PEGFsa.$(H): PEGFsa.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaAbstractDeterminizator.$(O) PEGFsaAbstractDeterminizator.$(H): PEGFsaAbstractDeterminizator.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaFailure.$(O) PEGFsaFailure.$(H): PEGFsaFailure.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaInterpret.$(O) PEGFsaInterpret.$(H): PEGFsaInterpret.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaInterpretRecord.$(O) PEGFsaInterpretRecord.$(H): PEGFsaInterpretRecord.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaMinimizator.$(O) PEGFsaMinimizator.$(H): PEGFsaMinimizator.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaPair.$(O) PEGFsaPair.$(H): PEGFsaPair.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaState.$(O) PEGFsaState.$(H): PEGFsaState.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaStateInfo.$(O) PEGFsaStateInfo.$(H): PEGFsaStateInfo.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaTransition.$(O) PEGFsaTransition.$(H): PEGFsaTransition.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCASTUtilities.$(O) PPCASTUtilities.$(H): PPCASTUtilities.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCArguments.$(O) PPCArguments.$(H): PPCArguments.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
@@ -154,24 +158,34 @@
 $(OUTDIR)PPCContext.$(O) PPCContext.$(H): PPCContext.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPStream.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/PeekableStream.$(H) $(INCLUDE_TOP)/stx/libbasic/PositionableStream.$(H) $(INCLUDE_TOP)/stx/libbasic/ReadStream.$(H) $(INCLUDE_TOP)/stx/libbasic/Stream.$(H) $(STCHDR)
 $(OUTDIR)PPCContextMemento.$(O) PPCContextMemento.$(H): PPCContextMemento.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCGuard.$(O) PPCGuard.$(H): PPCGuard.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPCIdGenerator.$(O) PPCIdGenerator.$(H): PPCIdGenerator.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCMethod.$(O) PPCMethod.$(H): PPCMethod.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCNode.$(O) PPCNode.$(H): PPCNode.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCNodeVisitor.$(O) PPCNodeVisitor.$(H): PPCNodeVisitor.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCPluggableConfiguration.$(O) PPCPluggableConfiguration.$(H): PPCPluggableConfiguration.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCScanner.$(O) PPCScanner.$(H): PPCScanner.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCScannerCodeGenerator.$(O) PPCScannerCodeGenerator.$(H): PPCScannerCodeGenerator.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPCScannerResultStrategy.$(O) PPCScannerResultStrategy.$(H): PPCScannerResultStrategy.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenGuard.$(O) PPCTokenGuard.$(H): PPCTokenGuard.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCompiledParser.$(O) PPCompiledParser.$(H): PPCompiledParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPMappedActionParser.$(O) PPMappedActionParser.$(H): PPMappedActionParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPActionParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPDelegateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)stx_goodies_petitparser_compiler.$(O) stx_goodies_petitparser_compiler.$(H): stx_goodies_petitparser_compiler.st $(INCLUDE_TOP)/stx/libbasic/LibraryDefinition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProjectDefinition.$(H) $(STCHDR)
 $(OUTDIR)FooScanner.$(O) FooScanner.$(H): FooScanner.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCScanner.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaCharacterTransition.$(O) PEGFsaCharacterTransition.$(H): PEGFsaCharacterTransition.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PEGFsaTransition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaChoiceDeterminizator.$(O) PEGFsaChoiceDeterminizator.$(H): PEGFsaChoiceDeterminizator.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PEGFsaAbstractDeterminizator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaDeterminizator.$(O) PEGFsaDeterminizator.$(H): PEGFsaDeterminizator.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PEGFsaAbstractDeterminizator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaEpsilonTransition.$(O) PEGFsaEpsilonTransition.$(H): PEGFsaEpsilonTransition.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PEGFsaTransition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaGenerator.$(O) PEGFsaGenerator.$(H): PEGFsaGenerator.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNodeVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaPredicateTransition.$(O) PEGFsaPredicateTransition.$(H): PEGFsaPredicateTransition.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PEGFsaTransition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaSequenceDeterminizator.$(O) PEGFsaSequenceDeterminizator.$(H): PEGFsaSequenceDeterminizator.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PEGFsaAbstractDeterminizator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaUncopiableState.$(O) PEGFsaUncopiableState.$(H): PEGFsaUncopiableState.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PEGFsaState.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCAbstractLiteralNode.$(O) PPCAbstractLiteralNode.$(H): PPCAbstractLiteralNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCAbstractPredicateNode.$(O) PPCAbstractPredicateNode.$(H): PPCAbstractPredicateNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCAnyNode.$(O) PPCAnyNode.$(H): PPCAnyNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCCharacterNode.$(O) PPCCharacterNode.$(H): PPCCharacterNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCCodeGenerator.$(O) PPCCodeGenerator.$(H): PPCCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNodeVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCDelegateNode.$(O) PPCDelegateNode.$(H): PPCDelegateNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPCDistinctResultStrategy.$(O) PPCDistinctResultStrategy.$(H): PPCDistinctResultStrategy.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCScannerResultStrategy.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCEndOfFileNode.$(O) PPCEndOfFileNode.$(H): PPCEndOfFileNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCFSACodeGen.$(O) PPCFSACodeGen.$(H): PPCFSACodeGen.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCCodeGen.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCInlinedMethod.$(O) PPCInlinedMethod.$(H): PPCInlinedMethod.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCMethod.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
@@ -181,11 +195,15 @@
 $(OUTDIR)PPCPluggableNode.$(O) PPCPluggableNode.$(H): PPCPluggableNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCProfilingContext.$(O) PPCProfilingContext.$(H): PPCProfilingContext.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPStream.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCContext.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/PeekableStream.$(H) $(INCLUDE_TOP)/stx/libbasic/PositionableStream.$(H) $(INCLUDE_TOP)/stx/libbasic/ReadStream.$(H) $(INCLUDE_TOP)/stx/libbasic/Stream.$(H) $(STCHDR)
 $(OUTDIR)PPCRewritingVisitor.$(O) PPCRewritingVisitor.$(H): PPCRewritingVisitor.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNodeVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPCTokenCodeGenerator.$(O) PPCTokenCodeGenerator.$(H): PPCTokenCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNodeVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPCTokenizingCodeGen.$(O) PPCTokenizingCodeGen.$(H): PPCTokenizingCodeGen.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCCodeGen.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenizingCompiler.$(O) PPCTokenizingCompiler.$(H): PPCTokenizingCompiler.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCCompiler.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenizingConfiguration.$(O) PPCTokenizingConfiguration.$(H): PPCTokenizingConfiguration.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCConfiguration.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCUniversalConfiguration.$(O) PPCUniversalConfiguration.$(H): PPCUniversalConfiguration.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCConfiguration.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPCUniversalResultStrategy.$(O) PPCUniversalResultStrategy.$(H): PPCUniversalResultStrategy.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCScannerResultStrategy.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCUnknownNode.$(O) PPCUnknownNode.$(H): PPCUnknownNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPTokenizingCompiledParser.$(O) PPTokenizingCompiledParser.$(H): PPTokenizingCompiledParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCompiledParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaEOFTransition.$(O) PEGFsaEOFTransition.$(H): PEGFsaEOFTransition.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PEGFsaPredicateTransition.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PEGFsaTransition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCAbstractActionNode.$(O) PPCAbstractActionNode.$(H): PPCAbstractActionNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCDelegateNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCAndNode.$(O) PPCAndNode.$(H): PPCAndNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCDelegateNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCCharSetPredicateNode.$(O) PPCCharSetPredicateNode.$(H): PPCCharSetPredicateNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCAbstractPredicateNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
@@ -213,7 +231,6 @@
 $(OUTDIR)PPCSequenceNode.$(O) PPCSequenceNode.$(H): PPCSequenceNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCListNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCSpecializingVisitor.$(O) PPCSpecializingVisitor.$(H): PPCSpecializingVisitor.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNodeVisitor.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCRewritingVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCStarNode.$(O) PPCStarNode.$(H): PPCStarNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCDelegateNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
-$(OUTDIR)PPCTokenCodeGenerator.$(O) PPCTokenCodeGenerator.$(H): PPCTokenCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNodeVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenConsumeNode.$(O) PPCTokenConsumeNode.$(H): PPCTokenConsumeNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCDelegateNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenDetector.$(O) PPCTokenDetector.$(H): PPCTokenDetector.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNodeVisitor.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCRewritingVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenNode.$(O) PPCTokenNode.$(H): PPCTokenNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCDelegateNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
@@ -236,7 +253,7 @@
 $(OUTDIR)PPCMappedActionNode.$(O) PPCMappedActionNode.$(H): PPCMappedActionNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCAbstractActionNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCActionNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCDelegateNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenStarMessagePredicateNode.$(O) PPCTokenStarMessagePredicateNode.$(H): PPCTokenStarMessagePredicateNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCDelegateNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCStarMessagePredicateNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCStarNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenStarSeparatorNode.$(O) PPCTokenStarSeparatorNode.$(H): PPCTokenStarSeparatorNode.st $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCDelegateNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCStarMessagePredicateNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCStarNode.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/compiler/PPCTokenStarMessagePredicateNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
-$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPActionParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPAndParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPCharSetPredicate.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPChoiceParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPCompositeParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPContext.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPDelegateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPEndOfInputParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPEpsilonParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPFailure.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPFlattenParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPListParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPLiteralObjectParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPLiteralParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPLiteralSequenceParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPNotParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPOptionalParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPPluggableParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPPossessiveRepeatingParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPPredicateObjectParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPPredicateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPRepeatingParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPSequenceParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPStream.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPToken.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPTokenParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPTrimmingParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/parsers/java/PPJavaWhitespaceParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/parsers/smalltalk/PPSmalltalkGrammar.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/parsers/smalltalk/PPSmalltalkTokenParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/parsers/smalltalk/PPSmalltalkWhitespaceParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Character.$(H) $(INCLUDE_TOP)/stx/libbasic/Magnitude.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/PeekableStream.$(H) $(INCLUDE_TOP)/stx/libbasic/PositionableStream.$(H) $(INCLUDE_TOP)/stx/libbasic/ReadStream.$(H) $(INCLUDE_TOP)/stx/libbasic/Stream.$(H) $(INCLUDE_TOP)/stx/libbasic/UndefinedObject.$(H) $(STCHDR)
+$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPActionParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPAndParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPCharSetPredicate.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPChoiceParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPCompositeParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPContext.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPDelegateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPEndOfFileParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPEndOfInputParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPEpsilonParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPFailure.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPFlattenParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPListParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPLiteralObjectParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPLiteralParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPLiteralSequenceParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPNotParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPOptionalParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPPluggableParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPPossessiveRepeatingParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPPredicateObjectParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPPredicateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPRepeatingParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPSequenceParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPStream.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPToken.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPTokenParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPTrimmingParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/parsers/java/PPJavaWhitespaceParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/parsers/smalltalk/PPSmalltalkGrammar.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/parsers/smalltalk/PPSmalltalkTokenParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/parsers/smalltalk/PPSmalltalkWhitespaceParser.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBLiteralNode.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBLiteralValueNode.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBProgramNode.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBStatementNode.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBValueNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Character.$(H) $(INCLUDE_TOP)/stx/libbasic/Magnitude.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/PeekableStream.$(H) $(INCLUDE_TOP)/stx/libbasic/PositionableStream.$(H) $(INCLUDE_TOP)/stx/libbasic/ReadStream.$(H) $(INCLUDE_TOP)/stx/libbasic/Stream.$(H) $(INCLUDE_TOP)/stx/libbasic/UndefinedObject.$(H) $(STCHDR)
 
 # ENDMAKEDEPEND --- do not remove this line
 
--- a/compiler/Make.spec	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/Make.spec	Mon Aug 17 12:56:02 2015 +0100
@@ -52,10 +52,14 @@
 
 COMMON_CLASSES= \
 	PEGFsa \
+	PEGFsaAbstractDeterminizator \
 	PEGFsaFailure \
 	PEGFsaInterpret \
+	PEGFsaInterpretRecord \
+	PEGFsaMinimizator \
 	PEGFsaPair \
 	PEGFsaState \
+	PEGFsaStateInfo \
 	PEGFsaTransition \
 	PPCASTUtilities \
 	PPCArguments \
@@ -75,24 +79,34 @@
 	PPCContext \
 	PPCContextMemento \
 	PPCGuard \
+	PPCIdGenerator \
 	PPCMethod \
 	PPCNode \
 	PPCNodeVisitor \
 	PPCPluggableConfiguration \
 	PPCScanner \
 	PPCScannerCodeGenerator \
+	PPCScannerResultStrategy \
 	PPCTokenGuard \
 	PPCompiledParser \
 	PPMappedActionParser \
 	stx_goodies_petitparser_compiler \
 	FooScanner \
+	PEGFsaCharacterTransition \
+	PEGFsaChoiceDeterminizator \
+	PEGFsaDeterminizator \
+	PEGFsaEpsilonTransition \
 	PEGFsaGenerator \
+	PEGFsaPredicateTransition \
+	PEGFsaSequenceDeterminizator \
+	PEGFsaUncopiableState \
 	PPCAbstractLiteralNode \
 	PPCAbstractPredicateNode \
 	PPCAnyNode \
 	PPCCharacterNode \
 	PPCCodeGenerator \
 	PPCDelegateNode \
+	PPCDistinctResultStrategy \
 	PPCEndOfFileNode \
 	PPCFSACodeGen \
 	PPCInlinedMethod \
@@ -102,11 +116,15 @@
 	PPCPluggableNode \
 	PPCProfilingContext \
 	PPCRewritingVisitor \
+	PPCTokenCodeGenerator \
+	PPCTokenizingCodeGen \
 	PPCTokenizingCompiler \
 	PPCTokenizingConfiguration \
 	PPCUniversalConfiguration \
+	PPCUniversalResultStrategy \
 	PPCUnknownNode \
 	PPTokenizingCompiledParser \
+	PEGFsaEOFTransition \
 	PPCAbstractActionNode \
 	PPCAndNode \
 	PPCCharSetPredicateNode \
@@ -134,7 +152,6 @@
 	PPCSequenceNode \
 	PPCSpecializingVisitor \
 	PPCStarNode \
-	PPCTokenCodeGenerator \
 	PPCTokenConsumeNode \
 	PPCTokenDetector \
 	PPCTokenNode \
@@ -163,10 +180,14 @@
 
 COMMON_OBJS= \
     $(OUTDIR_SLASH)PEGFsa.$(O) \
+    $(OUTDIR_SLASH)PEGFsaAbstractDeterminizator.$(O) \
     $(OUTDIR_SLASH)PEGFsaFailure.$(O) \
     $(OUTDIR_SLASH)PEGFsaInterpret.$(O) \
+    $(OUTDIR_SLASH)PEGFsaInterpretRecord.$(O) \
+    $(OUTDIR_SLASH)PEGFsaMinimizator.$(O) \
     $(OUTDIR_SLASH)PEGFsaPair.$(O) \
     $(OUTDIR_SLASH)PEGFsaState.$(O) \
+    $(OUTDIR_SLASH)PEGFsaStateInfo.$(O) \
     $(OUTDIR_SLASH)PEGFsaTransition.$(O) \
     $(OUTDIR_SLASH)PPCASTUtilities.$(O) \
     $(OUTDIR_SLASH)PPCArguments.$(O) \
@@ -186,24 +207,34 @@
     $(OUTDIR_SLASH)PPCContext.$(O) \
     $(OUTDIR_SLASH)PPCContextMemento.$(O) \
     $(OUTDIR_SLASH)PPCGuard.$(O) \
+    $(OUTDIR_SLASH)PPCIdGenerator.$(O) \
     $(OUTDIR_SLASH)PPCMethod.$(O) \
     $(OUTDIR_SLASH)PPCNode.$(O) \
     $(OUTDIR_SLASH)PPCNodeVisitor.$(O) \
     $(OUTDIR_SLASH)PPCPluggableConfiguration.$(O) \
     $(OUTDIR_SLASH)PPCScanner.$(O) \
     $(OUTDIR_SLASH)PPCScannerCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)PPCScannerResultStrategy.$(O) \
     $(OUTDIR_SLASH)PPCTokenGuard.$(O) \
     $(OUTDIR_SLASH)PPCompiledParser.$(O) \
     $(OUTDIR_SLASH)PPMappedActionParser.$(O) \
     $(OUTDIR_SLASH)stx_goodies_petitparser_compiler.$(O) \
     $(OUTDIR_SLASH)FooScanner.$(O) \
+    $(OUTDIR_SLASH)PEGFsaCharacterTransition.$(O) \
+    $(OUTDIR_SLASH)PEGFsaChoiceDeterminizator.$(O) \
+    $(OUTDIR_SLASH)PEGFsaDeterminizator.$(O) \
+    $(OUTDIR_SLASH)PEGFsaEpsilonTransition.$(O) \
     $(OUTDIR_SLASH)PEGFsaGenerator.$(O) \
+    $(OUTDIR_SLASH)PEGFsaPredicateTransition.$(O) \
+    $(OUTDIR_SLASH)PEGFsaSequenceDeterminizator.$(O) \
+    $(OUTDIR_SLASH)PEGFsaUncopiableState.$(O) \
     $(OUTDIR_SLASH)PPCAbstractLiteralNode.$(O) \
     $(OUTDIR_SLASH)PPCAbstractPredicateNode.$(O) \
     $(OUTDIR_SLASH)PPCAnyNode.$(O) \
     $(OUTDIR_SLASH)PPCCharacterNode.$(O) \
     $(OUTDIR_SLASH)PPCCodeGenerator.$(O) \
     $(OUTDIR_SLASH)PPCDelegateNode.$(O) \
+    $(OUTDIR_SLASH)PPCDistinctResultStrategy.$(O) \
     $(OUTDIR_SLASH)PPCEndOfFileNode.$(O) \
     $(OUTDIR_SLASH)PPCFSACodeGen.$(O) \
     $(OUTDIR_SLASH)PPCInlinedMethod.$(O) \
@@ -213,11 +244,15 @@
     $(OUTDIR_SLASH)PPCPluggableNode.$(O) \
     $(OUTDIR_SLASH)PPCProfilingContext.$(O) \
     $(OUTDIR_SLASH)PPCRewritingVisitor.$(O) \
+    $(OUTDIR_SLASH)PPCTokenCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)PPCTokenizingCodeGen.$(O) \
     $(OUTDIR_SLASH)PPCTokenizingCompiler.$(O) \
     $(OUTDIR_SLASH)PPCTokenizingConfiguration.$(O) \
     $(OUTDIR_SLASH)PPCUniversalConfiguration.$(O) \
+    $(OUTDIR_SLASH)PPCUniversalResultStrategy.$(O) \
     $(OUTDIR_SLASH)PPCUnknownNode.$(O) \
     $(OUTDIR_SLASH)PPTokenizingCompiledParser.$(O) \
+    $(OUTDIR_SLASH)PEGFsaEOFTransition.$(O) \
     $(OUTDIR_SLASH)PPCAbstractActionNode.$(O) \
     $(OUTDIR_SLASH)PPCAndNode.$(O) \
     $(OUTDIR_SLASH)PPCCharSetPredicateNode.$(O) \
@@ -245,7 +280,6 @@
     $(OUTDIR_SLASH)PPCSequenceNode.$(O) \
     $(OUTDIR_SLASH)PPCSpecializingVisitor.$(O) \
     $(OUTDIR_SLASH)PPCStarNode.$(O) \
-    $(OUTDIR_SLASH)PPCTokenCodeGenerator.$(O) \
     $(OUTDIR_SLASH)PPCTokenConsumeNode.$(O) \
     $(OUTDIR_SLASH)PPCTokenDetector.$(O) \
     $(OUTDIR_SLASH)PPCTokenNode.$(O) \
--- a/compiler/PEGFsa.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PEGFsa.st	Mon Aug 17 12:56:02 2015 +0100
@@ -35,8 +35,15 @@
 !
 
 minPriority
-    "this is the worst estimate"
-    ^ (self states size) negated
+    | priority |
+"	defaultPriority := self states size negated.
+    self finalStates isEmpty ifTrue: [ ^ defaultPriority ].
+    
+    ^ (self finalStates collect: [ :e | e priorityIfNone: defaultPriority  ]) min
+"
+    priority := -1.
+    self allTransitions do: [ :t | t isEpsilon ifTrue: [ priority := priority + t priority ] ].
+    ^ priority
 !
 
 name
@@ -48,11 +55,12 @@
     name := anObject
 !
 
-prefix
-    ^ 'fsa_'
+retvals
+    ^ (self finalStates flatCollect: [ :e | e retvals collect: #value ]) asIdentitySet
 !
 
 startState
+    self assert: (states includes: startState).
     ^ startState
 !
 
@@ -64,8 +72,8 @@
     ^ states
 !
 
-suffix
-    ^ ''
+states: whatever
+    states := whatever
 !
 
 transitionFrom: from to: to
@@ -172,7 +180,27 @@
 !
 
 finalStates
-    ^ self reachableStates select: [ :s | s isFinal ]
+    ^ self states select: [ :s | s isFinal ]
+!
+
+hasDistinctRetvals
+    | finalStates retvals |
+    finalStates := self finalStates.
+
+    (finalStates anySatisfy: [ :s | s isMultivalue  ]) ifTrue: [ ^ false ].
+    retvals := finalStates collect: [:s | s retval].
+
+        
+    (finalStates size == 1) ifTrue: [ ^ true ].
+
+
+    (retvals asSet size == 1) ifTrue: [ ^ true ].
+    "final states leads only to final states with the same retval"
+    (finalStates allSatisfy: [ :s | 
+        (self statesReachableFrom: s) allSatisfy: [ :rs | rs retval value isNil or: [ rs retval value == s retval value ] ]
+    ]) ifTrue: [ ^ true ].
+    
+    ^ false
 !
 
 is: state furtherThan: anotherState
@@ -184,6 +212,14 @@
     ^ self backTransitions includes: t
 !
 
+isWithoutPriorities
+    ^ self states allSatisfy: [ :s | 
+        s hasPriority not or: [ 
+            s stateInfos allSatisfy: [ :i | i priority == 0 ]
+        ] 
+    ].
+!
+
 joinPoints
     ^ self joinTransitions collect: [ :t | t destination ]
 !
@@ -222,7 +258,7 @@
 statePairs
     |  pairs ordered |
     pairs := OrderedCollection new.
-    ordered := self topologicalOrder.
+    ordered := self states asOrderedCollection.
     1 to: (ordered size - 1) do: [ :index1 |
         (index1 + 1) to: ordered size do: [ :index2 |
             pairs add: (PEGFsaPair with: (ordered at: index1) with: (ordered at: index2))
@@ -266,7 +302,7 @@
 
 = anotherFsa
     "
-        Please note what the compare does. IMO nothing useful for no.
+        Please note what the compare does. IMO nothing useful for now.
         
         For comparing if two FSA's are equivalent, use isIsomorphicTo:
     "
@@ -336,7 +372,7 @@
 !PEGFsa methodsFor:'gt'!
 
 gtGraphViewIn: composite
-    <gtInspectorPresentationOrder: 41>
+    <gtInspectorPresentationOrder: 0>
     composite roassal2
         title: 'Graph'; 
         initializeView: [ RTMondrian new ];
@@ -386,6 +422,24 @@
     ^ b
 ! !
 
+!PEGFsa methodsFor:'ids'!
+
+defaultName
+    ^ #fsa
+!
+
+hasName
+    ^ name isNil not
+!
+
+prefix
+    ^ nil
+!
+
+suffix
+    ^ nil
+! !
+
 !PEGFsa methodsFor:'initialization'!
 
 initialize
@@ -400,7 +454,16 @@
 !
 
 addTransitionFrom: fromState to: toState 
-    ^ self addTransitionFrom: fromState to: toState priority: 0 
+    | transition |
+    self assert: (states includes: fromState).
+    self assert: (states includes: toState).
+    
+    transition := PEGFsaEpsilonTransition new 
+        destination: toState;
+        priority: 0;
+        yourself.
+        
+    fromState addTransition: transition.
 !
 
 addTransitionFrom: fromState to: toState on: character
@@ -409,7 +472,7 @@
 
 addTransitionFrom: fromState to: toState on: character priority: priority
     | transition |
-    transition := PEGFsaTransition new 
+    transition := PEGFsaCharacterTransition new 
         addCharacter: character;
         destination: toState;
         priority: priority;
@@ -424,7 +487,7 @@
 
 addTransitionFrom: fromState to: toState onCharacterSet: characterSet priority: priority
     | transition |
-    transition := PEGFsaTransition new 
+    transition := PEGFsaCharacterTransition new 
         characterSet: characterSet;
         destination: toState;
         priority: priority;
@@ -433,12 +496,29 @@
     fromState addTransition: transition
 !
 
+addTransitionFrom: fromState to: toState onPredicate: block
+    self addTransitionFrom: fromState to: toState onPredicate: block priority: 0
+!
+
+addTransitionFrom: fromState to: toState onPredicate: block priority: priority
+    | transition |
+    transition := PEGFsaPredicateTransition new 
+        predicate: block;
+        destination: toState;
+        priority: priority;
+        yourself.
+        
+    fromState addTransition: transition
+!
+
 addTransitionFrom: fromState to: toState priority: priority
     | transition |
+    "should not use minus priority epsilons any more"
+    self assert: (priority == 0).	
     self assert: (states includes: fromState).
     self assert: (states includes: toState).
     
-    transition := PEGFsaTransition new 
+    transition := PEGFsaEpsilonTransition new 
         destination: toState;
         priority: priority;
         yourself.
@@ -450,9 +530,24 @@
     states addAll: fsa reachableStates.
 !
 
+decreasePriority
+    ^ self decreasePriorityBy: 1
+!
+
+decreasePriorityBy: value
+    self states select: [ :s | s hasPriority ] thenDo: [ :s |
+        s decreasePriorityBy: value.
+    ].
+
+    self allTransitions do: [ :t |
+        t decreasePriorityBy: value
+    ]
+!
+
 finalState: state
     self assert: state isFinal not.
     state final: true.
+    state priority: 0.
 !
 
 fixFinalStatePriorities
@@ -461,6 +556,20 @@
     ]
 !
 
+minimize
+    ^ PEGFsaMinimizator new minimize: self
+!
+
+removePriorities
+    self states select: [ :s| s hasPriority ] thenDo: [ :s |
+        s priority: 0
+    ].
+
+    self allTransitions do: [ :t |
+        t priority: 0
+    ]
+!
+
 removeState: state
     self assert: (states includes: state).
     states remove: state.
@@ -468,8 +577,8 @@
 
 replace: state with: anotherState
     | transitions  |
-    self assert: (state class == PEGFsaState).
-    self assert: (anotherState class == PEGFsaState).
+    self assert: (state isKindOf: PEGFsaState).
+    self assert: (anotherState isKindOf: PEGFsaState).
     
     transitions := self allTransitions.
 
@@ -478,7 +587,17 @@
             t destination: anotherState.
         ]
     ].
-    states := startState reachableStates.	
+
+    state == startState ifTrue: [ startState := anotherState ].
+    states remove: state.
+    states add: anotherState.
+!
+
+retval: returnValue
+    self finalStates do: [ :s |
+        self assert: s retval isNil.
+        s retval: returnValue
+    ]
 !
 
 startState: state
@@ -487,6 +606,142 @@
     startState := state
 ! !
 
+!PEGFsa methodsFor:'modifications - determinization'!
+
+determinize
+    ^ PEGFsaSequenceDeterminizator new determinize: self.
+!
+
+determinize: joinDictionary
+    self error: 'deprecated'.
+    
+    self removeEpsilons.
+    self removeUnreachableStates.
+    self removeLowPriorityTransitions.
+    self mergeTransitions.
+    
+    
+    states := self topologicalOrder asOrderedCollection.
+    
+    states do: [ :state |
+        state determinize: joinDictionary.
+    ].
+    
+    states	 := startState reachableStates.
+
+    self removeUnreachableStates.
+    self removeLowPriorityTransitions.
+    self mergeTransitions.
+    
+!
+
+determinizeChoice
+    ^ PEGFsaChoiceDeterminizator new determinize: self.
+!
+
+determinizeStandard
+    ^ PEGFsaDeterminizator new determinize: self.
+! !
+
+!PEGFsa methodsFor:'modifications - epsilons'!
+
+removeEpsilonTransition: transition source: state
+    ^ self removeEpsilonTransition: transition source: state openSet: IdentitySet new
+!
+
+removeEpsilonTransition: transition source: source openSet: openSet
+    | destination |
+    (openSet includes: transition) ifTrue: [ self error: 'loop in epsilons?!!' ].
+    openSet add: transition.
+    
+    destination := transition destination.
+    
+    "First Remove Recursively"
+    ((self transitionsFor: destination ) select: [ :t | t isEpsilon  ]) do: [ :t |
+        self removeEpsilonTransition: t source: destination openSet: openSet
+    ].
+
+    self assert: transition isEpsilon.
+    self assert: transition priority = 0.
+    
+    (destination transitions) do: [ :t |
+        source addTransition: (t copy)
+    ].
+
+    source mergeInfo: destination into: source.
+
+    destination isFinal ifTrue: [ 
+        source final: true.
+        source retval: destination retval.
+    ].
+
+    source removeTransition: transition.
+!
+
+removeEpsilons
+    "First, remove the negative values from epsilons"
+    self removeNegativeEpsilons.
+    
+    states do: [ :state |
+        self removeEpsilonsFor: state
+    ]
+!
+
+removeEpsilonsFor: state
+    (self transitionsFor: state) copy do: [ :t |
+        (t isEpsilon and: [ t destination isStub not ]) ifTrue: [ 
+            self removeEpsilonTransition: t source: state
+        ]
+    ]
+!
+
+removeNegativeEpsilonTransition: transition source: state
+    ^ self removeNegativeEpsilonTransition: transition source: state openSet: IdentitySet new
+!
+
+removeNegativeEpsilonTransition: transition source: source openSet: openSet
+    | destination |
+    (openSet includes: transition) ifTrue: [ self error: 'loop in epsilons?!!' ].
+    openSet add: transition.
+    
+    destination := transition destination.
+    
+    "First Remove Recursively"
+    ((self transitionsFor: destination ) select: [ :t | t isEpsilon  ]) do: [ :t |
+        self removeNegativeEpsilonTransition: t source: destination openSet: openSet
+    ].
+    
+    "JK: Problem alert: if two different epsilons point to the same state,
+        it will decreas the state priority two times!! I don't know how to handle
+        this situation properly and I make sure during FSA generation that there
+        are no two paths to one state (except for loops).
+    "
+    (self statesReachableFrom: destination) do: [ :s |
+        s decreasePriorityBy: transition priority abs.
+        s transitions do: [ :t | t decreasePriorityBy: transition priority abs  ]
+    ].
+
+    transition priority: 0.
+!
+
+removeNegativeEpsilons
+    "
+        This will remove only negative values from epsilons, the epsilons itself will not
+        be removed!!
+    "
+    states do: [ :state |
+        self removeNegativeEpsilonsFor: state
+    ]
+!
+
+removeNegativeEpsilonsFor: state
+    (self transitionsFor: state) copy do: [ :t |
+        t isEpsilon ifTrue: [ 
+            self removeNegativeEpsilonTransition: t source: state
+        ]
+    ]
+! !
+
 !PEGFsa methodsFor:'printing'!
 
 asString
@@ -533,6 +788,7 @@
 checkSanity
     self checkConsistency.
     self checkTransitionsIdentity.
+    self checkTransitionsPriority.
     self checkFinalStatesPriorities.
 !
 
@@ -546,6 +802,14 @@
     self assert: bag size == set size.
 !
 
+checkTransitionsPriority
+    self finalStates do: [ :fs |
+        fs isMultivalue ifFalse: [ 
+            fs transitions allSatisfy: [ :t | fs priority >= t priority ]
+        ]
+    ]
+!
+
 isDeterministic
     self reachableStates do: [ :state |
         state transitionPairs do: [ :pair | 
@@ -577,115 +841,13 @@
 !PEGFsa methodsFor:'transformations'!
 
 compact
-    self fixFinalStatePriorities.
-    self determinize.
-    self minimize.
-    
-    self checkSanity.
-!
-
-determinize
-    | joinDictionary |
-    self removeEpsilons.
-
-    self removeUnreachableStates.
-    self removeLowPriorityTransitions.
-    self mergeTransitions.
-    
-    joinDictionary := Dictionary new.
-    self topologicalOrder do: [:state | state determinize: joinDictionary ].
-    
-    states	 := startState reachableStates.
-
-    self removeUnreachableStates.
-    self removeLowPriorityTransitions.
-    self mergeTransitions.
-    
+    self error: 'deprecated?'
 !
 
 mergeTransitions
-    | toRemove |
+    |  |
     self reachableStates do: [ :state |
-        toRemove := OrderedCollection new.
-        state transitionPairs do:[ :pair | 
-            (pair first destination = pair second destination) ifTrue: [ 
-                pair first mergeWith: pair second.
-                toRemove add: pair second.
-            ]
-        ].
-        toRemove do: [ :t |
-            state removeTransition: t
-        ]
-    ]
-!
-
-minimize
-    | pair |
-    pair := self statePairs detect:  [ :p | p first equals: p second ] ifNone: [ nil ].
-    [ pair isNil not ] whileTrue: [ 
-        "Join priorities, because equivalency of priorities does not imply from the equeality of states"
-        pair first joinPriority: pair second newState: pair first.
-        pair first joinName: pair second newState: pair first.
-        self replace: pair second with: pair first.
-        self mergeTransitions.
-        pair := self statePairs detect:  [ :p | p first equals: p second ] ifNone: [ nil ].
- 	].
-!
-
-removeEpsilonTransition: transition source: state
-    ^ self removeEpsilonTransition: transition source: state openSet: IdentitySet new
-!
-
-removeEpsilonTransition: transition source: source openSet: openSet
-    | destination |
-    (openSet includes: transition) ifTrue: [ self error: 'loop in epsilons?!!' ].
-    openSet add: transition.
-    
-    destination := transition destination.
-    
-    "First Remove Recursively"
-    ((self transitionsFor: destination ) select: [ :t | t isEpsilon  ]) do: [ :t |
-        self removeEpsilonTransition: t source: destination openSet: openSet
-    ].
-    
-    (transition priority abs) timesRepeat: [ 
-        (self statesReachableFrom: destination) do: [ :s |
-            s decreasePriority.
-            s transitions do: [ :t | t decreasePriority  ]
-        ]
-    ].
-
-    (destination transitions) do: [ :t |
-        source addTransition: (t copy)
-    ].
-
-    destination hasPriority ifTrue: [ 
-        source hasPriority ifTrue: [ 
-            "self assert: source priority == destination priority"
-            self flag: 'I am not 100% sure about this case'
-        ].
-        source priority: destination priority
-    ].
-
-    destination isFinal ifTrue: [ 
-        source final: true.
-        source retval: destination retval.
-    ].
-
-    source removeTransition: transition.
-!
-
-removeEpsilons
-    states do: [ :state |
-        self removeEpsilonsFor: state
-    ]
-!
-
-removeEpsilonsFor: state
-    (self transitionsFor: state) copy do: [ :t |
-        t isEpsilon ifTrue: [ 
-            self removeEpsilonTransition: t source: state
-        ]
+        state mergeTransitions.
     ]
 !
 
@@ -696,10 +858,14 @@
 !
 
 removeLowPriorityTransitionsFor: state
+    | transitions |
     state hasPriority ifFalse: [ ^ self ].
     state isFinal ifFalse: [ ^ self ].
-    
-    state transitions do: [ :t |
+    "TODO JK: I can probably cut some transitions from multivalu as well"
+    state isMultivalue ifTrue: [ ^ self ].
+
+    transitions := state transitions copy.
+    transitions do: [ :t |
         (t priority < state priority) ifTrue: [ 
             state removeTransition: t
         ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaAbstractDeterminizator.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,163 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#PEGFsaAbstractDeterminizator
+	instanceVariableNames:'fsa joinDictionary'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaAbstractDeterminizator class methodsFor:'as yet unclassified'!
+
+new
+    ^ self basicNew initialize
+! !
+
+!PEGFsaAbstractDeterminizator methodsFor:'accessing - keys'!
+
+joinKey: key with: anotherKey
+    ^ Set new
+        addAll: key;
+        addAll: anotherKey;
+        yourself.
+!
+
+keyFor: state
+    ^ joinDictionary keyAtIdentityValue: state ifAbsent: [ Set with: state ]
+!
+
+keyFor: state and: anotherState
+    | key anotherKey |
+    key := self keyFor: state.
+    anotherKey := self keyFor: anotherState.
+    
+    ^ self joinKey: key with: anotherKey
+! !
+
+!PEGFsaAbstractDeterminizator methodsFor:'determinization'!
+
+determinize
+    | states |
+"	fsa checkSanity."
+    fsa removeEpsilons.
+    fsa removeUnreachableStates.
+    fsa mergeTransitions.
+    
+    states := fsa topologicalOrder asOrderedCollection.
+    states do: [ :state |
+        self determinizeState: state
+    ].
+
+    fsa states:	fsa startState reachableStates.
+    
+    fsa removeUnreachableStates.
+    fsa mergeTransitions.
+!
+
+determinize: anFsa
+    fsa := anFsa.
+    joinDictionary := Dictionary new.
+    
+    self determinize.
+    ^ fsa
+!
+
+determinizeOverlap: t1 second: t2 state: state
+    |  t1Prime t2Prime tIntersection |
+    self assert: (state transitions includes: t1).
+    self assert: (state transitions includes: t2).
+    
+    tIntersection := self joinTransition: t1 with: t2.
+
+    t1Prime := PEGFsaCharacterTransition new
+                    destination: t1 destination;
+                    characterSet: (t1 complement: t2);
+                    yourself.
+    t2Prime := PEGFsaCharacterTransition new
+                    destination: t2 destination;
+                    characterSet: (t2 complement: t1);
+                    yourself.					
+                                    
+                                
+    state removeTransition: t1.
+    state removeTransition: t2.
+    
+    tIntersection isEmpty ifFalse: [ state addTransition: tIntersection  ].
+    t1Prime isEmpty ifFalse: [ state addTransition: t1Prime ].
+    t2Prime isEmpty ifFalse: [ state addTransition: t2Prime ].
+!
+
+determinizeState: state
+    | pairs |
+
+    pairs := state transitionPairs asOrderedCollection.
+
+    [pairs isEmpty] whileFalse: [ 
+        | pair |
+        
+        (joinDictionary size > 100) ifTrue: [ self error: 'Oh man, this is really big FSA. Are you sure you want to continue?' ].
+        
+        pair := pairs removeFirst.
+        self assert:((pair first destination = pair second destination) not 
+                    or: [pair first isPredicateTransition not 
+                    or: [pair second isPredicateTransition not ] ]).
+                
+        self assert: (pair contains: #isEpsilon) not.		
+                
+        (pair first overlapsWith: pair second) ifTrue: [ 
+            self determinizeOverlap: pair first second: pair second state: state.
+            "recompute pairs after the determinization"
+            pairs := state transitionPairs asOrderedCollection.
+        ]
+    ].
+! !
+
+!PEGFsaAbstractDeterminizator methodsFor:'initialization'!
+
+initialize
+    super initialize.
+    joinDictionary := Dictionary new
+! !
+
+!PEGFsaAbstractDeterminizator methodsFor:'joining'!
+
+joinName: state with: anotherState into: newState
+    newState name: state name asString, '_', anotherState name asString.
+!
+
+joinState: state with: anotherState
+    | key newState |
+    key := self keyFor: state and: anotherState.
+    (joinDictionary includesKey: key) ifTrue: [ ^ joinDictionary at: key ].
+    
+    newState := PEGFsaState new.
+    joinDictionary at: key put: newState.
+
+    self joinRetval: state with: anotherState into: newState.
+    self joinInfo: state with: anotherState into: newState.
+    self joinName: state with: anotherState into: newState.
+    self joinTransitions: state with: anotherState into: newState.	
+
+    self determinizeState: newState.
+    
+    self assert: ((joinDictionary at: key) == newState).
+    ^ newState
+!
+
+joinTransition: t1 with: t2
+    | newDestination newTransition |
+    self assert: t1 isCharacterTransition.
+    self assert: t2 isCharacterTransition.
+    
+    newDestination := self joinState: t1 destination with: t2 destination.
+    
+    newTransition := PEGFsaCharacterTransition new.
+    newTransition destination: newDestination.
+    newTransition characterSet: (t1 intersection: t2).
+    newTransition priority: (t1 priority max: t2 priority).
+    
+    ^ newTransition 
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaCharacterTransition.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,326 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+PEGFsaTransition subclass:#PEGFsaCharacterTransition
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaCharacterTransition methodsFor:'accessing'!
+
+acceptsCodePoint: codePoint
+    self assert: codePoint isInteger.
+    (codePoint < 1) ifTrue: [ ^ false ].
+    ^ characterSet at: codePoint
+!
+
+beginOfRange
+    characterSet withIndexDo: [ :e :index | 
+        e ifTrue: [ ^ index ]
+    ].
+    self error: 'should not happend'
+!
+
+character
+ 	self assert: (self isSingleCharacter).
+	characterSet withIndexDo: [ :e :index | e ifTrue: [ ^ Character codePoint: index ] ].
+	self error: 'should not happen'.
+!
+
+characterSet
+    ^ characterSet
+!
+
+characterSet: anObject
+    characterSet := anObject
+!
+
+endOfRange
+    | change |
+    change := false.
+    characterSet withIndexDo: [ :e :index | 
+        e ifTrue: [ change := true ].
+        (e not and: [ change ]) ifTrue: [ ^ index - 1]
+    ].
+    ^ characterSet size
+!
+
+notCharacter
+    self assert: self isNotSingleCharacter.
+    characterSet withIndexDo: [ :value :index | value ifFalse: [ ^ Character codePoint: index ] ].
+    ^ self error: 'should not happen'
+! !
+
+!PEGFsaCharacterTransition methodsFor:'comparing'!
+
+= anotherTransition
+    "
+    Please note the identity comparison on destination
+    If you use equality instead of identy, you will get infinite loop.
+
+    So much for comparison by now :)	
+    "
+    super = anotherTransition ifFalse: [ ^ false ].
+    (characterSet = anotherTransition characterSet) ifFalse: [ ^ false ].
+    
+    ^ true
+!
+
+canBeIsomorphicTo: anotherTransition
+    (super canBeIsomorphicTo: anotherTransition) ifFalse: [ ^ false ].
+    (characterSet = anotherTransition characterSet) ifFalse: [ ^ false ].
+    
+    ^ true
+!
+
+equals: anotherTransition
+    (super equals: anotherTransition) ifFalse: [ ^ false ].
+    (characterSet = anotherTransition characterSet) ifFalse: [ ^ false ].
+
+    "JK: If character set and destination are the same, priority does not really matter"
+    ^ true
+!
+
+hash
+    ^ super hash bitXor: characterSet hash
+! !
+
+!PEGFsaCharacterTransition methodsFor:'copying'!
+
+postCopy
+    super postCopy.
+    characterSet := characterSet copy.
+! !
+
+!PEGFsaCharacterTransition methodsFor:'gt'!
+
+gtName
+    | gtName |
+    gtName := self characterSetAsString.
+    priority < 0 ifTrue: [ gtName := gtName, ',', priority asString ].
+    ^ gtName
+! !
+
+!PEGFsaCharacterTransition methodsFor:'initialization'!
+
+initialize
+    super initialize.
+    
+    characterSet := Array new: 255 withAll: false.
+! !
+
+!PEGFsaCharacterTransition methodsFor:'modifications'!
+
+addCharacter: character
+    characterSet at: character codePoint put: true
+! !
+
+!PEGFsaCharacterTransition methodsFor:'printing'!
+
+characterSetAsString
+    | stream |
+    stream := WriteStream on: ''.
+    self printCharacterSetOn: stream.
+    ^ stream contents
+!
+
+printCharacterSetOn: stream
+    (self isLetter) ifTrue: [ 
+        stream nextPutAll: '#letter'.
+        ^ self
+    ].
+
+    (self isWord) ifTrue: [ 
+        stream nextPutAll: '#word'.
+        ^ self
+    ].
+
+
+    stream nextPut: $[.
+    32 to: 126 do: [ :index |
+        (characterSet at: index) ifTrue: [ 
+            ((Character codePoint: index) == $") ifTrue: [ 
+                stream nextPutAll: '""'.
+            ] ifFalse: [ 
+                stream nextPut: (Character codePoint: index)
+            ]
+        ]
+    ].
+    stream nextPut: $].
+!
+
+printOn: stream
+    self printCharacterSetOn: stream.
+    stream nextPutAll: ' ('.
+    priority printOn: stream.
+    stream nextPutAll: ')'.		
+    stream nextPutAll: '-->'.
+    destination printOn: stream.
+    stream nextPutAll: '(ID: '.
+    stream nextPutAll: self identityHash asString.
+    stream nextPutAll: ')'.
+! !
+
+!PEGFsaCharacterTransition methodsFor:'set operations'!
+
+complement: transition
+    | complement |
+    complement := Array new: 255.
+    
+    1 to: 255 do: [ :index |
+        complement
+            at: index 
+            put: ((self characterSet at: index) and: [(transition characterSet at: index) not])
+    ].
+
+    ^ complement
+!
+
+disjunction: transition
+    | disjunction |
+    disjunction := Array new: 255.
+    
+    1 to: 255 do: [ :index |
+        disjunction
+            at: index 
+            put: ((self characterSet at: index) xor: [transition characterSet at: index])
+    ].
+
+    ^ disjunction
+!
+
+intersection: transition
+    | intersection |
+    intersection := Array new: 255.
+    
+    transition isPredicateTransition ifTrue: [ ^ intersection  ].
+    transition isEpsilonTransition ifTrue: [ self error: 'Dont know!!' ].
+    
+    1 to: 255 do: [ :index |
+        intersection
+            at: index 
+            put: ((self characterSet at: index) and: [transition characterSet at: index])
+    ].
+
+    ^ intersection
+!
+
+union: transition
+    | union |
+    union := Array new: 255.
+    
+    1 to: 255 do: [ :index |
+        union
+            at: index 
+            put: ((self characterSet at: index) or: [transition characterSet at: index])
+    ].
+
+    ^ union
+! !
+
+!PEGFsaCharacterTransition methodsFor:'testing'!
+
+accepts: character
+    self assert: character isCharacter.
+    ^ self acceptsCodePoint: character codePoint
+!
+
+isAny
+    ^ characterSet allSatisfy: [ :e | e ]
+!
+
+isCharacterTransition
+    ^ true
+!
+
+isDigit
+    characterSet withIndexDo: [ :value :index | 
+        (Character codePoint: index) isDigit == value ifFalse: [ ^ false ]
+    ].
+    ^ true
+!
+
+isEmpty
+    ^ characterSet allSatisfy: [ :e | e not ]
+!
+
+isEpsilon
+    ^ false
+!
+
+isLetter
+    characterSet withIndexDo: [ :value :index | 
+        (Character codePoint: index) isLetter == value ifFalse: [ ^ false ]
+    ].
+    ^ true
+!
+
+isNotSingleCharacter
+    ^ (characterSet select: [ :e | e not ]) size == 1
+!
+
+isSingleCharacter
+    ^ (characterSet select: [ :e | e ]) size == 1
+!
+
+isSingleRange
+    | changes previous |
+    changes := 0.
+    previous := false.
+    characterSet do: [ :e | 
+        (e == previous) ifFalse: [ changes := changes + 1 ].
+        previous := e.
+    ].
+    ^ changes < 3
+!
+
+isWord
+    characterSet withIndexDo: [ :value :index | 
+        (Character codePoint: index) isAlphaNumeric == value ifFalse: [ ^ false ]
+    ].
+    ^ true
+!
+
+overlapsWith: transition
+    transition isCharacterTransition ifFalse: [ ^ false ].
+    self isEpsilon ifTrue: [ ^ true ].
+    transition isEpsilon ifTrue: [ ^ true ].
+    
+    ^ (self intersection: transition) anySatisfy: [ :bool | bool ]
+! !
+
+!PEGFsaCharacterTransition methodsFor:'transformation'!
+
+join: transition
+    ^ self join: transition joinDictionary: Dictionary new.
+!
+
+join: transition joinDictionary: dictionary
+    | newDestination newTransition |
+"	pair := PEGFsaPair with: self with: transition.
+    (dictionary includesKey: pair) ifTrue: [ ^ dictionary at: pair ].
+    dictionary at: pair put: nil.
+"	
+    newDestination := self destination join: transition destination joinDictionary: dictionary.
+    newDestination isNil ifTrue: [ self error: 'What a cycle!! I wonder, how does this happened!!' ].
+    
+    newTransition := PEGFsaCharacterTransition new.
+    newTransition destination: newDestination.
+    newTransition characterSet: (self intersection: transition).
+    newTransition priority: (self priority min: transition priority).
+    
+"	^ dictionary at: pair put: newTransition"
+    ^ newTransition 
+!
+
+mergeWith: transition
+    | union |
+    self assert: destination = transition destination.
+    
+    union := self union: transition.
+    self characterSet: union
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaChoiceDeterminizator.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,79 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+PEGFsaAbstractDeterminizator subclass:#PEGFsaChoiceDeterminizator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaChoiceDeterminizator methodsFor:'as yet unclassified'!
+
+determinize
+    super determinize.
+
+    fsa removeLowPriorityTransitions.
+    fsa removeUnreachableStates.
+    fsa removePriorities.
+!
+
+joinInfo: info with: anotherInfo into: newInfo
+    "Merging into the failure"
+    (info isFsaFailure and: [anotherInfo isFsaFailure not]) ifTrue: [  
+        newInfo final: anotherInfo isFinal.
+        newInfo priority: anotherInfo priority.
+        newInfo failure: false.
+        ^ self
+    ].
+    
+    (anotherInfo isFsaFailure and: [info isFsaFailure not]) ifTrue: [  
+        newInfo final: info isFinal.
+        newInfo priority: (anotherInfo priority max: info priority).
+        newInfo failure: false.
+        ^ self
+    ].
+    
+    (info hasEqualPriorityTo: anotherInfo) ifTrue: [ 
+        newInfo final: (info isFinal or: [ anotherInfo isFinal ]).
+        newInfo failure: (info isFsaFailure or: [anotherInfo isFailure]).
+        newInfo priority: info priority.	
+        ^ self
+    ].
+    
+    (info hasHigherPriorityThan: anotherInfo) ifTrue: [ 
+ 		newInfo priority: info priority.	
+        newInfo failure: info isFsaFailure.
+        newInfo final: info isFinal.
+        ^ self
+    ].
+
+    newInfo priority: anotherInfo priority.
+    newInfo failure: anotherInfo isFsaFailure.
+    newInfo final: anotherInfo isFinal.
+!
+
+joinState: state with: anotherState
+    self assert: state isMultivalue not.
+    self assert: anotherState isMultivalue not.
+
+    ^ super joinState: state with: anotherState
+!
+
+joinTransitions: state with: anotherState into: newState
+    self assert: newState isMultivalue not.
+    
+    newState transitions addAll: (state transitions collect: #copy).
+    newState transitions addAll: (anotherState transitions collect: #copy).
+    newState mergeTransitions.
+! !
+
+!PEGFsaChoiceDeterminizator methodsFor:'joining'!
+
+joinRetval: state with: anotherState into: newState
+    "Different retvals cannot merge their info"
+    self assert: (state hasDifferentRetvalThan: anotherState) not. 
+    self assert: state retval == anotherState retval.
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaDeterminizator.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,61 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+PEGFsaAbstractDeterminizator subclass:#PEGFsaDeterminizator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaDeterminizator methodsFor:'checking'!
+
+checkPriorities
+    self assert: ((fsa states select: [ :s | s hasPriority  ]) allSatisfy: [ :s | s priority == 0 ]).
+    self assert: (fsa allTransitions allSatisfy: [ :s | s priority == 0 ]).
+! !
+
+!PEGFsaDeterminizator methodsFor:'determinization'!
+
+determinize
+    self checkPriorities.
+    super determinize.	
+! !
+
+!PEGFsaDeterminizator methodsFor:'joining'!
+
+joinInfo: info with: anotherInfo into: newInfo
+    "nothing to do"
+!
+
+joinRetval: state with: anotherState into: newState
+    "Different retvals cannot merge their info"
+
+    state retvalsAndInfosDo: [:retval :info |
+        retval isNil ifFalse: [ 
+            newState addInfo: info for: retval.
+        ]
+    ].
+
+    anotherState retvalsAndInfosDo: [:retval :info |
+        retval isNil ifFalse: [ 
+            self assert: (newState retvals includes: retval) not.
+            newState addInfo: info for: retval.
+        ]
+    ].
+!
+
+joinState: state with: anotherState
+    self assert: state hasZeroPriorityOnly.
+    self assert: anotherState hasZeroPriorityOnly.
+    
+    ^ super joinState: state with: anotherState
+!
+
+joinTransitions: state with: anotherState into: newState
+    newState transitions addAll: (state transitions collect: #copy).
+    newState transitions addAll: (anotherState transitions collect: #copy).
+    ^ self
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaEOFTransition.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,17 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+PEGFsaPredicateTransition subclass:#PEGFsaEOFTransition
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaEOFTransition methodsFor:'as yet unclassified'!
+
+isEOF
+    ^ true
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaEpsilonTransition.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,49 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+PEGFsaTransition subclass:#PEGFsaEpsilonTransition
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaEpsilonTransition methodsFor:'gt'!
+
+gtName
+    | gtName |
+    gtName := '<eps>'.
+    priority < 0 ifTrue: [ gtName := gtName, ',', priority asString ].
+    ^ gtName
+! !
+
+!PEGFsaEpsilonTransition methodsFor:'modifications'!
+
+decreasePriorityBy: value
+    "
+        My value has special semantics, when I have negative priority, all the reachable states and transitions should
+        be decreased by that value.
+        
+        In case I am preceded by another epsilon with negative priority, I do not decrease my value, that would multiply
+        the the negative priority effect....
+    "
+    ^ self
+! !
+
+!PEGFsaEpsilonTransition methodsFor:'set operations'!
+
+intersection: anotherState
+    ^ anotherState
+! !
+
+!PEGFsaEpsilonTransition methodsFor:'testing'!
+
+isEpsilon
+    ^ true
+!
+
+isEpsilonTransition
+    ^ true
+! !
+
--- a/compiler/PEGFsaFailure.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PEGFsaFailure.st	Mon Aug 17 12:56:02 2015 +0100
@@ -3,9 +3,66 @@
 "{ NameSpace: Smalltalk }"
 
 Object subclass:#PEGFsaFailure
-	instanceVariableNames:'message'
+	instanceVariableNames:'retval'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-FSA'
 !
 
+PEGFsaFailure class instanceVariableNames:'Instance'
+
+"
+ No other class instance variables are inherited by this class.
+"
+!
+
+!PEGFsaFailure class methodsFor:'as yet unclassified'!
+
+on: retval
+    ^ (self new)
+        retval: retval;
+        yourself
+! !
+
+!PEGFsaFailure methodsFor:'accessing'!
+
+retval
+    ^ retval
+!
+
+retval: anObject
+    retval := anObject
+!
+
+value
+    ^ retval
+! !
+
+!PEGFsaFailure methodsFor:'comparing'!
+
+= anotherFailure
+    (self == anotherFailure) ifTrue: [ ^ true ].
+    self class == anotherFailure class ifFalse: [ ^ false ].
+    
+    ^ (self retval == anotherFailure retval)
+!
+
+hash
+    ^ self retval hash
+! !
+
+!PEGFsaFailure methodsFor:'printing'!
+
+printOn: aStream
+    super printOn: aStream.
+    aStream nextPut: $(.
+    retval printOn: aStream.
+    aStream nextPut: $).
+! !
+
+!PEGFsaFailure methodsFor:'testing'!
+
+isFsaFailure
+    ^ true
+! !
+
--- a/compiler/PEGFsaGenerator.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PEGFsaGenerator.st	Mon Aug 17 12:56:02 2015 +0100
@@ -9,7 +9,114 @@
 	category:'PetitCompiler-FSA'
 !
 
-!PEGFsaGenerator methodsFor:'as yet unclassified'!
+!PEGFsaGenerator methodsFor:'hooks'!
+
+afterAccept: node retval: retval
+    retval checkSanity.
+    ^ super afterAccept: node retval: retval
+!
+
+cache: node value: retval
+    (self assert: (retval isKindOf: PEGFsa)).
+
+    (cache includesKey: node) ifTrue: [
+        self assert: (retval isIsomorphicTo: (cache at: node)).
+    ].
+
+    "I put copy of the FSA because FSA can be modified (e.g. concatenated to other FSA)"
+    cache at: node put: retval copy.
+!
+
+openDetected: node
+    "
+        This should be called when there is a recursive definition of a token.
+        The forward node caches the fsa stub with startState in order to reference it
+    "
+    ^ (self cachedValue: node)
+! !
+
+!PEGFsaGenerator methodsFor:'support'!
+
+connect: fsa with: anotherFsa
+    | finals |
+    finals := fsa finalStates reject: [:s | s isFsaFailure ].
+
+    self assert: (finals allSatisfy: [ :s | s priority = 0 ]).
+    self assert: (finals allSatisfy: [:f | fsa states includes: f]).
+    
+    finals do: [ :final |
+        | toAdopt |
+        toAdopt := anotherFsa.
+        toAdopt decreasePriority.
+        final final: false.	
+
+        fsa adopt: toAdopt.
+        fsa addTransitionFrom: final to: toAdopt startState.
+    ].
+!
+
+connectOverlapping: fsa with: anotherFsa
+    | finals |
+    finals := fsa finalStates reject: [:s | s isFsaFailure ].
+
+    self assert: (finals allSatisfy: [ :s | s priority = 0 ]).
+    self assert: (finals allSatisfy: [:f | fsa states includes: f]).
+    
+    finals do: [ :final |
+        | toAdopt |
+        toAdopt := anotherFsa copy.
+        toAdopt decreasePriority.
+        final final: false.	
+
+        fsa adopt: toAdopt.
+        fsa addTransitionFrom: final to: toAdopt startState.
+    ].
+!
+
+sequenceOf: fsa and: anotherFsa
+    | newFsa start   |
+
+    newFsa := PEGFsa new.
+    start := PEGFsaState new name: 'start'; yourself.
+    newFsa addState: start.
+    newFsa startState: start.
+    newFsa adopt: fsa.
+    newFsa addTransitionFrom: start to: fsa startState.
+
+    (newFsa finalStates size == 1) ifTrue: [  
+        self connect: newFsa with: anotherFsa.
+    ] ifFalse: [ 
+    (newFsa finalStates allSatisfy: [ :s | s transitions isEmpty ]) ifTrue: [  
+        self connect: newFsa with: anotherFsa.
+    ] ifFalse: [ 
+        self connectOverlapping: newFsa with: anotherFsa.
+    ]].
+    
+    newFsa determinize.
+    ^ newFsa
+! !
+
+!PEGFsaGenerator methodsFor:'visiting'!
+
+visitAnyNode: node
+    | stop start fsa classification |
+    start := PEGFsaState new.
+    stop := PEGFsaState new.
+    
+    classification := Array new: 255 withAll: true.
+    
+    fsa := PEGFsa new
+        addState: start;
+        addState: stop;
+        
+        startState: start;
+        finalState: stop;
+        yourself.
+    
+    fsa addTransitionFrom: start to: stop onCharacterSet: (classification).
+    
+    ^ fsa
+!
 
 visitCharSetPredicateNode: node
     | stop start fsa |
@@ -48,8 +155,9 @@
 
 visitChoiceNode: node
     | priority childrenFsa fsa start |
-    
     childrenFsa := node children collect: [ :child | child accept: self ].
+    self assert: (childrenFsa allSatisfy: [ :child | child isDeterministic  ]).
+
     fsa := PEGFsa new.
     start := PEGFsaState new.
     
@@ -58,14 +166,72 @@
 
     priority := 0.
     childrenFsa do: [ :childFsa |
+        childFsa decreasePriorityBy: priority.
         fsa adopt: childFsa.
-        fsa addTransitionFrom: start to: childFsa startState priority: priority.
-        priority := priority + childFsa minPriority.
+        fsa addTransitionFrom: start to: childFsa startState.
+        priority := priority + 1.
+        
+        fsa determinizeChoice.
     ].
 
     ^ fsa
 !
 
+visitEndOfFileNode: node
+    | stop start fsa transition |
+    start := PEGFsaState new.
+    stop := PEGFsaState new.
+    stop name: 'EOF'.
+    
+    fsa := PEGFsa new
+        addState: start;
+        addState: stop;
+        
+        startState: start;
+        finalState: stop;
+
+        yourself.
+        
+    transition := PEGFsaEOFTransition new
+        predicate: [ :cp | cp == 0 ];
+        destination: stop;
+        yourself.
+        
+    start addTransition: transition.
+    ^ fsa
+!
+
+visitForwardNode: node
+    | fsa childFsa startState startStubState |
+
+    fsa	 := PEGFsa new.
+    startStubState := PEGFsaUncopiableState new.
+    startState := PEGFsaState new.
+
+    fsa addState: startStubState.
+    fsa startState: startStubState.
+
+
+    "  cache the incomplete fsa in order to allow for
+        recursive back references... 
+    "	
+    self cache: node value: fsa.
+
+    childFsa := self visit: node child.
+    
+    cache removeKey: node.
+    
+    fsa adopt: childFsa.
+    fsa replace: startStubState with: startState.
+
+
+    fsa addTransitionFrom: startState to: childFsa startState.
+    fsa startState: startState.
+
+    fsa name: self name.
+    ^ fsa
+!
+
 visitLiteralNode: node
     | states fsa |
 
@@ -92,10 +258,20 @@
     ^ fsa
 !
 
+visitMessagePredicateNode: node
+    ^ self visitPredicateNode: node
+!
+
 visitNode: node
     self error: 'node not supported'
 !
 
+visitNotCharacterNode: node
+    self assert: (node child isKindOf: PPCCharacterNode).
+    
+    ^ self visitNotNode: node
+!
+
 visitNotNode: node
     | fsa finalState |
     fsa := node child accept: self.
@@ -104,63 +280,49 @@
         yourself.
     
     fsa finalStates do: [ :fs |
-        fs retval: PEGFsaFailure new.
+        fs failure: true.
     ].
     
-    fsa addState: finalState.
-    fsa finalState: finalState.
-
-    fsa addTransitionFrom: fsa startState to: finalState priority: -1.
+    fsa finalState: fsa startState.
+    
     ^ fsa
 !
 
 visitOptionalNode: node
-    | fsa startState finalState |
+    | fsa   |
 
     fsa := node child accept: self.
-    startState := PEGFsaState new
-        yourself.
-
-    finalState := PEGFsaState new
-        final: true;
-        yourself.
-
-    fsa addState: startState.
-    fsa addState: finalState.
-    
-    fsa addTransitionFrom: startState to: fsa startState priority: 0.
-    fsa addTransitionFrom: startState to: finalState priority: fsa minPriority.
-
-    fsa startState: startState.
+    fsa finalState: fsa startState.
 
     ^ fsa
 !
 
 visitPlusNode: node
-    | fsa finalState |
+    | fsa |
 
-    finalState := PEGFsaState new.
+"	finalState := PEGFsaState new."
     fsa := node child accept: self.
-    fsa addState: finalState.
+"	fsa addState: finalState."
     
     fsa finalStates do: [ :state |
         fsa addTransitionFrom: state to: (fsa startState).
-        fsa addTransitionFrom: state to: finalState priority: -1.
-        self assert: (state hasPriority not).
-        state priority: 0.
+"		fsa addTransitionFrom: state to: finalState priority: fsa minPriority."
+"		state hasPriority ifFalse: [ state priority: 0 ].
         state final: false.
-    ].
+"	].
 
-    fsa finalState: finalState.	
+"	fsa finalState: finalState.	"
     
     ^ fsa
 !
 
 visitPredicateNode: node
-    | stop start fsa  |
+    | stop start fsa classification |
     start := PEGFsaState new.
     stop := PEGFsaState new.
     
+    classification := (1 to: 255) collect: [:codePoint | node predicate value: (Character codePoint: codePoint) ].
+    
     fsa := PEGFsa new
         addState: start;
         addState: stop;
@@ -169,61 +331,55 @@
         finalState: stop;
         yourself.
     
-    fsa addTransitionFrom: start to: stop onCharacterSet: (node predicate classification).
-        
+    fsa addTransitionFrom: start to: stop onCharacterSet: (classification).
+    
     ^ fsa
 !
 
 visitSequenceNode: node
-    | childrenFsa fsa start previousFinalStates  |
-
-    childrenFsa := node children collect: [ :child | child accept: self ].
-
-    fsa := PEGFsa new.
-    start := PEGFsaState new name: 'start'; yourself.
-    fsa addState: start.
-    fsa startState: start.
-
-    fsa adopt: childrenFsa first.	
-    fsa addTransitionFrom: start to: childrenFsa first startState.
+    | fsa childrenFsa previousFsa  |
+    childrenFsa := node children collect: [ :child | self visit: child ].
+    self assert: (childrenFsa allSatisfy: [ :child | child isDeterministic  ]).
 
-    previousFinalStates := childrenFsa first finalStates.
-    childrenFsa allButFirst do: [ :childFsa | 
-        | newFinalStates |
-        newFinalStates := IdentitySet new.
-        previousFinalStates do: [ :state |
-            | copy |
-            copy := childFsa copy.
-            fsa adopt: copy.
-            
-            state isFailure ifFalse: [ 
-                state final: false.
-                fsa addTransitionFrom: state to: copy startState.
-            ].
-            newFinalStates addAll: copy finalStates.
-        ].
-        previousFinalStates := newFinalStates.
+    previousFsa := childrenFsa first.
+    childrenFsa allButFirst do: [ :nextFsa | 
+        fsa := self sequenceOf: previousFsa and: nextFsa.
+        previousFsa := fsa.
     ].
+    
     ^ fsa
 !
 
 visitStarNode: node
-    | fsa finalState |
+    | fsa  |
 
-    finalState := PEGFsaState new.
-    fsa := node child accept: self.
-    fsa addState: finalState.
-    
+"	finalState := PEGFsaState new.
+"	fsa := node child accept: self.
+"	fsa addState: finalState.
+"	
     fsa finalStates do: [ :state |
         fsa addTransitionFrom: state to: (fsa startState).
-        self assert: (state hasPriority not).
-        state priority: 0.
+"		state hasPriority ifFalse: [ state priority: 0 ].
         state final: false.
-    ].
+"	].
 
-    fsa addTransitionFrom: fsa startState to: finalState priority: -1.
-    fsa finalState: finalState.
+"	fsa addTransitionFrom: fsa startState to: finalState priority: -1."	
+    fsa finalState: fsa startState.
 
     ^ fsa
+!
+
+visitTokenNode: node
+    ^ self visit: node child
+!
+
+visitTrimmingTokenCharacterNode: node
+    "I do not care about trimming (so far), it should be handled by TokenCodeGenerator"
+    ^ self visit: node child
+!
+
+visitTrimmingTokenNode: node
+    "I do not care about trimming (so far), it should be handled by TokenCodeGenerator"
+    ^ self visit: node child
 ! !
 
--- a/compiler/PEGFsaInterpret.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PEGFsaInterpret.st	Mon Aug 17 12:56:02 2015 +0100
@@ -3,7 +3,7 @@
 "{ NameSpace: Smalltalk }"
 
 Object subclass:#PEGFsaInterpret
-	instanceVariableNames:'fsa debug retvals stream maxPriority'
+	instanceVariableNames:'fsa debug retvals stream'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-FSA'
@@ -29,6 +29,10 @@
 
 fsa
     ^ fsa
+!
+
+recordFor: retval
+    ^ retvals at: retval ifAbsentPut: [ PEGFsaInterpretRecord new ]
 ! !
 
 !PEGFsaInterpret methodsFor:'debugging'!
@@ -62,7 +66,6 @@
 
 interpret
     | states newStates character run  |
-    maxPriority := SmallInteger minVal.
     newStates := IdentitySet with: fsa startState.
     retvals := IdentityDictionary new.
     
@@ -71,12 +74,12 @@
     self reportStart.
     self reportFsa: fsa.
     
-    run := stream atEnd not.
+    run := "stream atEnd not" true.
     
     [run] whileTrue: [  
         states := newStates.
         newStates := IdentitySet new.
-        character := stream peek.
+        character := stream peek codePoint.
 
         self reportStates: states.
 
@@ -85,10 +88,9 @@
         ].
         
         newStates isEmpty ifFalse: [ stream next ].
-        run := stream atEnd not and: [ newStates isEmpty not ].
+        run := "stream atEnd not and: [ "newStates isEmpty not" ]".
     ].
-
-    ^ self return: newStates
+    ^ self return: states
 !
 
 interpret: anFsa on: aStream
@@ -112,36 +114,24 @@
     ^ true
 !
 
-expand: state on: character into: newStates "transitionsTaken: transitionsTaken"
-    | transitions transitionsTaken |
-
-    transitionsTaken := OrderedCollection new.
-    transitions := self sortedTransitionsFor: state.
-    transitions do: [ :t | 
-        (self allowsTransition: t from: state transitionsTaken: transitionsTaken) ifTrue: [ 
-            t isEpsilon ifTrue: [  
-                (t destination isFinal) ifTrue: [ 
-                    newStates add: t destination.
-                    self recordNewState: t destination position: stream position.
-                ].
+expand: state on: codePoint into: newStates
+    state transitions do: [ :t | 
+        t isEpsilon ifTrue: [  
+            (t destination isFinal) ifTrue: [ 
+                newStates add: t destination.
+                self recordNewState: t destination position: stream position.
+            ].
 
-                "Descent into the next state"
-                self 	expand: t destination 
-                        on: character 
-                        into: newStates.
-
-                newStates isEmpty ifFalse: [ 
-                    transitionsTaken add: t.
-                ].
-
-            ] ifFalse: [  
-                (t accepts: character) ifTrue: [ 
-                    transitionsTaken add: t.
-                    newStates add: t destination.
-                    self recordNewState: t destination.
-                ]
-            ] 
-        ]
+            "Descent into the next state"
+            self 	expand: t destination 
+                    on: codePoint 
+                    into: newStates.
+        ] ifFalse: [  
+            (t acceptsCodePoint: codePoint) ifTrue: [ 
+                newStates add: t destination.
+                self recordNewState: t destination.
+            ]
+        ] 
     ]
 !
 
@@ -150,35 +140,38 @@
 !
 
 recordNewState: state position: position
-    (state isFinal) ifFalse: [ ^ self ].
-    (maxPriority > state priority) ifTrue: [ ^ true ].
-        
-    self assert: state hasPriority description: 'final state must have priority'.
-    (maxPriority < state priority) ifTrue: [ 
-        retvals := IdentityDictionary new.
-        maxPriority := state priority.
+    | currentRecord |
+    (state isFinal) ifFalse: [ 
+        ^ self 
     ].
 
+    (state isFinal) ifFalse: [ self error: 'should not happen' ].
+    self assert: state hasPriority description: 'final state must have priority'.
 
-    state retvalAsCollection do: [ :r |
-        retvals at: r put: position
+    state retvalsAndInfosDo: [ :retval :info |
+        currentRecord := self recordFor: retval.
+        info isFsaFailure ifTrue: [ 
+            "JK: hack, nil refers to failure!! :( Refactor!!"
+            currentRecord position: nil
+        ] ifFalse: [ 
+     		currentRecord position: position	
+        ]
     ].
 !
 
 return: states
-    | priority priorities |
-    priorities := (states select: #hasPriority thenCollect: #priority).
-    priorities isEmpty ifTrue: [  
-        ^ retvals keysAndValuesRemove: [ :key :value | key class == PEGFsaFailure ] 
+    | return |
+    return := IdentityDictionary new.
+    retvals keysAndValuesRemove: [ :key :record | record position isNil ].
+
+    retvals keysAndValuesDo: [ :key :value |
+        return at: key put: value position
     ].
-    
-    priority := priorities max.
-    
-    (maxPriority < priority) ifTrue: [ ^ IdentityDictionary new ].
-    ^ retvals keysAndValuesRemove: [ :key :value | key class == PEGFsaFailure ]
+    ^ return
 !
 
 sortedTransitionsFor: state
+    self error: 'deprecated!!'.
     ^ (fsa transitionsFor: state) asOrderedCollection
         "Dear future me, enjoy this:"
 "		sort: [ :e1 :e2 | (e1 isEpsilon not and: [e2 isEpsilon]) not ])"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaInterpretRecord.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,36 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#PEGFsaInterpretRecord
+	instanceVariableNames:'maxPriority position'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaInterpretRecord methodsFor:'accessing'!
+
+maxPriority
+    ^ maxPriority
+!
+
+maxPriority: anObject
+    maxPriority := anObject
+!
+
+position
+    ^ position
+!
+
+position: anObject
+    position := anObject
+! !
+
+!PEGFsaInterpretRecord methodsFor:'initialize'!
+
+initialize
+    super initialize.
+    maxPriority := SmallInteger minVal.
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaMinimizator.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,105 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#PEGFsaMinimizator
+	instanceVariableNames:'fsa joinDictionary'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaMinimizator methodsFor:'comparison'!
+
+info: info equals: anotherInfo
+    (info == anotherInfo) ifTrue: [ ^ true ].
+    (info class == anotherInfo class) ifFalse: [ ^ false ].
+
+    "	
+        I suppose I don't if someone does not have the priority set.
+        Please note that equals is used for minimization, so I try to
+        be as liberal as possible to get as small automaton as possible.
+    "
+    (info hasPriority and: [anotherInfo hasPriority]) ifTrue: [ 	
+        (info priority == anotherInfo priority) ifFalse: [ ^ false ].
+    ].
+
+    (info isFinal == anotherInfo isFinal) ifFalse: [ ^ false ].
+    (info isFsaFailure == anotherInfo isFsaFailure) ifFalse: [ ^ false ].
+
+    ^ true
+!
+
+state: state equals: anotherState
+    (state == anotherState) ifTrue: [ ^ true ].
+    (state class == anotherState class) ifFalse: [ ^ false ].
+    
+    (state isFinal = anotherState isFinal) ifFalse: [ ^ false ].
+
+    (state stateInfos size == anotherState stateInfos size) ifFalse: [ ^ false ].
+    state retvals do: [:retval |
+        (self info: (state infoFor: retval) equals: (anotherState infoFor: retval ifAbsent: [ ^ false ])) ifFalse: [ ^ false ]
+    ].
+
+
+    (state transitions size == anotherState transitions size) ifFalse: [ ^ false ].
+    anotherState transitions do: [ :anotherStateT | 
+        (state transitions contains: [ :stateT | 
+            (anotherStateT equals: stateT) or: [
+                "this is condition for self reference" 
+                (anotherStateT destination == anotherState) and: [ stateT destination == state ]	
+            ] ] ) ifFalse: [ ^ false ]
+    ].
+    
+    ^ true
+! !
+
+!PEGFsaMinimizator methodsFor:'joining'!
+
+joinInfo: state with: anotherState
+    self assert: state stateInfos size == anotherState stateInfos size.
+
+    state stateInfos do: [ :si1 | 
+        self assert: (anotherState stateInfos contains: [ :si2 | 
+            si1 isFinal == si2 isFinal and: [ si1 isFsaFailure == si2 isFsaFailure  ]
+        ])
+    ]
+!
+
+joinName: state with: anotherState
+    state name: state name asString, '+', anotherState name asString.
+!
+
+joinState: state with: anotherState
+    self assert: state hasZeroPriorityOnly.
+    self assert: anotherState hasZeroPriorityOnly.
+
+    self joinName: state with: anotherState.
+    self joinInfo: state with: anotherState.
+    
+! !
+
+!PEGFsaMinimizator methodsFor:'minimization'!
+
+minimize
+    | pair |
+    pair := fsa statePairs detect:  [ :p | self state: p first equals: p second ] ifNone: [ nil ].
+
+    [ pair isNil not ] whileTrue: [ 
+        "Join priorities, because equivalency of priorities does not follow from the `equals:` of states"
+        self joinState: pair first with: pair second.
+        fsa replace: pair second with: pair first.
+        fsa mergeTransitions.
+
+        pair := fsa statePairs detect: [ :p | self state: p first equals: p second ] ifNone: [ nil ].
+ 	].
+!
+
+minimize: anFsa
+    fsa := anFsa.
+
+    self minimize.
+    fsa checkSanity.
+    ^ fsa
+! !
+
--- a/compiler/PEGFsaPair.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PEGFsaPair.st	Mon Aug 17 12:56:02 2015 +0100
@@ -52,3 +52,22 @@
     ^ first hash bitXor: second hash
 ! !
 
+!PEGFsaPair methodsFor:'enumerating'!
+
+detect: block
+    (block value: self first) ifTrue: [ ^ self first ].
+    (block value: self second) ifTrue: [ ^ self second ].	
+    
+    self error: 'not found!!'
+! !
+
+!PEGFsaPair methodsFor:'testing'!
+
+contains: block
+    ^ (block value: self first) or: [ block value: self second  ]
+!
+
+includes: anObject
+    ^ self first == anObject or: [ self second == anObject ]
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaPredicateTransition.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,75 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+PEGFsaTransition subclass:#PEGFsaPredicateTransition
+	instanceVariableNames:'predicate'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaPredicateTransition methodsFor:'accessing'!
+
+predicate
+    ^ predicate
+!
+
+predicate: anObject
+    predicate := anObject
+! !
+
+!PEGFsaPredicateTransition methodsFor:'comparing'!
+
+equals: anotherTransition
+    (super equals: anotherTransition) ifFalse: [ ^ false ].
+    (predicate asString = anotherTransition predicate asString) ifFalse: [ ^ false ].
+
+    ^ true
+! !
+
+!PEGFsaPredicateTransition methodsFor:'gt'!
+
+gtName
+    | gtName |
+    gtName := self predicate asString.
+    priority < 0 ifTrue: [ gtName := gtName, ',', priority asString ].
+    ^ gtName
+! !
+
+!PEGFsaPredicateTransition methodsFor:'set operations'!
+
+intersection: transition
+    | intersection |
+    intersection := Array new: 255 withAll: false.
+    ^ intersection
+! !
+
+!PEGFsaPredicateTransition methodsFor:'testing'!
+
+accepts: character
+    self assert: character isCharacter.
+    ^ self acceptsCodePoint: character codePoint
+!
+
+acceptsCodePoint: codePoint
+    self assert: codePoint isInteger.
+    ^ predicate value: codePoint
+!
+
+isCharacterTransition
+    ^ false
+!
+
+isEOF
+    ^ false
+!
+
+isPredicateTransition
+    ^ true
+!
+
+overlapsWith: transition
+    ^ false
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaSequenceDeterminizator.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,95 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+PEGFsaAbstractDeterminizator subclass:#PEGFsaSequenceDeterminizator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaSequenceDeterminizator methodsFor:'determinization'!
+
+determinize
+    super determinize.
+
+    self markFailures.
+    fsa removePriorities.
+!
+
+markFailures
+    fsa finalStates do: [ :fs |
+        | priority |
+        priority := fs priority.
+        fs reachableStates do: [ :rs |
+            (rs hasPriority and: [ (rs priority > fs priority) and: [ rs isFinal not ] ]) ifTrue: [ 
+                rs failure: true.
+                rs final: true.
+            ]
+        ]
+    ]
+! !
+
+!PEGFsaSequenceDeterminizator methodsFor:'joining'!
+
+joinInfo: info with: anotherInfo into: newInfo
+    (info hasEqualPriorityTo: anotherInfo) ifTrue: [ 
+        newInfo final: (info isFinal or: [ anotherInfo isFinal ]).
+        newInfo priority: info priority.	
+        ^ self
+    ].
+    
+    (info hasHigherPriorityThan: anotherInfo) ifTrue: [ 
+ 		newInfo priority: info priority.	
+        newInfo failure: info isFsaFailure.
+        newInfo final: info isFinal.
+        ^ self
+    ].
+
+    newInfo priority: anotherInfo priority.
+    newInfo failure: anotherInfo isFsaFailure.
+    newInfo final: anotherInfo isFinal.
+!
+
+joinRetval: state with: anotherState into: newState
+    "Different retvals cannot merge their info"
+    self assert: (state hasDifferentRetvalThan: anotherState) not. 
+    self assert: state retval == anotherState retval.
+    
+    newState retval: state retval.
+!
+
+joinState: state with: anotherState
+    self assert: state isMultivalue not.
+    self assert: anotherState isMultivalue not.
+    
+    ^ super joinState: state with: anotherState
+!
+
+joinTransitions: state with: anotherState into: newState
+    self assert: newState isMultivalue not.
+    
+    newState hasPriority ifFalse: [ 
+        newState transitions addAll: (state transitions collect: #copy).
+        newState transitions addAll: (anotherState transitions collect: #copy).
+        ^ self
+    ].
+    
+    self assert: newState hasPriority.
+    "This is a part when low priority branches are cut-out"
+    (state priority == newState priority) ifTrue: [ 
+        newState transitions addAll: (state transitions collect: #copy).
+    ] ifFalse: [
+        newState transitions addAll: (state transitions select: [ :t | t priority > newState priority ] thenCollect: #copy)
+    ].
+
+    (anotherState priority == newState priority) ifTrue: [ 
+        newState transitions addAll: (anotherState transitions collect: #copy).
+    ] ifFalse: [
+        newState transitions addAll: (anotherState transitions select: [ :t | t priority > newState priority ] thenCollect: #copy)
+    ].
+
+    newState mergeTransitions.
+! !
+
--- a/compiler/PEGFsaState.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PEGFsaState.st	Mon Aug 17 12:56:02 2015 +0100
@@ -3,7 +3,7 @@
 "{ NameSpace: Smalltalk }"
 
 Object subclass:#PEGFsaState
-	instanceVariableNames:'name retval priority transitions final multivalue'
+	instanceVariableNames:'name infos transitions'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-FSA'
@@ -17,6 +17,14 @@
     ^ self basicNew initialize.
 ! !
 
+!PEGFsaState class methodsFor:'as yet unclassified'!
+
+named: aName
+    ^ self new
+        name: aName;
+        yourself
+! !
+
 !PEGFsaState methodsFor:'accessing'!
 
 destination
@@ -28,20 +36,42 @@
     ^ (transitions collect: #destination) asIdentitySet
 !
 
+failure: boolean
+    self info failure: boolean
+!
+
 final
-    ^ final
+    ^ self info final
 !
 
-final: anObject
-    final := anObject
+final: boolean
+    self info final: boolean
+!
+
+infoFor: retval
+    ^ infos at: retval
+!
+
+infoFor: retval ifAbsent: block
+    ^ infos at: retval ifAbsent: block
+!
+
+isFsaFailure
+    ^ self isFinal and: [ self info isFsaFailure ]
 !
 
 multivalue
-    ^ multivalue
+    <resource: #obsolete>
+    ^ self isMultivalue
+
+    "Modified: / 17-08-2015 / 12:03:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 multivalue: anObject
-    multivalue := anObject
+    self flag: 'JK: Obsolete?'.
+    "multivalue := anObject"
+
+    "Modified: / 17-08-2015 / 12:03:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 name
@@ -52,16 +82,16 @@
     name := anObject asString
 !
 
-prefix
-    ^ 'state'
-!
-
 priority
-    ^ priority
+    ^ self info priority
 !
 
 priority: anObject
-    priority := anObject
+    self info priority: anObject
+!
+
+priorityFor: retval
+    ^ (self infoFor: retval) priority
 !
 
 priorityIfNone: value
@@ -69,23 +99,31 @@
 !
 
 retval
-    ^ retval
+    self assert: self isMultivalue not.
+    ^ infos keys anyOne
 !
 
 retval: anObject
-    retval := anObject
+    | info |
+    info := self info.
+    infos removeAll.
+    infos at: anObject put: info.
 !
 
 retvalAsCollection
-    ^ self isMultivalue ifTrue: [ 
-        self retval
-    ] ifFalse: [ 
-        Array with: self retval
-    ]
+    ^ infos keys
+!
+
+retvals
+    ^ infos keys
 !
 
-suffix
-    ^ ''
+retvalsAndInfosDo: twoArgBlock
+ 	infos keysAndValuesDo: twoArgBlock
+!
+
+stateInfos
+    ^ infos values
 !
 
 transitions
@@ -94,6 +132,35 @@
 
 !PEGFsaState methodsFor:'analysis'!
 
+collectNonEpsilonTransitionsOf: state to: collection
+    state transitions do: [ :t | 
+        t isEpsilon ifTrue: [ 
+            self collectNonEpsilonTransitionsOf: t destination to: collection
+        ] ifFalse: [ 
+            collection add: t
+        ]
+    ].
+    ^ collection
+!
+
+nonEpsilonTransitionPairs
+    | size pairs collection |
+    pairs := OrderedCollection new.
+    
+    collection := OrderedCollection new.
+    self collectNonEpsilonTransitionsOf: self to: collection.
+    size := collection size.
+
+    1 to: (size - 1) do: [ :index1 |
+        (index1 + 1 to: size) do: [ :index2 | 
+            pairs add: (PEGFsaPair 
+                with: (collection at: index1)
+                with: (collection at: index2)).
+        ]
+    ].
+    ^ pairs
+!
+
 reachableStates
     | openSet |
     openSet := IdentitySet new.
@@ -117,16 +184,15 @@
 transitionPairs
     | size pairs collection |
     size := transitions size.
-    pairs := OrderedCollection new: (size - 1) * size / 2.
+    pairs := OrderedCollection new.
     
     collection := transitions asOrderedCollection.
 
     1 to: (size - 1) do: [ :index1 |
         (index1 + 1 to: size) do: [ :index2 | 
-            pairs add: (PEGFsaPair new 
-                first: (collection at: index1);
-                second: (collection at: index2);
-                yourself).
+            pairs add: (PEGFsaPair 
+                with: (collection at: index1)
+                with: (collection at: index2)).
         ]
     ].
     ^ pairs
@@ -136,13 +202,14 @@
 
 = anotherState
     (self == anotherState) ifTrue: [ ^ true ].
-    (self class == anotherState class) ifFalse: [ ^ true ].
+    (self class == anotherState class) ifFalse: [ ^ false ].
     
     (name == anotherState name) ifFalse: [ ^ false ].
-    (priority == anotherState priority) ifFalse: [ ^ false ].
-    (multivalue == anotherState multivalue) ifFalse: [ ^ false ].
-    (retval = anotherState retval) ifFalse: [ ^ false ].
-    (final = anotherState final) ifFalse: [ ^ false ].
+
+    (self stateInfos size == anotherState stateInfos size) ifFalse: [ ^ false ].
+    self retvals do: [:retval |
+        ((self infoFor: retval) = (anotherState infoFor: retval  ifAbsent: [ ^ false ])) ifFalse: [ ^ false ]
+    ].
 
     (transitions size = anotherState transitions size) ifFalse: [ ^ false ].
     transitions do: [:t |
@@ -154,25 +221,35 @@
 
 canBeIsomorphicTo: anotherState
     (name == anotherState name) ifFalse: [ ^ false ].
-    (priority == anotherState priority) ifFalse: [ ^ false ].
-    (multivalue == anotherState multivalue) ifFalse: [ ^ false ].
-    (final == anotherState final) ifFalse: [ ^ false ].
     (transitions size == anotherState transitions size) ifFalse: [ ^ false ].
-    (retval = anotherState retval) ifFalse: [ ^ false ].
+
+    (self stateInfos size == anotherState stateInfos size) ifFalse: [ ^ false ].
+    self retvals do: [:retval |
+        ((self infoFor: retval) = (anotherState infoFor: retval ifAbsent: [ ^ false ])) ifFalse: [ ^ false ]
+    ].
     
     ^ true
 !
 
 equals: anotherState
+    self error: 'deprecated'.
+    "
+        JK: there is a bit mess between equals, isomorphic and =
+        
+        JK: I should clean it, but the idea behind is:
+            - for minimization, I use equals 
+            - for comparing, I use canBeIsomorphicTo: (because it can handle nested structures)
+            - I have no idea, why I override =     O:)
+    "
+
     (self == anotherState) ifTrue: [ ^ true ].
-    (anotherState class == PEGFsaState) ifFalse: [ ^ false ].
+    (self class == anotherState class) ifFalse: [ ^ false ].
     
-    (retval = anotherState retval) ifFalse: [ ^ false ].
-    (multivalue = anotherState multivalue) ifFalse: [ ^ false ].
     (self isFinal = anotherState isFinal) ifFalse: [ ^ false ].
 
-    (self hasPriority and: [anotherState hasPriority]) ifTrue: [ 	
-        (priority == anotherState priority) ifFalse: [ ^ false ].
+    (self stateInfos size == anotherState stateInfos size) ifFalse: [ ^ false ].
+    self retvals do: [:retval |
+        ((self infoFor: retval) equals: (anotherState infoFor: retval ifAbsent: [ ^ false ])) ifFalse: [ ^ false ]
     ].
 
     (transitions size == anotherState transitions size) ifFalse: [ ^ false ].
@@ -184,22 +261,20 @@
 !
 
 hash
-    ^ retval hash bitXor: (
-        priority hash bitXor: (
-        multivalue hash bitXor:
-        "JK: Size is not the best option here, but it one gets infinite loops otherwise"
-        transitions size hash)).
+    "JK: Size is not the best option here, but it one gets infinite loops otherwise"
+    ^ infos hash bitXor: transitions size hash
 !
 
 isIsomorphicTo: anotherState resolvedSet: set
+    self error: 'depracated?'.
     (self == anotherState) ifTrue: [ ^ true ].
     
-    (name == anotherState name) ifFalse: [ ^ false ].
+"	(name == anotherState name) ifFalse: [ ^ false ].
     (priority == anotherState priority) ifFalse: [ ^ false ].
-    (multivalue == anotherState multivalue) ifFalse: [ ^ false ].
+    (multivalue == anotherState isMultivalue) ifFalse: [ ^ false ].
     (retval = anotherState retval) ifFalse: [ ^ false ].
     (final = anotherState final) ifFalse: [ ^ false ].
-
+"
     (transitions size = anotherState transitions size) ifFalse: [ ^ false ].
     transitions do: [:t |
         (anotherState transitions contains: [:at | t isIsomorphicto: at]) ifFalse: [ ^ false ].
@@ -211,22 +286,60 @@
 !PEGFsaState methodsFor:'copying'!
 
 postCopy
+    | newInfos |
     super postCopy.
     transitions := (transitions collect: [ :t | t copy ]).
-    retval := retval copy.
+    
+    newInfos := IdentityDictionary new.
+    infos keysAndValuesDo: [ :key :value | 
+        newInfos at: key put: value copy
+    ].
+
+    infos := newInfos.
 ! !
 
 !PEGFsaState methodsFor:'gt'!
 
 gtName
-    | gtName |
-    gtName := name.
-
+    |  gtStream |
+    gtStream := '' writeStream.
+    self printNameOn: gtStream.
+    
     self hasPriority ifTrue: [ 
-        gtName := gtName asString, ',', self priority asString.
+        self retvalsAndInfosDo: [ :retval :info | 
+            gtStream nextPut: (Character codePoint: 13). 
+            gtStream nextPutAll: retval asString.
+            gtStream nextPutAll: '->'.
+            info printOn: gtStream. 
+        ].
     ].
 
-    ^ gtName
+    ^ gtStream contents trim
+! !
+
+!PEGFsaState methodsFor:'ids'!
+
+defaultName
+    ^ #state
+!
+
+hasName
+    ^ name isNil not
+!
+
+prefix
+    ^ nil
+!
+
+suffix
+    ^ nil
+! !
+
+!PEGFsaState methodsFor:'infos'!
+
+info
+    self assert: infos size = 1.
+    ^ infos anyOne
 ! !
 
 !PEGFsaState methodsFor:'initialization'!
@@ -235,22 +348,59 @@
     super initialize.
     
     transitions := OrderedCollection new.
-    multivalue := false.
+
+    infos := IdentityDictionary new.
+    infos at: nil put: PEGFsaStateInfo new.
 ! !
 
 !PEGFsaState methodsFor:'modifications'!
 
+addInfo: info for: retval
+    infos removeKey: nil ifAbsent: [ "not a big deal" ].
+    infos at: retval put: info
+!
+
 addTransition: t
     self assert: (transitions identityIncludes: t) not.
     transitions add: t
 !
 
 decreasePriority
+    self decreasePriorityBy: 1.
+!
+
+decreasePriorityBy: value
     (self isFinal and: [ self hasPriority not ]) ifTrue: [ 
-        priority := 0.
+        self error: 'Final States Should have priority!!'
     ].
-    priority isNil ifFalse: [ 
-        priority := priority - 1
+
+    self priority isNil ifFalse: [ 
+        self priority: self priority - value
+    ]
+!
+
+join: state
+    ^ self join: state joinDictionary: Dictionary new
+!
+
+mergeInfo: state into: newState
+    self info merge: state info into: newState info.
+!
+
+mergeTransitions
+    | toRemove |
+    toRemove := OrderedCollection new.
+    self transitionPairs do:[ :pair | 
+        (pair first destination = pair second destination) ifTrue: [ 
+            (pair first isPredicateTransition not and: [pair second isPredicateTransition not]) ifTrue: [ 
+                pair first mergeWith: pair second.
+                toRemove add: pair second.
+            ]
+        ]
+    ].
+
+    toRemove do: [ :t |
+        self removeTransition: t
     ]
 !
 
@@ -259,6 +409,94 @@
     transitions remove: t
 ! !
 
+!PEGFsaState methodsFor:'modifications - determinization'!
+
+determinize
+    ^ PEGFsaAbstractDeterminizator new determinizeState: self
+!
+
+join: state joinDictionary: dictionary
+    | pair newState |
+    self error: 'deprecated'.
+    pair := PEGFsaPair with: self with: state.
+    (dictionary includesKey: pair) ifTrue: [ ^ dictionary at: pair ].
+    
+    newState := PEGFsaState new.
+    
+    dictionary at: pair put: newState.
+
+    self joinRetval: state into: newState.
+    self joinName: state into: newState.
+    self joinTransitions: state into: newState.	
+
+    newState determinize: dictionary.
+    
+    ^ dictionary at: pair put: newState
+!
+
+joinInfo: state into: newState
+    self info join: state info into: newState info.
+!
+
+joinName: state into: newState
+    newState name: self name asString, '_', state name asString.
+!
+
+joinRetval: state into: newState
+    "Different retvals cannot merge their info"
+    (self hasDifferentRetvalThan: state) ifTrue: [  
+        newState addInfo: self info for: self retval.
+        newState addInfo: state info for: state retval.
+        ^ self
+    ].
+
+
+    (self hasHigherPriorityThan: state) ifTrue: [ 
+        newState retval: self retval	
+    ].
+
+    (state hasHigherPriorityThan: self) ifTrue: [ 
+        newState retval: state retval	
+    ].
+
+    (state priority == self priority) ifTrue: [ 
+        self hasRetval ifTrue: [newState retval: self retval].
+        state hasRetval ifTrue: [newState retval: state retval].
+    ].
+
+    self joinInfo: state into: newState.
+!
+
+joinTransitions: state into: newState
+    newState isMultivalue ifTrue: [ 
+        newState transitions addAll: (self transitions collect: #copy).
+        newState transitions addAll: (state transitions collect: #copy).
+        ^ self
+    ].
+    
+    newState hasPriority ifFalse: [ 
+        newState transitions addAll: (self transitions collect: #copy).
+        newState transitions addAll: (state transitions collect: #copy).
+        ^ self
+    ].
+
+    
+    self assert: newState hasPriority.
+    
+    "This is a part when low priority branches are cut"
+    (self priority == newState priority) ifTrue: [ 
+        newState transitions addAll: (self transitions collect: #copy).
+    ] ifFalse: [
+        newState transitions addAll: (self transitions select: [ :t | t priority > newState priority ] thenCollect: #copy)
+    ].
+
+    (state priority == newState priority) ifTrue: [ 
+        newState transitions addAll: (state transitions collect: #copy).
+    ] ifFalse: [
+        newState transitions addAll: (state transitions select: [ :t | t priority > newState priority ] thenCollect: #copy)
+    ].
+! !
+
 !PEGFsaState methodsFor:'printing'!
 
 printNameOn: aStream
@@ -273,11 +511,14 @@
     self printNameOn: aStream.
     aStream nextPut: Character space.
     aStream nextPutAll: self identityHash asString.
-    self isFinal ifTrue: [ 
-        aStream nextPutAll: ' FINAL'.
+
+    self retvalsAndInfosDo: [ :retval :info | 
+        retval printOn: aStream.
+        aStream nextPutAll: '->'.
+        info printOn: aStream.
+        aStream nextPutAll: ';'.
     ].
-    aStream nextPut: (Character codePoint: 32).
-    aStream nextPutAll: priority asString.
+
     aStream nextPut: $)
 ! !
 
@@ -287,129 +528,58 @@
     ^ true
 !
 
+hasDifferentRetvalThan: anotherState
+    "returns true only if both hav retval and both retvals are different"
+    self hasRetval ifFalse: [ ^ false ].	
+    anotherState hasRetval ifFalse: [ ^ false ].
+
+    "`retval value` is called in order to obtain retval from FsaFailure (if any)"
+    ^ (self retval value == anotherState retval value) not
+!
+
 hasEqualPriorityTo: state
-    "nil - nil"
-    (self hasPriority not and: [state hasPriority not]) ifTrue: [ ^ true ].
-    
-    "nil - priority"
-    (self hasPriority) ifFalse: [ ^ false ].
-    
-    "priority - nil"
-    state hasPriority ifFalse: [ ^ false ].
-    
-    "priority - priority"
-    ^ self priority = state priority 
+    ^ self info hasEqualPriorityTo: state info
 !
 
 hasHigherPriorityThan: state
-    "nil - nil"
-    (self hasPriority not and: [state hasPriority not]) ifTrue: [ ^ true ].
-    
-    "nil - priority"
-    (self hasPriority) ifFalse: [ ^ false ].
-    
-    "priority - nil"
-    state hasPriority ifFalse: [ ^ true ].
-    
-    "priority - priority"
-    ^ self priority > state priority 
+    ^ self info hasHigherPriorityThan: state info
 !
 
 hasPriority
-    ^ priority isNil not
+    ^ self stateInfos anySatisfy: [ :info | info hasPriority ]
+!
+
+hasRetval
+    ^ self retval isNil not
+!
+
+hasZeroPriorityOnly
+    ^ self stateInfos allSatisfy: [ :si | si hasPriority not or: [ si priority == 0 ] ].
 !
 
 isFailure
+    self error: 'Obsolete?'.
+    "
     ^ self isFinal and: [ retval class == PEGFsaFailure ]
+    "
+
+    "Modified: / 17-08-2015 / 12:01:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 isFinal
-    final isNil ifTrue: [ ^ false ].
-    
-    final ifTrue: [
-"		self assert: self hasPriority. "
-        ^ true
-    ].
-
-    ^ false
+    ^ self stateInfos anySatisfy: [ :info | info isFinal ].
 !
 
 isMultivalue
-    ^ multivalue
+    ^ infos size > 1
+!
+
+isStub
+    ^ false
 ! !
 
 !PEGFsaState methodsFor:'transformation'!
 
-determinize
-    ^ self determinize: Dictionary new.
-!
-
-determinize: dictionary
-    self transitionPairs do: [ :pair |
-        self assert: (pair first destination = pair second destination) not.
-        (pair first overlapsWith: pair second) ifTrue: [ 
-            self determinizeOverlap: pair first second: pair second joinDictionary: dictionary
-        ]
-    ].
-!
-
-determinizeOverlap: t1 second: t2 joinDictionary: dictionary
-    | pair t1Prime t2Prime tIntersection |
-    pair := PEGFsaPair with: t1 with: t2.
-
-    (dictionary includes: pair) ifTrue: [ self error: 'should not happen'.].
-    dictionary at: pair put: nil.
-    
-    tIntersection := t1 join: t2 joinDictionary: dictionary.
-    t1Prime := PEGFsaTransition new
-                    destination: t1 destination;
-                    characterSet: (t1 complement: t2);
-                    yourself.
-    t2Prime := PEGFsaTransition new
-                    destination: t2 destination;
-                    characterSet: (t2 complement: t1);
-                    yourself.					
-                                    
-                                
-    self removeTransition: t1.
-    self removeTransition: t2.
-    
-    tIntersection isEpsilon ifFalse: [ self addTransition: tIntersection  ].
-    t1Prime isEpsilon ifFalse: [ self addTransition: t1Prime ].
-    t2Prime isEpsilon ifFalse: [ self addTransition: t2Prime ].
-    
-    dictionary at: pair put: (Array 
-                                        with: tIntersection 
-                                        with: t1Prime
-                                        with: t2Prime
-                                    )
-!
-
-join: state
-    ^ self join: state joinDictionary: Dictionary new
-!
-
-join: state joinDictionary: dictionary
-    | pair newState |
-    pair := PEGFsaPair with: self with: state.
-    (dictionary includesKey: pair) ifTrue: [ ^ dictionary at: pair ].
-    
-    newState := PEGFsaState new.
-    
-    dictionary at: pair put: newState.
-    
-    self joinFinal: state newState: newState.
-    self joinPriority: state newState: newState.
-    self joinRetval: state newState: newState.
-    self joinName: state newState: newState.
-    
-    newState transitions addAll: (self transitions collect: #copy).
-    newState transitions addAll: (state transitions collect: #copy).
-    newState determinize: dictionary.
-    
-    ^ dictionary at: pair put: newState
-!
-
 joinFinal: state newState: newState
     (self hasEqualPriorityTo: state) ifTrue: [ 
         ^ newState final: (self isFinal or: [ state isFinal ]).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaStateInfo.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,212 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#PEGFsaStateInfo
+	instanceVariableNames:'priority final failure'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaStateInfo methodsFor:'accessing'!
+
+failure
+    ^ failure
+!
+
+failure: anObject
+    failure := anObject
+!
+
+final
+    ^ final
+!
+
+final: anObject
+    final := anObject
+!
+
+priority
+    ^ priority
+!
+
+priority: anObject
+    priority := anObject
+! !
+
+!PEGFsaStateInfo methodsFor:'comparing'!
+
+= anotherInfo
+    (self == anotherInfo) ifTrue: [ ^ true ].
+    (self class == anotherInfo class) ifFalse: [ ^ false ].
+    
+    (priority == anotherInfo priority) ifFalse: [ ^ false ].
+
+    (self isFinal == anotherInfo isFinal) ifFalse: [ ^ false ].
+
+    ^ true
+!
+
+equals: anotherInfo
+    self error: 'deprecated'.
+    (self == anotherInfo) ifTrue: [ ^ true ].
+    (self class == anotherInfo class) ifFalse: [ ^ false ].
+
+    "	
+        I suppose I don't if someone does not have the priority set.
+        Please note that equals is used for minimization, so I try to
+        be as liberal as possible to get as small automaton as possible.
+    "
+    (self hasPriority and: [anotherInfo hasPriority]) ifTrue: [ 	
+        (priority == anotherInfo priority) ifFalse: [ ^ false ].
+    ].
+
+    (self isFinal == anotherInfo isFinal) ifFalse: [ ^ false ].
+
+    ^ true
+! !
+
+!PEGFsaStateInfo methodsFor:'modifications - determinization'!
+
+join: info into: newInfo
+    self error: 'deprecated'.
+    "
+        The diff between JOIN and Merge:
+        - join is used while determinizing the FSA
+        - merge is used when removing epsilons
+    "
+
+    (self hasEqualPriorityTo: info) ifTrue: [ 
+        newInfo final: (self isFinal or: [ info isFinal ]).
+ 		newInfo priority: self priority.	
+        ^ self
+    ].
+    
+    (self hasHigherPriorityThan: info) ifTrue: [ 
+ 		newInfo priority: self priority.	
+        newInfo final: self isFinal.
+        ^ self
+    ].
+
+    newInfo priority: info priority.
+    newInfo final: info isFinal.
+! !
+
+!PEGFsaStateInfo methodsFor:'printing'!
+
+printOn: aStream
+    priority isNil ifFalse: [ 
+        priority printOn: aStream.
+        aStream nextPutAll: ', '	
+    ].
+
+    self isFinal ifTrue: [ 
+        aStream nextPutAll: 'FINAL'.
+        aStream nextPutAll: ', '	
+    ].
+
+    self isFsaFailure ifTrue: [ 
+        aStream nextPutAll: 'FAILURE'
+    ].
+! !
+
+!PEGFsaStateInfo methodsFor:'testing'!
+
+hasEqualPriorityTo: stateInfo
+    "nil - nil"
+    (self hasPriority not and: [stateInfo hasPriority not]) ifTrue: [ ^ true ].
+    
+    "nil - priority"
+    (self hasPriority) ifFalse: [ ^ false ].
+    
+    "priority - nil"
+    stateInfo hasPriority ifFalse: [ ^ false ].
+    
+    "priority - priority"
+    ^ self priority = stateInfo priority 
+!
+
+hasHigherPriorityThan: stateInfo
+    "nil - nil"
+    (self hasPriority not and: [stateInfo hasPriority not]) ifTrue: [ ^ true ].
+    
+    "nil - priority"
+    (self hasPriority) ifFalse: [ ^ false ].
+    
+    "priority - nil"
+    stateInfo hasPriority ifFalse: [ ^ true ].
+    
+    "priority - priority"
+    ^ self priority > stateInfo priority 
+!
+
+hasPriority
+    ^ self priority isNil not
+!
+
+isBlank
+    ^ self hasPriority not and: [ self isFinal not ]
+!
+
+isFinal
+    final isNil ifTrue: [ ^ false ].
+    ^ final
+!
+
+isFsaFailure
+    failure isNil ifTrue: [ ^ false ].
+    ^ failure
+! !
+
+!PEGFsaStateInfo methodsFor:'transformation'!
+
+merge: info into: newInfo
+    "
+        The diff between JOIN and Merge:
+        - join is used while determinizing the FSA
+        - merge is used when removing epsilons
+    "
+
+    "final - final"
+    (self isFinal and: [info isFinal]) ifTrue: [ 
+        newInfo final: true.
+        (self hasHigherPriorityThan: info) ifTrue: [  
+            newInfo priority: self priority.
+        ] ifFalse: [  
+            newInfo priority: info priority.
+        ].
+        "
+            This has its reason: when moving from failure to non-failure
+            using the epsilon, just keep the latter:
+        "
+        newInfo failure: info isFsaFailure.
+        ^ self
+ 	].
+
+    "final - non final"
+    (self isFinal) ifTrue: [ 
+        newInfo final: true.
+        newInfo priority: self priority.
+        newInfo failure: self isFsaFailure.
+        ^ self
+    ].
+
+    "non final - final"
+    (info isFinal) ifTrue: [ 
+        newInfo final: true.
+        newInfo priority: info priority.
+        newInfo failure: info isFsaFailure.
+        ^ self
+    ].
+    
+    "non final - non final"
+ 	newInfo priority: self priority.	
+    (self hasHigherPriorityThan: info) ifTrue: [  
+        newInfo priority: self priority.
+    ] ifFalse: [  
+        newInfo priority: info priority.
+    ].
+    newInfo failure: info isFsaFailure.
+! !
+
--- a/compiler/PEGFsaTransition.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PEGFsaTransition.st	Mon Aug 17 12:56:02 2015 +0100
@@ -3,7 +3,7 @@
 "{ NameSpace: Smalltalk }"
 
 Object subclass:#PEGFsaTransition
-	instanceVariableNames:'characterSet destination priority'
+	instanceVariableNames:'destination priority characterSet'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-FSA'
@@ -57,14 +57,13 @@
 
     (destination == anotherTransition destination) ifFalse: [ ^ false ].
     (priority == anotherTransition priority) ifFalse: [ ^ false ].
-    (characterSet = anotherTransition characterSet) ifFalse: [ ^ false ].
     
     ^ true
 !
 
 canBeIsomorphicTo: anotherTransition
+    (self class == anotherTransition class) ifFalse: [ ^ false ].
     (priority == anotherTransition priority) ifFalse: [ ^ false ].
-    (characterSet = anotherTransition characterSet) ifFalse: [ ^ false ].
     
     ^ true
 !
@@ -73,32 +72,16 @@
     "this method is used for minimization of the FSA"
     
     (self == anotherTransition) ifTrue: [ ^ true ].
+    (self class == anotherTransition class) ifFalse: [ ^ false ].
 
     (destination == anotherTransition destination) ifFalse: [ ^ false ].
-    (characterSet = anotherTransition characterSet) ifFalse: [ ^ false ].
 
     "JK: If character set and destination are the same, priority does not really matter"
     ^ true
 !
 
 hash
-    ^ destination hash bitXor: (priority hash bitXor: characterSet hash)
-!
-
-isIsomorphicTo: object resolvedSet: set
-    (set includes: (PEGFsaPair with: self with: object)) ifTrue: [ 
-        ^ true
-    ].
-    set add: (PEGFsaPair with: self with: object).
-
-    (self == object) ifTrue: [ ^ true ].
-    (self class == object class) ifFalse: [ ^ false ].
-
-    (priority == object priority) ifFalse: [ ^ false ].
-    (characterSet = object characterSet) ifFalse: [ ^ false ].
-    (destination isIsomorphicTo: object destination resolvedSet: set) ifFalse: [ ^ false ].
-    
-    ^ true
+    ^ destination hash bitXor: priority hash
 ! !
 
 !PEGFsaTransition methodsFor:'copying'!
@@ -121,7 +104,6 @@
 
 initialize
     super initialize.
-    characterSet := Array new: 255 withAll: false.
     priority := 0.
 ! !
 
@@ -132,43 +114,11 @@
 !
 
 decreasePriority
-    priority := priority - 1
-! !
-
-!PEGFsaTransition methodsFor:'printing'!
-
-characterSetAsString
-    | stream |
-    stream := WriteStream on: ''.
-    self printCharacterSetOn: stream.
-    ^ stream contents
+    self decreasePriorityBy: 1
 !
 
-printCharacterSetOn: stream
-    self isEpsilon ifTrue: [ 
-        stream nextPutAll: '<epsilon>'.
-        ^ self
-    ].
-
-    stream nextPut: $[.
-    32 to: 127 do: [ :index |
-        (characterSet at: index) ifTrue: [ 
-            stream nextPut: (Character codePoint: index)
-        ]
-    ].
-    stream nextPut: $].
-!
-
-printOn: stream
-    self printCharacterSetOn: stream.
-    stream nextPutAll: ' ('.
-    priority printOn: stream.
-    stream nextPutAll: ')'.		
-    stream nextPutAll: '-->'.
-    destination printOn: stream.
-    stream nextPutAll: '(ID: '.
-    stream nextPutAll: self identityHash asString.
-    stream nextPutAll: ')'.
+decreasePriorityBy: value
+    priority := priority - value
 ! !
 
 !PEGFsaTransition methodsFor:'set operations'!
@@ -231,8 +181,20 @@
     ^ characterSet at: character codePoint
 !
 
+isCharacterTransition
+    ^ false
+!
+
 isEpsilon
-    ^ characterSet allSatisfy: [ :e | e not ]
+    ^ self isEpsilonTransition
+!
+
+isEpsilonTransition
+    ^ false
+!
+
+isPredicateTransition
+    ^ false
 !
 
 overlapsWith: transition
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PEGFsaUncopiableState.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,35 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+PEGFsaState subclass:#PEGFsaUncopiableState
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-FSA'
+!
+
+!PEGFsaUncopiableState methodsFor:'as yet unclassified'!
+
+addTransition: t
+    self error: 'should not happen'
+!
+
+copy
+    ^ self
+!
+
+final: value
+    self error: 'should not happen'
+!
+
+priority: anObject
+    self error: 'should not happen'
+! !
+
+!PEGFsaUncopiableState methodsFor:'testing'!
+
+isStub
+    ^ true
+! !
+
--- a/compiler/PPCASTUtilities.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCASTUtilities.st	Mon Aug 17 12:56:02 2015 +0100
@@ -28,17 +28,17 @@
     allClassVarNames := Set new.
     cls := aClaas.
     [ cls notNil ] whileTrue:[ 
-	| instanceVariables classVariables |
-		
-	instanceVariables := cls instanceVariables.
-	classVariables := cls classVariables.
-	instanceVariables notNil ifTrue:[
-	    allInstVarNames addAll: instanceVariables.
-	]. 
-	classVariables notNil ifTrue:[
-	    allClassVarNames addAll: classVariables.
-	].
-	cls := cls superclass.
+        | instanceVariables classVariables |
+                
+        instanceVariables := cls instanceVariables.
+        classVariables := cls classVariables.
+        instanceVariables notNil ifTrue:[
+            allInstVarNames addAll: instanceVariables.
+        ]. 
+        classVariables notNil ifTrue:[
+            allClassVarNames addAll: classVariables.
+        ].
+        cls := cls superclass.
     ].
 
     self withAllVariableNodesOf: anRBBlockNode  do: [ :node | 
--- a/compiler/PPCAbstractActionNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCAbstractActionNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -22,7 +22,7 @@
     block := anObject
 !
 
-prefix
+defaultName
     ^ #action
 ! !
 
--- a/compiler/PPCAbstractLiteralNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCAbstractLiteralNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,6 +11,10 @@
 
 !PPCAbstractLiteralNode methodsFor:'accessing'!
 
+defaultName
+    ^ #lit
+!
+
 literal
     
     ^ literal
@@ -19,10 +23,6 @@
 literal: anObject
     
     literal := anObject
-!
-
-prefix
-    ^ #lit
 ! !
 
 !PPCAbstractLiteralNode methodsFor:'analysis'!
--- a/compiler/PPCAbstractPredicateNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCAbstractPredicateNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -9,8 +9,13 @@
 	category:'PetitCompiler-Nodes'
 !
 
+
 !PPCAbstractPredicateNode methodsFor:'accessing'!
 
+defaultName
+    ^ #predicate
+!
+
 predicate
     
     ^ predicate
@@ -19,10 +24,6 @@
 predicate: anObject
     
     predicate := anObject
-!
-
-prefix
-    ^ #predicate
 ! !
 
 !PPCAbstractPredicateNode methodsFor:'analysis'!
@@ -65,3 +66,10 @@
     ^ (classification asOrderedCollection addLast: false; yourself) asArray
 ! !
 
+!PPCAbstractPredicateNode class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- a/compiler/PPCAndNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCAndNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,7 +11,7 @@
 
 !PPCAndNode methodsFor:'accessing'!
 
-prefix
+defaultName
     ^ #and
 ! !
 
--- a/compiler/PPCAnyNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCAnyNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -12,7 +12,7 @@
 
 !PPCAnyNode methodsFor:'accessing'!
 
-prefix
+defaultName
     ^ #any
 ! !
 
@@ -23,7 +23,8 @@
 !
 
 firstCharSet
-    ^ PPCharSetPredicate on: [:e | true ] 
+    self flag: 'JK: hack alert, 3 is EOF'.
+    ^ PPCharSetPredicate on: [:e | (e == 3) not  ] 
 ! !
 
 !PPCAnyNode methodsFor:'visiting'!
--- a/compiler/PPCCharacterNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCCharacterNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -19,7 +19,7 @@
     character := char
 !
 
-prefix
+defaultName
     ^ #char
 ! !
 
@@ -59,7 +59,7 @@
         ^ self
     ].
 
-    aStream nextPutAll: ', not('; print: character; nextPutAll: ')'
+    aStream nextPutAll: ', '; print: character.
 ! !
 
 !PPCCharacterNode methodsFor:'visiting'!
--- a/compiler/PPCChoiceNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCChoiceNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -12,7 +12,7 @@
 
 !PPCChoiceNode methodsFor:'accessing'!
 
-prefix
+defaultName
     ^ #ch
 ! !
 
--- a/compiler/PPCClassBuilder.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCClassBuilder.st	Mon Aug 17 12:56:02 2015 +0100
@@ -74,6 +74,16 @@
 !
 
 cleanGeneratedMethods
+    (compiledClass methodDictionary size == 0) ifTrue: [ ^ self ].
+
+    "this is hack, but might help the performance..."
+    (compiledClass methods allSatisfy: [:m | m category beginsWith: 'generated']) ifTrue: [
+        compiledClass removeFromSystem.
+        compiledClass := nil.
+        ^ self
+    ].
+
+
     ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[
         compiledClass methodsDo: [ :mthd |
             (mthd category beginsWith: 'generated') ifTrue:[
@@ -81,10 +91,17 @@
             ]
         ]
     ] ifFalse: [ 
+"		compiledClass methodsDo: [ :mthd |
+            (mthd category beginsWith: 'generated') ifTrue:[
+                compiledClass removeSelector: mthd selector.
+            ]
+        ]
+"
+"		Too slow, but more stable :("
         (compiledClass allProtocolsUpTo: compiledClass) do: [ :protocol |
             (protocol beginsWith: 'generated') ifTrue: [ 
                 compiledClass removeProtocol: protocol.
-            ]
+            ]		
         ]
     ]
 ! !
--- a/compiler/PPCCodeBlock.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCCodeBlock.st	Mon Aug 17 12:56:02 2015 +0100
@@ -38,16 +38,9 @@
 !PPCCodeBlock methodsFor:'code generation'!
 
 code: aStringOrBlockOrRBParseNode
-    aStringOrBlockOrRBParseNode isString ifTrue:[ 
-        self emitCodeAsString: aStringOrBlockOrRBParseNode
-    ] ifFalse:[
-        (aStringOrBlockOrRBParseNode isKindOf: RBProgramNode) ifTrue:[ 
-            self emitCodeAsRBNode: aStringOrBlockOrRBParseNode.
-        ] ifFalse:[  
-            self emitCodeAsBlock: aStringOrBlockOrRBParseNode
-        ].
-    ].
-
+    self codeNl.
+    self codeOnLine: aStringOrBlockOrRBParseNode
+    
     "Created: / 01-06-2015 / 21:07:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified: / 03-06-2015 / 05:52:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
@@ -66,6 +59,22 @@
     ].
 
     "Created: / 01-06-2015 / 22:58:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+codeNl
+    self add: ''.
+!
+
+codeOnLine: aStringOrBlockOrRBParseNode
+    aStringOrBlockOrRBParseNode isString ifTrue:[ 
+        self emitCodeAsString: aStringOrBlockOrRBParseNode
+    ] ifFalse:[
+        (aStringOrBlockOrRBParseNode isKindOf: RBProgramNode) ifTrue:[ 
+            self emitCodeAsRBNode: aStringOrBlockOrRBParseNode.
+        ] ifFalse:[  
+            self emitCodeAsBlock: aStringOrBlockOrRBParseNode
+        ].
+    ].
 ! !
 
 !PPCCodeBlock methodsFor:'code generation - variables'!
@@ -178,7 +187,7 @@
 !
 
 emitCodeAsString: aString
-    buffer nextPutAll: aString
+    self addOnLine: aString
 !
 
 formatRBNode: anRBNode
--- a/compiler/PPCCodeGen.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCCodeGen.st	Mon Aug 17 12:56:02 2015 +0100
@@ -4,7 +4,7 @@
 
 Object subclass:#PPCCodeGen
 	instanceVariableNames:'compilerStack compiledParser methodCache currentMethod constants
-		returnVariable arguments idCache'
+		returnVariable arguments idGen'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-Compiler-Codegen'
@@ -52,8 +52,16 @@
     ^ currentMethod returnVariable 
 !
 
+idGen
+    ^ idGen
+!
+
+idGen: anObject
+    idGen := anObject
+!
+
 ids
-    ^ idCache keys
+    ^ idGen ids
 !
 
 methodCategory
@@ -144,6 +152,10 @@
     "Created: / 01-06-2015 / 23:49:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+codeAssert: aCode
+    self add: 'self assert: (', aCode, ').'.
+!
+
 codeAssign: code to: variable
     self assert: variable isNil not.
     
@@ -164,6 +176,7 @@
     method := [
             aBlock value
         ] ensure:[ returnVariable := tmpVarirable ].
+    self assert: (method isKindOf: PPCMethod).	
     method isInline ifTrue:[
         self callOnLine:method
     ] ifFalse:[
@@ -179,6 +192,11 @@
     "Created: / 01-06-2015 / 22:35:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+codeCall: aMethod
+    self assert: (aMethod isKindOf: PPCMethod).
+    self add: aMethod call.
+!
+
 codeClearError
     self add: 'self clearError.'.
 !
@@ -212,9 +230,9 @@
     (variable == #whatever) ifFalse: [ 
         "Do not assign, if somebody does not care!!"
         self add: variable, ' ', selector,' ', argument.
- 		] ifTrue: [ 
+ 	] ifTrue: [ 
         "In case argument has a side effect"
- 				self add: argument	
+ 		self add: argument	
     ]
 !
 
@@ -227,7 +245,7 @@
         self add: variable ,' := ', argument.
     ] ifTrue: [ 
         "In case an argument has a side effect"
- 		self add: argument.	
+        self add: argument.	
     ]
 !
 
@@ -254,16 +272,16 @@
 codeIf: condition then: then else: else
     currentMethod 
         add: '(';
-        code: condition;
+        codeOnLine: condition;
         addOnLine: ')'.
     then notNil ifTrue:[ 
         currentMethod 
-            addOnLine:' ifTrue:';
+            addOnLine:' ifTrue: ';
             codeBlock: then.
     ].
     else notNil ifTrue:[ 
         currentMethod 
-            addOnLine:' ifFalse:';
+            addOnLine:' ifFalse: ';
             codeBlock: else.
     ].
     self codeDot.
@@ -291,6 +309,27 @@
     "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+codeOnLIne:aStringOrBlockOrRBParseNode
+    currentMethod codeOnLine: aStringOrBlockOrRBParseNode
+
+    "Created: / 01-06-2015 / 23:49:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+codeParsedValueOf: aBlock 
+    | tmpVarirable  method |
+
+    self assert: aBlock isBlock.	
+    tmpVarirable := returnVariable.
+    returnVariable := #whatever.
+    method := [
+        aBlock value
+    ] ensure:[ returnVariable := tmpVarirable ].
+    self assert: returnVariable == tmpVarirable.
+    self assert: (method isKindOf: PPCMethod).
+    
+    self codeCall: method.
+!
+
 codeProfileStart
     self add: 'context methodInvoked: #', currentMethod methodName, '.'
 
@@ -305,16 +344,16 @@
 
 codeReturn
    currentMethod isInline ifTrue: [
-		"If inlined, the return variable already holds the value"
-	] ifFalse: [
-		arguments profile ifTrue:[ 
-			self codeProfileStop.
-		]. 
-		self add: '^ ', currentMethod returnVariable  
-	].
+				"If inlined, the return variable already holds the value"
+		] ifFalse: [
+				arguments profile ifTrue:[ 
+						self codeProfileStop.
+				]. 
+				self add: '^ ', currentMethod returnVariable  
+		].
 
-	"Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-	"Modified: / 01-06-2015 / 21:49:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+		"Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+		"Modified: / 01-06-2015 / 21:49:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 codeReturn: code
@@ -333,6 +372,25 @@
     "Modified: / 01-06-2015 / 21:48:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+codeReturnParsedValueOf: aBlock 
+    | tmpVarirable  method |
+
+    self assert:aBlock isBlock.	
+    tmpVarirable := returnVariable.
+    method := aBlock value. 
+    self assert: returnVariable == tmpVarirable.
+    self assert: (method isKindOf: PPCMethod).
+    method isInline ifTrue:[
+        self callOnLine:method.
+        self codeReturn: returnVariable.
+    ] ifFalse:[
+        self codeReturn: method call.
+        
+    ]
+
+    "Created: / 23-04-2015 / 18:21:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 codeStoreValueOf: aBlock intoVariable: aString
     | tmpVarirable method |
     self assert: aBlock isBlock.
@@ -394,9 +452,12 @@
     "Modified: / 10-05-2015 / 07:29:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-idFor: object
-    self assert: (object canHavePPCId).
-    ^ self idFor: object prefixed: object prefix suffixed: object suffix
+idFor: anObject
+    ^ idGen idFor: anObject
+!
+
+idFor: anObject defaultName: defaultName
+    ^ idGen idFor: anObject defaultName: defaultName
 !
 
 idFor: object prefixed: prefix
@@ -404,14 +465,16 @@
 !
 
 idFor: object prefixed: prefix suffixed: suffix
+    self error: 'Should no longer be used'.
+    "
     | name id |
     ^ idCache at: object ifAbsentPut: [ 
         ((object canHavePPCId) and: [object name isNotNil]) ifTrue: [ 
-            "Do not use prefix, if there is a name"
+            ""Do not use prefix, if there is a name""
             name := self asSelector: (object name asString).
             id := (name, suffix) asSymbol.
             
-            "Make sure, that the generated ID is uniqe!!"
+            ""Make sure, that the generated ID is uniqe!!""
             (idCache includes: id) ifTrue: [ 
                 (id, '_', idCache size asString) asSymbol 
             ] ifFalse: [ 
@@ -421,11 +484,18 @@
             (prefix, '_', (idCache size asString), suffix) asSymbol
         ]
     ]
+    "
+
+    "Modified: / 17-08-2015 / 12:00:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 idFor: object suffixed: suffix
     self assert: (object isKindOf: PPCNode) description: 'Shold use PPCNode for ids'.
     ^ self idFor: object prefixed: object prefix suffixed: suffix effect: #none
+!
+
+numberIdFor: object
+    ^ idGen numericIdFor: object
 ! !
 
 !PPCCodeGen methodsFor:'initialization'!
@@ -441,7 +511,7 @@
     compilerStack := Stack new.
     methodCache := IdentityDictionary new.
     constants := Dictionary new.
-    idCache := IdentityDictionary new.
+    idGen := PPCIdGenerator new.
 ! !
 
 !PPCCodeGen methodsFor:'profiling'!
@@ -468,8 +538,7 @@
 
 checkCache: id
     | method  |
-    
-    "self halt: 'deprecated?'."
+    self flag: 'deprecated?'.
     
     "Check if method is hand written"
     method := compiledParser ifNotNil: [ compiledParser compiledMethodAt: id ifAbsent: [ nil ] ].
@@ -535,7 +604,6 @@
 
 stopMethod
    self cache: currentMethod methodName as: currentMethod.
-	
 	"arguments profile ifTrue: [ Transcript show: currentMethod code; cr. ]."
 	^ self pop.
 
--- a/compiler/PPCCodeGenerator.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCCodeGenerator.st	Mon Aug 17 12:56:02 2015 +0100
@@ -131,7 +131,7 @@
         compiler addOnLine: '].'.
     ]."
     
-    guard id: (compiler idFor: guard prefixed: #guard).
+    guard id: (compiler idFor: guard defaultName: #guard).
     guard compileGuard: compiler.
 
     trueBlock isNil ifFalse: [ 
@@ -263,7 +263,7 @@
     | classificationId  classification |
     self error: 'deprecated.'.
     classification := node extendClassification: node predicate classification.
-    classificationId := (compiler idFor: classification prefixed: #classification).
+    classificationId := (compiler idFor: classification defaultName: #classification).
     compiler  addConstant: classification as: classificationId.
     
     compiler addOnLine: '(', classificationId, ' at: context peek asInteger)'.
@@ -304,11 +304,11 @@
 startMethodForNode:node
     node isMarkedForInline ifTrue:[ 
         compiler startInline: (compiler idFor: node).
-        compiler addComment: 'BEGIN inlined code of ' , node printString.
+        compiler codeComment: 'BEGIN inlined code of ' , node printString.
         compiler indent.
     ] ifFalse:[ 
         compiler startMethod: (compiler idFor: node).
-        compiler addComment: 'GENERATED by ' , node printString.
+        compiler codeComment: 'GENERATED by ' , node printString.
         compiler allocateReturnVariable.
     ].
 
@@ -473,7 +473,7 @@
 
     | classification classificationId |
     classification := node extendClassification: node predicate classification.
-    classificationId := compiler idFor: classification prefixed: #classification.
+    classificationId := compiler idFor: classification defaultName: #classification.
     compiler addConstant: classification as: classificationId.
     
     compiler add: '(', classificationId, ' at: context peek asInteger)'.
@@ -491,7 +491,7 @@
     node character ppcPrintable ifTrue: [ 
         chid := node character storeString 
     ] ifFalse: [ 
-        chid := compiler idFor: node character prefixed: #char.
+        chid := compiler idFor: node character defaultName: #char.
         compiler addConstant: (Character value: node character asInteger) as: chid .
     ].
     
@@ -656,7 +656,7 @@
 visitNotCharSetPredicateNode: node
     | classificationId  classification |
     classification := node extendClassification: node predicate classification.
-    classificationId := (compiler idFor: classification prefixed: #classification).
+    classificationId := (compiler idFor: classification defaultName: #classification).
     compiler  addConstant: classification as: classificationId.
     
     compiler addOnLine: '(', classificationId, ' at: context peek asInteger)'.
@@ -674,7 +674,7 @@
     node character ppcPrintable ifTrue: [ 
         chid := node character storeString 
     ] ifFalse: [ 
-        chid := compiler idFor: node character prefixed: #char.
+        chid := compiler idFor: node character defaultName: #char.
         compiler addConstant: (Character value: node character asInteger) as: chid .
     ].
     
@@ -747,7 +747,7 @@
 
 visitPluggableNode: node
     | blockId |
-    blockId := compiler idFor: node block prefixed: #block.
+    blockId := compiler idFor: node block defaultName: #pluggableBlock.
     
     compiler addConstant: node block as: blockId.
     compiler codeReturn: blockId, ' value: context.'.
@@ -793,7 +793,7 @@
 
 visitPredicateNode: node
     | pid |
-    pid := (compiler idFor: node predicate prefixed: #predicate).
+    pid := (compiler idFor: node predicate defaultName: #predicate).
 
     compiler addConstant: node predicate as: pid.
 
@@ -884,7 +884,7 @@
     
 
     classification := node extendClassification: node predicate classification.
-    classificationId := compiler idFor: classification prefixed: #classification.
+    classificationId := compiler idFor: classification defaultName: #classification.
     compiler addConstant: classification as: classificationId.
     
     compiler codeAssign: 'OrderedCollection new.' to: self retvalVar.	
@@ -916,8 +916,15 @@
 
     self addGuard: node child ifTrue: nil ifFalse: [ compiler codeReturn: '#()' ].
 
-    compiler codeAssign: 'OrderedCollection new.' to: self retvalVar.
     compiler codeAssignParsedValueOf:[ self visit:node child ] to:elementVar.
+    compiler codeIf: 'error' 
+        then: [ 
+            compiler codeClearError.
+            compiler codeReturn: '#()'.
+        ] else: [
+            compiler codeAssign: 'OrderedCollection new.' to: self retvalVar.
+        ].
+
     compiler add: '[ error ] whileFalse: ['.
     compiler indent.
     compiler add: self retvalVar, ' add: ', elementVar, '.'.
--- a/compiler/PPCCompilationError.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCCompilationError.st	Mon Aug 17 12:56:02 2015 +0100
@@ -9,3 +9,15 @@
 	category:'PetitCompiler-Exceptions'
 !
 
+!PPCCompilationError class methodsFor:'error signalling'!
+
+signalWith: message
+    ^ self signal: message
+! !
+
+!PPCCompilationError methodsFor:'signaling'!
+
+signalWith: message
+    self signal: message
+! !
+
--- a/compiler/PPCCompiler.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCCompiler.st	Mon Aug 17 12:56:02 2015 +0100
@@ -141,6 +141,10 @@
     currentMethod addOnLine: anotherMethod call.
 !
 
+codeComment: string
+    currentMethod add: '"', string, '"'.
+!
+
 dedent
     currentMethod dedent
 !
@@ -244,9 +248,9 @@
     (variable == #whatever) ifFalse: [ 
         "Do not assign, if somebody does not care!!"
         self add: variable, ' ', selector,' ', argument.
- 		] ifTrue: [ 
+ 				] ifTrue: [ 
         "In case argument has a side effect"
- 				self add: argument	
+ 								self add: argument	
     ]
 !
 
@@ -259,7 +263,7 @@
         self add: variable ,' := ', argument.
     ] ifTrue: [ 
         "In case an argument has a side effect"
- 		self add: argument.	
+ 				self add: argument.	
     ]
 !
 
@@ -337,16 +341,16 @@
 
 codeReturn
    currentMethod isInline ifTrue: [
-		"If inlined, the return variable already holds the value"
-	] ifFalse: [
-		arguments profile ifTrue:[ 
-			self codeProfileStop.
-		]. 
-		self add: '^ ', currentMethod returnVariable  
-	].
+				"If inlined, the return variable already holds the value"
+		] ifFalse: [
+				arguments profile ifTrue:[ 
+						self codeProfileStop.
+				]. 
+				self add: '^ ', currentMethod returnVariable  
+		].
 
-	"Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-	"Modified: / 01-06-2015 / 21:49:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+		"Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+		"Modified: / 01-06-2015 / 21:49:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 codeReturn: code
@@ -565,11 +569,11 @@
 
 stopMethod
    self cache: currentMethod methodName as: currentMethod.
-	
-	"arguments profile ifTrue: [ Transcript show: currentMethod code; cr. ]."
-	^ self pop.
+		
+		"arguments profile ifTrue: [ Transcript show: currentMethod code; cr. ]."
+		^ self pop.
 
-	"Modified: / 01-06-2015 / 21:38:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+		"Modified: / 01-06-2015 / 21:38:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 top
--- a/compiler/PPCCompilerTokenErrorStrategy.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCCompilerTokenErrorStrategy.st	Mon Aug 17 12:56:02 2015 +0100
@@ -6,7 +6,7 @@
 	instanceVariableNames:'compiler'
 	classVariableNames:''
 	poolDictionaries:''
-	category:'PetitCompiler-Compiler'
+	category:'PetitCompiler-Compiler-Codegen-Straregies'
 !
 
 !PPCCompilerTokenErrorStrategy class methodsFor:'as yet unclassified'!
--- a/compiler/PPCCompilerTokenRememberStrategy.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCCompilerTokenRememberStrategy.st	Mon Aug 17 12:56:02 2015 +0100
@@ -6,7 +6,7 @@
 	instanceVariableNames:'compiler'
 	classVariableNames:''
 	poolDictionaries:''
-	category:'PetitCompiler-Compiler'
+	category:'PetitCompiler-Compiler-Codegen-Straregies'
 !
 
 !PPCCompilerTokenRememberStrategy class methodsFor:'instance creation'!
@@ -26,6 +26,7 @@
 !PPCCompilerTokenRememberStrategy methodsFor:'as yet unclassified'!
 
 smartRemember: parser to: variableName 
+    self error: 'deprecated?'.
     parser isContextFree ifTrue: [ 
         compiler 	codeAssign: 'context lwRemember.' 
                     to: variableName.
--- a/compiler/PPCCompilerTokenizingErrorStrategy.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCCompilerTokenizingErrorStrategy.st	Mon Aug 17 12:56:02 2015 +0100
@@ -6,7 +6,7 @@
 	instanceVariableNames:'compiler'
 	classVariableNames:''
 	poolDictionaries:''
-	category:'PetitCompiler-Compiler'
+	category:'PetitCompiler-Compiler-Codegen-Straregies'
 !
 
 !PPCCompilerTokenizingErrorStrategy class methodsFor:'as yet unclassified'!
--- a/compiler/PPCCompilerTokenizingRememberStrategy.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCCompilerTokenizingRememberStrategy.st	Mon Aug 17 12:56:02 2015 +0100
@@ -6,7 +6,7 @@
 	instanceVariableNames:'compiler'
 	classVariableNames:''
 	poolDictionaries:''
-	category:'PetitCompiler-Compiler'
+	category:'PetitCompiler-Compiler-Codegen-Straregies'
 !
 
 
@@ -27,27 +27,50 @@
 !PPCCompilerTokenizingRememberStrategy methodsFor:'as yet unclassified'!
 
 smartRemember: parser to: variableName 
+    compiler allocateTemporaryVariableNamed: '__position'.
+    compiler allocateTemporaryVariableNamed: '__tokenType'.
+    compiler allocateTemporaryVariableNamed: '__tokenValue'.
+
+    compiler codeAssign: 'context position.' to: '__position'.	
+    compiler codeAssign: 'currentTokenType.' to: '__tokenType'.	
+    compiler codeAssign: 'currentTokenValue.' to: '__tokenValue'.	
+
+false ifFalse: [ 
     parser isContextFree ifTrue: [ 
-        compiler codeAssign: '{ context lwRemember. currentTokenType . currentTokenValue }.' 
-"		compiler codeAssign: 'context lwRemember.' "
+"		compiler codeAssign: '{ context lwRemember. currentTokenType . currentTokenValue }.' "
+        compiler codeAssign: 'scanner position.' 
                     to: variableName.
     ] ifFalse: [ 
         compiler codeAssign: '{ context remember. currentTokenType . currentTokenValue }.'
                     to: variableName.
     ]
+]
 !
 
 smartRestore: parser from: mementoName
+    compiler add: 'context lwRestore: __position.'.
+    compiler codeAssign: '__tokenType.' to: 'currentTokenType'.
+    compiler codeAssign: '__tokenValue.' to: 'currentTokenValue'.
+
+
+false ifTrue: [ 
     parser isContextFree ifTrue: [ 
-        compiler add: 'context lwRestore: (', mementoName, ' at: 1).'.
-"		compiler add: 'context lwRestore: ', mementoName, '.'."
+"		compiler add: 'context lwRestore: (', mementoName, ' at: 1).'."
+        compiler add: 'context lwRestore: ', mementoName, '.'.
     ] ifFalse: [ 
         compiler add: 'context restore: (', mementoName, ' at: 1).'.
     ].
 
+    compiler codeAssign: 'nil.' to: 'currentTokenType'.
+"	
     compiler codeAssign: '(', mementoName, ' at: 2).' to: 'currentTokenType'.
     compiler codeAssign: '(', mementoName, ' at: 3).' to: 'currentTokenValue'.	
+"
+"	
+    compiler code: 'scanner backtrack.'.
+"
     
+]
 ! !
 
 !PPCCompilerTokenizingRememberStrategy class methodsFor:'documentation'!
--- a/compiler/PPCConfiguration.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCConfiguration.st	Mon Aug 17 12:56:02 2015 +0100
@@ -32,8 +32,8 @@
 !PPCConfiguration methodsFor:'accessing'!
 
 arguments
- 		arguments isNil ifTrue: [ arguments := self defaultArguments ].
-		^ arguments
+ 				arguments isNil ifTrue: [ arguments := self defaultArguments ].
+				^ arguments
 !
 
 arguments: args
@@ -41,7 +41,7 @@
 !
 
 defaultArguments
- 		^ PPCArguments default
+ 				^ PPCArguments default
 !
 
 input: whatever
@@ -98,7 +98,7 @@
 cacheFollowSetWithTokens
     "Creates a PPCNodes from a PPParser"
     | followSets |
-    followSets := ir firstSetsSuchThat: [:e | e isTerminal or: [ e isTokenNode ] ].
+    followSets := ir followSetsSuchThat: [:e | e isTerminal or: [ e isTokenNode ] ].
     ir allNodesDo: [ :node |
         node followSetWithTokens: (followSets at: node)
     ]
@@ -106,9 +106,17 @@
 
 !PPCConfiguration methodsFor:'compiling'!
 
+buildClass: compiler
+    self subclassResponsibility
+!
+
 compile: whatever
+    | time |
     self input: whatever.
-    self invokePhases.
+    
+    time := [ self invokePhases ] timeToRun asMilliSeconds.
+    self reportTime: time.
+    
     ^ ir
 !
 
@@ -130,8 +138,12 @@
 
 !PPCConfiguration methodsFor:'hooks'!
 
+codeCompiler
+    ^ PPCCodeGen on: arguments 
+!
+
 codeCompilerOn: args
-    ^ PPCCompiler on: args
+    ^ PPCCodeGen on: args
 !
 
 codeGeneratorVisitorOn: compiler
@@ -178,18 +190,18 @@
 !
 
 generate
-    | compiler rootMethod compiledParser |
+    |  compiler rootMethod compiledParser |
     arguments generate ifFalse: [ ^ self ].
     
-    compiler := self codeCompilerOn: arguments.
+    compiler := self codeCompiler.
     
     rootMethod := (self codeGeneratorVisitorOn: compiler)
         arguments: arguments;
         visit: ir.
     
-    compiler compileParser.
-    compiler compiledParser startSymbol: rootMethod methodName.
-    compiledParser := compiler compiledParser new.
+    compiledParser := self buildClass: compiler.
+    compiledParser startSymbol: rootMethod methodName.
+    compiledParser := compiledParser new.
     
     ir := compiledParser.
 !
@@ -234,3 +246,11 @@
     self remember: #ppcNodes
 ! !
 
+!PPCConfiguration methodsFor:'reporting'!
+
+reportTime: timeInMs
+    arguments profile ifTrue: [ 
+        Transcript show: 'Time to compile: ', timeInMs asString, ' ms'; cr.
+    ]
+! !
+
--- a/compiler/PPCDelegateNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCDelegateNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -17,6 +17,7 @@
 !
 
 child: whatever
+    self assert: (whatever == self) not.
     child := whatever 
 !
 
@@ -45,6 +46,7 @@
 !PPCDelegateNode methodsFor:'transformation'!
 
 replace: node with: anotherNode
+    self assert: (anotherNode == self) not.
     child == node ifTrue: [ child := anotherNode ]
 ! !
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PPCDistinctResultStrategy.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,47 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+PPCScannerResultStrategy subclass:#PPCDistinctResultStrategy
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-Scanner'
+!
+
+!PPCDistinctResultStrategy methodsFor:'as yet unclassified'!
+
+recordFailure: retval
+    ^ self recordFailure: retval offset: 0
+!
+
+recordFailure: retval offset: offset
+    offset == 0 ifTrue: [ 
+        codeGen codeRecordDistinctMatch: nil.
+        ^ self
+    ].
+    codeGen codeRecordDistinctMatch: nil offset: offset 
+!
+
+recordMatch: retval
+    ^ self recordMatch: retval offset: 0
+!
+
+recordMatch: retval offset: offset
+    offset == 0 ifTrue: [ 
+        codeGen codeRecordDistinctMatch: retval.
+        ^ self
+    ].
+
+    codeGen codeRecordDistinctMatch: retval offset: offset
+!
+
+reset
+    ^ codeGen code: 'self resetDistinct.'.
+!
+
+returnResult: state
+    codeGen codeNl.
+    codeGen codeReturnDistinct.	
+! !
+
--- a/compiler/PPCEndOfFileNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCEndOfFileNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -9,9 +9,26 @@
 	category:'PetitCompiler-Nodes'
 !
 
+PPCEndOfFileNode class instanceVariableNames:'Instance'
+
+"
+ No other class instance variables are inherited by this class.
+"
+!
+
+!PPCEndOfFileNode class methodsFor:'as yet unclassified'!
+
+instance
+    Instance isNil ifTrue: [
+        Instance := self new.
+    ].
+
+    ^ Instance
+! !
+
 !PPCEndOfFileNode methodsFor:'accessing'!
 
-prefix
+defaultName
     ^ #eof
 ! !
 
--- a/compiler/PPCEndOfInputNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCEndOfInputNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -9,13 +9,29 @@
 	category:'PetitCompiler-Nodes'
 !
 
-!PPCEndOfInputNode methodsFor:'as yet unclassified'!
+!PPCEndOfInputNode methodsFor:'accessing'!
+
+defaultName
+    ^ #endOfInput
+! !
+
+!PPCEndOfInputNode methodsFor:'analysis'!
+
+acceptsEpsilon
+    ^ false
+!
+
+acceptsEpsilonOpenSet: set
+    ^ false
+!
+
+firstCharSet
+    ^ PPCharSetPredicate on: [:e | true ] 
+! !
+
+!PPCEndOfInputNode methodsFor:'visiting'!
 
 accept: visitor
     ^ visitor visitEndOfInputNode: self
-!
-
-prefix
-    ^ #endOfInput
 ! !
 
--- a/compiler/PPCFSACodeGen.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCFSACodeGen.st	Mon Aug 17 12:56:02 2015 +0100
@@ -3,7 +3,7 @@
 "{ NameSpace: Smalltalk }"
 
 PPCCodeGen subclass:#PPCFSACodeGen
-	instanceVariableNames:'fsa backlinkStates'
+	instanceVariableNames:'fsa backlinkStates compiler'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-Scanner'
@@ -15,88 +15,86 @@
     ^ 'generated - scanning'
 ! !
 
-!PPCFSACodeGen methodsFor:'analysis'!
-
-beginOfRange: characterSet
-    characterSet withIndexDo: [ :e :index | 
-        e ifTrue: [ ^ index ]
-    ].
-    self error: 'should not happend'
-!
-
-endOfRange: characterSet
-    | change |
-    change := false.
-    characterSet withIndexDo: [ :e :index | 
-        e ifTrue: [ change := true ].
-        (e not and: [ change ]) ifTrue: [ ^ index - 1]
-    ].
-    ^ characterSet size
-!
-
-isLetter: characterSet
-    | changes previous |
-    changes := 0.
-    previous := false.
-    characterSet withIndexDo: [ :e :index |
-        (e == (Character codePoint: index) isLetter) ifFalse: [ ^ false ].
-    ].
-    ^ true
-!
-
-isSingleCharacter: characterSet
-    ^ (characterSet select: [ :e | e ]) size = 1
-!
-
-isSingleRange: characterSet
-    | changes previous |
-    changes := 0.
-    previous := false.
-    characterSet do: [ :e | 
-        (e == previous) ifFalse: [ changes := changes + 1 ].
-        previous := e.
-    ].
-    ^ changes < 3
-! !
-
 !PPCFSACodeGen methodsFor:'coding'!
 
 codeAbsoluteReturn: code
     self add: '^ ', code
 !
 
-codeAssertPeek: characterSet
-    | character id extendedCharacterSet |
+codeAssertPeek: t
+    |   id  |
+    self assert: (t isKindOf: PEGFsaTransition).
+
+    (t isPredicateTransition and: [t isEOF]) ifTrue: [ 
+        self addOnLine: 'currentChar isNil'.
+        ^ self
+    ].
+
     
-    (self isSingleCharacter: characterSet) ifTrue: [ 
-        character := self character: characterSet.
-        self addOnLine: 'self peek == ', character storeString.
+    (t isPredicateTransition) ifTrue: [ 
+        self addOnLine: t predicate asString, ' value: currentChar codePoint'.
+        ^ self
+    ].
+
+    (t isAny) ifTrue: [ 
+        self addOnLine: 'true'.
         ^ self
     ].
 
-    (self isLetter: characterSet) ifTrue: [ 
-        self addOnLine: 'self peek isLetter'.
+    
+    (t isSingleCharacter) ifTrue: [ 
+        self addOnLine: 'currentChar == ', t character storeString.
+        ^ self
+    ].
+
+    (t isNotSingleCharacter) ifTrue: [ 
+        self addOnLine: 'currentChar ~~ ', t notCharacter storeString.
         ^ self
     ].
 
-    (self isSingleRange: characterSet) ifTrue: [ 
+    (t isLetter) ifTrue: [ 
+        self addOnLine: 'currentChar isLetter'.
+        ^ self
+    ].
+
+    (t isWord) ifTrue: [ 
+        self addOnLine: 'currentChar isAlphaNumeric'.
+        ^ self
+    ].
+
+    (t isDigit) ifTrue: [ 
+        self addOnLine: 'currentChar isDigit'.
+        ^ self
+    ].
+
+    (t isSingleRange) ifTrue: [ 
         | begin end |
-        begin := self beginOfRange: characterSet.
-        end := self endOfRange: characterSet.
+        begin := t beginOfRange.
+        end := t endOfRange.
         self addOnLine: 'self peekBetween: ', begin asString, ' and: ', end asString.
         ^ self
     ].
 
-    extendedCharacterSet := (characterSet asOrderedCollection addLast: false; yourself) asArray.
-    id := self idFor: characterSet prefixed: 'characterSet'.
     
-    self addConstant: extendedCharacterSet as: id.
-    self addOnLine: id, ' at: self peek asInteger'.
+    id := idGen cachedSuchThat: [ :e | e = t characterSet ] 
+                    ifNone: [ self idFor: t characterSet defaultName: 'characterSet' ].
+    
+    self addConstant: t characterSet as: id.
+    self addOnLine: '(currentChar isNotNil) and: [',  id, ' at: currentChar codePoint ]'.
 !
 
-codeAssertPeek: characterSet ifTrue: block
+codeAssertPeek: transition ifFalse: falseBlock
+    self add: '('.
+    self codeAssertPeek: transition.
+    self addOnLine: ') ifFalse: [ '.
+    falseBlock value.
+    self addOnLine: ']'.
+    self codeDot.
+!
+
+codeAssertPeek: t ifTrue: block
     self addOnLine: '('.
-    self codeAssertPeek: characterSet.
+    self codeAssertPeek: t.
     self addOnLine: ') ifTrue: ['.
     self indent.
     self code: block.
@@ -104,18 +102,19 @@
     self add: ']'.
 !
 
-codeAssertPeek: characterSet orReturn: priority
+codeAssertPeek: transition orReturn: priority
+    self error: 'deprecated'.
     self add: '('.
-    self codeAssertPeek: characterSet.
+    self codeAssertPeek: transition.
     self addOnLine: ') ifFalse: [ '.
     self codeReturnResult: priority.
     self addOnLine: ']'.
     self codeDot.
 !
 
-codeAssertPeek: characterSet whileTrue: block
+codeAssertPeek: transition whileTrue: block
     self add: '['.
-    self codeAssertPeek: characterSet.
+    self codeAssertPeek: transition.
     self addOnLine: '] whileTrue: ['.
     self indent.
     self code: block.
@@ -162,8 +161,8 @@
     self add: '^ self returnPriority: ', priority asString, '.'
 !
 
-codeRecordMatch: state
-    self add: 'self recordMatch: ', state storeString, '.'
+codeRecordDistinctMatch: retval offset: value
+    self add: 'self recordDistinctMatch: ', retval storeString, ' offset: ', value storeString, '.'
 !
 
 codeRecordMatch: state priority: priority
@@ -191,21 +190,39 @@
     self indent.
 ! !
 
-!PPCFSACodeGen methodsFor:'helpers'!
+!PPCFSACodeGen methodsFor:'coding - results'!
+
+codeRecordDistinctMatch: retval
+    self add: 'self recordDistinctMatch: ', retval storeString, '.'
+!
+
+codeRecordFailure: index
+    self assert: index isInteger.
+    self add: 'self recordFailure: ', index asString, '.'
+!
 
-character: characterSet
-    self assert: (self isSingleCharacter: characterSet).
-    characterSet withIndexDo: [ :e :index | e ifTrue: [ ^ Character codePoint: index ] ].
-    
-    self error: 'should not happen'
+codeRecordMatch: retval
+    self add: 'self recordMatch: ', retval storeString, '.'
+!
+
+codeRecordMatch: retval offset: offset
+    self add: 'self recordMatch: ', retval storeString, ' offset: ', offset storeString, '.'
+!
+
+codeReturn
+    self addOnLine: '^ self'
+!
+
+codeReturnDistinct
+    self addOnLine: '^ self returnDistinct.'
 ! !
 
 !PPCFSACodeGen methodsFor:'intitialization'!
 
 initialize
     super initialize.
+    
+    compiler := PPCCodeGen new.
     backlinkStates := IdentityDictionary new.
-
-    "Modified: / 24-07-2015 / 15:03:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
--- a/compiler/PPCForwardNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCForwardNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,7 +11,12 @@
 
 !PPCForwardNode methodsFor:'accessing'!
 
-prefix
+child: node
+    "(node name asString beginsWith: 'symbol') ifTrue: [ self halt. ]."
+    ^ super child: node
+!
+
+defaultName
     ^ #fw
 ! !
 
--- a/compiler/PPCGuard.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCGuard.st	Mon Aug 17 12:56:02 2015 +0100
@@ -71,7 +71,7 @@
         (index > 32 and: [ index < 127 ]) ifTrue: [ 
             compiler add: '(context peek == ', (Character value: index) storeString, ')'
         ] ifFalse: [ 
-            id := compiler idFor: (Character value: index) prefixed: #character.
+            id := compiler idFor: (Character value: index) defaultName: #character.
             compiler addConstant: (Character value: index) as: id.
             compiler add: '(context peek = ', id, ')'.
      		] 
@@ -92,12 +92,12 @@
 !
 
 testMessage: selector
- 		classification keysAndValuesDo: [:index :element |
-				(element = ((Character value: index) perform: selector)) ifFalse: [ 
-						^ false 
-				]
-		].
-		^ true
+ 				classification keysAndValuesDo: [:index :element |
+								(element = ((Character value: index) perform: selector)) ifFalse: [ 
+												^ false 
+								]
+				].
+				^ true
 !
 
 testSingleCharacter
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PPCIdGenerator.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,145 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#PPCIdGenerator
+	instanceVariableNames:'idCache numericIdCache'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-Compiler-Codegen'
+!
+
+!PPCIdGenerator class methodsFor:'as yet unclassified'!
+
+new
+    ^ self basicNew initialize
+! !
+
+!PPCIdGenerator methodsFor:'accessing'!
+
+ids
+    ^ idCache keys
+!
+
+numericIdCache
+    ^ numericIdCache
+!
+
+numericIds
+    ^ numericIdCache keys
+! !
+
+!PPCIdGenerator methodsFor:'as yet unclassified'!
+
+asSelector: string
+    "e.g. '234znak 43 ) 2' asLegalSelector = #v234znak432"
+    
+    | toUse |
+
+    toUse := string select: [:char | char isAlphaNumeric or: [ char = $_ ] ].
+    (toUse isEmpty or: [ toUse first isLetter not ])
+        ifTrue: [ toUse := 'v', toUse ].
+    toUse first isUppercase ifFalse:[
+        toUse := toUse copy.
+        toUse at: 1 put: toUse first asLowercase
+    ].
+    ^toUse
+
+    "Modified: / 10-05-2015 / 07:29:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+cachedSuchThat: block ifNone: noneBlock
+    | key |
+    key := idCache keys detect: block ifNone: [ nil ].
+    key isNil ifTrue: [ ^ noneBlock value ].
+    
+    ^ idCache at: key
+!
+
+generateIdFor: object defaultName: defaultName prefix: prefix suffix: suffix  
+    | name count |
+    object canHavePPCId ifTrue: [ 
+        name := object hasName ifTrue: [ object name ] ifFalse: [ object defaultName ].
+        name := self asSelector: name asString.
+        
+        "JK: I am not sure, if prefix and suffix should be applied to the name or not..."
+        suffix isNil ifFalse: [ 
+            name := name, '_', suffix.		
+        ].
+    
+        prefix isNil ifFalse: [ 
+            name := prefix , '_', name.		
+        ].	
+        
+        "(idCache contains: [ :e | e = name ]) ifTrue: [  self error: 'Duplicit names?' ]."
+    ] ifFalse: [ 
+        name := defaultName.
+
+        prefix isNil ifFalse: [ 
+            name := prefix , '_', name.		
+        ].
+
+        suffix isNil ifFalse: [ 
+            name := name, '_', suffix.		
+        ].
+
+        name := self asSelector: name asString.
+        
+    ].
+
+    (idCache contains: [ :e | e = name ]) ifTrue: [  
+        count := 2. 
+        
+        [	| tmpName |	
+            tmpName := (name, '_', count asString).
+            idCache contains: [:e | e = tmpName ]
+        ] whileTrue: [ count := count + 1 ].
+
+        name := name, '_', count asString
+    ].
+    
+    ^ name asSymbol
+!
+
+idFor: object
+    self assert: object canHavePPCId.
+    ^ self idFor: object defaultName: object defaultName prefix: object prefix suffix: object suffix
+!
+
+idFor: object defaultName: defaultName
+    ^ self idFor: object defaultName: defaultName prefix: nil suffix: nil
+!
+
+idFor: object defaultName: defaultName prefix: prefix
+    ^ self idFor: object defaultName: defaultName prefix: prefix suffix: ''
+!
+
+idFor: object defaultName: defaultName prefix: prefix suffix: suffix
+    ^ idCache at: object ifAbsentPut: [ 
+        self generateIdFor: object defaultName: defaultName prefix: prefix suffix: suffix
+    ]
+!
+
+isCachedSuchThat: block
+    ^ idCache keys contains: block
+!
+
+isCachedSuchThat: block ifTrue: trueBlock ifFalse: falseBlock
+    ^ (idCache keys contains: block) ifTrue: [trueBlock value] ifFalse: [falseBlock value]
+!
+
+numericIdFor: object
+    self assert: object isSymbol.
+    ^ numericIdCache at: object ifAbsentPut: [ 
+        numericIdCache at: object put: (numericIdCache size) + 1
+    ]
+! !
+
+!PPCIdGenerator methodsFor:'initialization'!
+
+initialize
+    super initialize.
+    idCache := IdentityDictionary new.
+    numericIdCache := IdentityDictionary new.
+! !
+
--- a/compiler/PPCInlinedMethod.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCInlinedMethod.st	Mon Aug 17 12:56:02 2015 +0100
@@ -9,7 +9,6 @@
 	category:'PetitCompiler-Compiler-Codegen'
 !
 
-
 !PPCInlinedMethod methodsFor:'as yet unclassified'!
 
 call
@@ -18,6 +17,18 @@
     "Modified: / 24-07-2015 / 19:45:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+callOn: receiver
+    self error: 'are you sure you want to inline code from different receiver? If so, remove me!!'.
+    ^ self code
+!
+
+code
+    self error: 'deprecated?'.
+    ^ (String streamContents:[:s |" buffer codeOn:s "]) trimRight
+
+    "Modified (format): / 01-06-2015 / 21:44:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 isInline
     ^ true
 !
@@ -34,6 +45,12 @@
 
 !PPCInlinedMethod methodsFor:'code generation - variables'!
 
+allocateReturnVariable
+    self error: 'return variable must be assigned by the non-inlined method....'
+
+   "Created: / 23-04-2015 / 21:06:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 allocateReturnVariableNamed: name
     self error: 'return variable must be assigned by the non-inlined method....'
 
@@ -46,10 +63,3 @@
    "Created: / 23-04-2015 / 21:06:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
-!PPCInlinedMethod class methodsFor:'documentation'!
-
-version_HG
-
-    ^ '$Changeset: <not expanded> $'
-! !
-
--- a/compiler/PPCInliningVisitor.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCInliningVisitor.st	Mon Aug 17 12:56:02 2015 +0100
@@ -104,10 +104,13 @@
 !
 
 visitTokenConsumeNode: node
-    super visitTokenConsumeNode: node.
+    "super visitTokenConsumeNode: node."
+
     node name isNil ifTrue: [ 
-        self markForInline: node
+        self flag: 'temporarily disabled'.
+        "self markForInline: node"
     ].
+
     ^ node
 !
 
@@ -126,8 +129,12 @@
 !
 
 visitTokenizingParserNode: node
-    self visit: node tokenizer.
+    "skip tokens"
+    "skip whitespace"
+    "self visit: node whitespace."
+
     self visit: node parser.
+    
     ^ node
 ! !
 
--- a/compiler/PPCMethod.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCMethod.st	Mon Aug 17 12:56:02 2015 +0100
@@ -20,6 +20,15 @@
 
 !PPCMethod methodsFor:'accessing'!
 
+body
+    self error: 'Should no longer be used'.
+    "    
+    ^ buffer contents
+    "
+
+    "Modified: / 17-08-2015 / 11:58:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 bridge
     ^ PPCBridge on: self methodName.
 !
@@ -35,6 +44,15 @@
     category := value
 !
 
+code
+    ^ String streamContents: [ :s |
+        s nextPutAll: self methodName; cr.
+        source codeOn: s.    
+    ]
+
+    "Modified: / 01-06-2015 / 21:24:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 id: value
     selector := value
 !
@@ -55,6 +73,24 @@
     ^ selector
 !
 
+profile
+    self error: 'Should no longer be used'.
+    "    
+    ^ profile
+    "
+
+    "Modified: / 17-08-2015 / 11:58:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+profile: aBoolean
+    self error: 'Should no longer be used'.
+    "
+    profile := aBoolean 
+    "
+
+    "Modified: / 17-08-2015 / 11:58:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 source
     ^ source isString ifTrue:[ 
         source
@@ -92,16 +128,20 @@
     ^ 'self ', self methodName, '.'.
 !
 
+callOn: receiver
+    ^ receiver, ' ', self methodName.
+!
+
 profilingBegin
     self profile ifTrue: [ 
- 								^ '  context methodInvoked: #', selector, '.'	
+ 																^ '  context methodInvoked: #', selector, '.'	
     ].
     ^ ''
 !
 
 profilingEnd
     self profile ifTrue: [ 
- 								^ '  context methodFinished: #', selector, '.'	
+ 																^ '  context methodFinished: #', selector, '.'	
     ].
     ^ ''
 ! !
@@ -124,7 +164,7 @@
     [ 
         outerBlock addOnLine:'['.
         source := innerBlock.
-        self code: contents.
+        self codeOnLine: contents.
     ] ensure:[
         outerBlock 
             code: (String streamContents:[:s | innerBlock sourceOn:s]);
@@ -134,6 +174,13 @@
 
     "Created: / 01-06-2015 / 22:33:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified: / 03-06-2015 / 06:11:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+codeOnLine: aStringOrBlockOrRBParseNode
+    source codeOnLine: aStringOrBlockOrRBParseNode.
+
+    "Created: / 01-06-2015 / 22:31:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 01-06-2015 / 23:50:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !PPCMethod methodsFor:'code generation - indenting'!
@@ -159,6 +206,18 @@
 
 !PPCMethod methodsFor:'code generation - variables'!
 
+addVariable: name
+    self error: 'Should no longer be used'
+    "
+    (variables includes: name) ifTrue:[ 
+        self error:'Duplicate variable name, must rename'.
+    ].
+    variables add: name.
+    "
+
+    "Modified: / 17-08-2015 / 11:56:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 allocateReturnVariable
     
 	^ variableForReturn isNil ifTrue:[ 
@@ -208,6 +267,15 @@
 
     "Created: / 23-04-2015 / 18:23:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified: / 15-06-2015 / 18:14:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+variables
+    self error: 'Should no longer be used'.
+    "
+    ^ '  | ', (variables inject: '' into: [ :s :e | s, ' ', e]), ' |'
+    "
+
+    "Modified: / 17-08-2015 / 11:54:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !PPCMethod methodsFor:'initialization'!
--- a/compiler/PPCNegateNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCNegateNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,7 +11,7 @@
 
 !PPCNegateNode methodsFor:'accessing'!
 
-prefix
+defaultName
     ^ #negate
 ! !
 
--- a/compiler/PPCNilNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCNilNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -12,7 +12,7 @@
 
 !PPCNilNode methodsFor:'accessing'!
 
-prefix
+defaultName
     ^ #nil
 ! !
 
--- a/compiler/PPCNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -34,6 +34,10 @@
     ^ #()
 !
 
+defaultName
+    ^ 'node' 
+!
+
 firstFollowCache
     ^ self propertyAt: #firstFollowCache ifAbsentPut: [ IdentityDictionary new ]
 !
@@ -61,10 +65,14 @@
 !
 
 name: anObject
-    
+"	(anObject asString beginsWith: 'symbolLiteral') ifTrue: [ self halt. ]."
     name := anObject
 !
 
+nameOrEmptyString
+    ^ self hasName ifTrue: [ self name ] ifFalse: [ '' ]
+!
+
 parser
     ^ self propertyAt: #parser ifAbsent: [ nil ]
 !
@@ -74,11 +82,11 @@
 !
 
 prefix
-    ^ 'node' 
+    ^ nil
 !
 
 suffix
-    ^ self isMarkedForInline ifTrue: [ '_inlined' ] ifFalse: [ '' ]
+    ^ self isMarkedForInline ifTrue: [ 'inlined' ] ifFalse: [ nil ]
 !
 
 unmarkForGuard
@@ -242,12 +250,12 @@
         finite := self.
         infinite := anotherNode.
     ] ifFalse: [ 
- 								finite := anotherNode.
+ 		finite := anotherNode.
         infinite := self.	
     ].
         
     finite recognizedSentences do: [ :sentence |
-            (infinite parser matches: sentence) ifTrue: [ ^ true ].
+        (infinite parser matches: sentence) ifTrue: [ ^ true ].
     ].
     ^ false
     
@@ -529,6 +537,10 @@
     ^ true
 !
 
+hasName
+    ^ (name == nil) not
+!
+
 isMarkedForInline
     ^ self propertyAt: #inlined ifAbsent: [ false ].
 
@@ -558,7 +570,10 @@
 asFsa
     | visitor |
     visitor := PEGFsaGenerator new.
-    ^ visitor visit: self
+    ^ (visitor visit: self)
+        name: self name;
+        yourself
+    
 !
 
 replace: node with: anotherNode
--- a/compiler/PPCNodeVisitor.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCNodeVisitor.st	Mon Aug 17 12:56:02 2015 +0100
@@ -53,7 +53,8 @@
 
 close: node
     self assert: (self isOpen: node) description: 'should be opened first!!'.
-    
+    openSet size > 500 ifTrue: [ self error: 'This seems to be a bit too much, isnt it?' ].
+        
     openSet remove: node.
     closeSet add: node
 !
@@ -68,6 +69,7 @@
 
 open: node
     self assert: (self isOpen: node) not description: 'already opened!!'.
+    openSet size > 100 ifTrue: [ self error: 'This seems to be a bit too much, isnt it?' ].
     openSet add: node
 !
 
--- a/compiler/PPCNotCharacterNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCNotCharacterNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,7 +11,7 @@
 
 !PPCNotCharacterNode methodsFor:'accessing'!
 
-prefix
+defaultName
     ^ #notChar
 ! !
 
@@ -38,3 +38,17 @@
     ^ retval
 ! !
 
+!PPCNotCharacterNode methodsFor:'printing'!
+
+printNameOn: aStream
+    super printNameOn: aStream.
+
+    character = $" ifTrue: [ 
+        "this is hack to allow for printing '' in comments..."
+        aStream nextPutAll: ', '; nextPutAll: '$'''''.
+        ^ self
+    ].
+
+    aStream nextPutAll: ', not('; print: character; nextPutAll: ')'
+! !
+
--- a/compiler/PPCNotLiteralNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCNotLiteralNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,12 +11,12 @@
 
 !PPCNotLiteralNode methodsFor:'accessing'!
 
+defaultName
+    ^ #notLit
+!
+
 firstCharSet
     ^ PPCharSetPredicate on: [:e | true ]
-!
-
-prefix
-    ^ #notLit
 ! !
 
 !PPCNotLiteralNode methodsFor:'visiting'!
--- a/compiler/PPCNotNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCNotNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,7 +11,7 @@
 
 !PPCNotNode methodsFor:'accessing'!
 
-prefix
+defaultName
     ^ #not
 ! !
 
--- a/compiler/PPCOptionalNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCOptionalNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,7 +11,7 @@
 
 !PPCOptionalNode methodsFor:'accessing'!
 
-prefix
+defaultName
     ^ #opt
 ! !
 
--- a/compiler/PPCPluggableNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCPluggableNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -22,7 +22,7 @@
     block := anObject
 !
 
-prefix
+defaultName
     ^ #plug
 ! !
 
--- a/compiler/PPCPlusNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCPlusNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -18,16 +18,16 @@
 
 !PPCPlusNode methodsFor:'as yet unclassified'!
 
+defaultName
+    ^ #plus
+!
+
 followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet suchThat: aBlock
     | first |
     super followSets: aFollowDictionary firstSets:  aFirstDictionary into: aSet suchThat: aBlock.
     
     first := aFirstDictionary at: self.
     (aFollowDictionary at: child) addAll: (first reject: [:each | each isNullable])
-!
-
-prefix
-    ^ #plus
 ! !
 
 !PPCPlusNode methodsFor:'visiting'!
--- a/compiler/PPCProfilingContext.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCProfilingContext.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,6 +11,13 @@
 !
 
 
+!PPCProfilingContext methodsFor:'accessing'!
+
+position: value
+    self assert: value isInteger.
+    super position: value
+! !
+
 !PPCProfilingContext methodsFor:'gt'!
 
 gtReport: composite
--- a/compiler/PPCRecognizerComponentDetector.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCRecognizerComponentDetector.st	Mon Aug 17 12:56:02 2015 +0100
@@ -21,6 +21,11 @@
     ^ node
 !
 
+visitTokenConsumeNode: node
+    "Let the scanner handle this stuff"
+    ^ node
+!
+
 visitTokenNode: node
     | child newChild |
     
@@ -32,6 +37,30 @@
     ^ node
 !
 
+visitTokenWhitespaceNode: node
+    | child newChild |
+    self change.
+    child := node child.
+    newChild := self visitWithRecognizingComponentVisitor: child.
+    node replace: child with: newChild.
+    
+    ^ node
+!
+
+visitTokenizingParserNode: node
+    | newWhitespace |
+    self change.
+    newWhitespace := self visitWithRecognizingComponentVisitor: node whitespace.
+    node replace: node whitespace with: newWhitespace.
+
+    "Do not visit tokens, they will be handled by the scanner:"
+    "self visit: node tokens."
+    
+    self visitChild: node parser of: node.
+    
+    ^ node
+!
+
 visitTrimmingTokenNode: node
     | child newChild whitespace newWhitespace |
     
--- a/compiler/PPCRecognizerComponentVisitor.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCRecognizerComponentVisitor.st	Mon Aug 17 12:56:02 2015 +0100
@@ -39,7 +39,6 @@
 
 visitSequenceNode: node
     self visitChildren: node.
-
     self change.
     ^ PPCRecognizingSequenceNode new
         children: node children;
--- a/compiler/PPCRecognizingSequenceNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCRecognizingSequenceNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -12,7 +12,7 @@
 !PPCRecognizingSequenceNode methodsFor:'accessing'!
 
 suffix
-    ^ super suffix, '_fast'
+    ^ super suffix isNil ifTrue: [ 'fast' ] ifFalse: [ super suffix, '_fast' ]
 ! !
 
 !PPCRecognizingSequenceNode methodsFor:'visiting'!
--- a/compiler/PPCScanner.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCScanner.st	Mon Aug 17 12:56:02 2015 +0100
@@ -3,14 +3,35 @@
 "{ NameSpace: Smalltalk }"
 
 Object subclass:#PPCScanner
-	instanceVariableNames:'matches stream maxPriority currentChar'
+	instanceVariableNames:'match matchPosition matches tokens stream currentChar
+		maxSymbolNumber position'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-Scanner'
 !
 
+!PPCScanner class methodsFor:'as yet unclassified'!
+
+acceptsLoggingOfCompilation
+"	^ self == PPCScanner"
+    ^ true
+! !
+
 !PPCScanner methodsFor:'accessing'!
 
+maxSymbolNumber
+    ^ maxSymbolNumber
+!
+
+maxSymbolNumber: value
+    maxSymbolNumber := value
+!
+
+position
+    "returns the start position before the scan method..."
+    ^ position
+!
+
 stream
     ^ stream
 !
@@ -19,49 +40,185 @@
     stream := anObject
 ! !
 
-!PPCScanner methodsFor:'as yet unclassified'!
-
-recordMatch: match 
- 	^ self recordMatch: match priority: 0
-!
-
-recordMatch: match priority: currentPriority
-    (maxPriority < currentPriority) ifTrue: [ 
-        matches := IdentityDictionary new.
-        maxPriority := currentPriority.
-    ].
-         
-    (maxPriority == currentPriority) ifTrue: [ 
-     	matches at: match put: stream position
- 	].
-!
-
-return
-    ^ self returnPriority: SmallInteger minVal.
-!
-
-returnPriority: priority
-    (maxPriority < priority) ifTrue: [ 
-        ^ IdentityDictionary new
-    ].
-    ^ matches keysAndValuesRemove: [ :key :value | key class == PEGFsaFailure ]
-! !
-
 !PPCScanner methodsFor:'initialization'!
 
 initialize
     super initialize.
-    matches := IdentityDictionary new.	
-    maxPriority := SmallInteger minVal.
+    
+    maxSymbolNumber := self class classVarNamed: #MaxSymbolNumber.
+    tokens := self class classVarNamed: #Tokens.
+    
+    matches := Array new: maxSymbolNumber withAll: -2.
+    position := 0.
+!
+
+reset
+    matchPosition := nil. "This flag says that multimode run the last time"
+
+    position := stream position.
+"	matches := Array new: maxSymbolNumber."
+!
+
+reset: tokenList
+    "Method should not be used, it is here for debugging and testing purposes"
+    self error: 'deprecated'.
+    
+    matchPosition := nil. "This flag says that multimode run the last time"
+    
+    tokens := tokenList.
+    matches := Array new: tokens size.
+    
+!
+
+resetDistinct
+"	matches := IdentityDictionary new.	"
+    match := nil.
+    matchPosition := -1.						"this is a flag that the distnict mode was running"
+"	matches := nil."
+
+    position := stream position.
+    
+! !
+
+!PPCScanner methodsFor:'results'!
+
+backtrack
+    matchPosition := nil.
+    match := nil.
+    matches := Array new: maxSymbolNumber withAll: -2.
+    position := 0.
+!
+
+backtrackDistinct
+    matchPosition := nil.
+    match := nil.
+    position := 0.
+!
+
+backtracked
+    ^ position == 0
+!
+
+indexOf: symbol
+    (1 to: tokens size) do: [ :index | (tokens at: index) == symbol ifTrue: [^ index ] ]. 
+!
+
+match
+"	^ match isNil not."
+    ^ match isNotNil
+"	^ matchPosition isNil not"
+!
+
+match: symbolNumber
+"	matches isNil ifTrue: [ ^ false ]."
+    
+    "
+        The general idea here is optimization. I cannot initialize 
+        the matches before each token, it would be too expensive.
+    "
+    ^ (matches at: symbolNumber) > position
+!
+
+matchSymbol: symbol
+    matches isNil ifTrue: [ ^ false ].
+    (1 to: tokens size) do: [ :index | (tokens at: index) == symbol ifTrue: [
+        ^ (matches at: index) > position
+    ] ]. 
+!
+
+polyResult
+    | dictionary |
+    "TODO JK: refactor"	
+    self isSingleMatch ifFalse: [ 
+        dictionary := IdentityDictionary new.
+        (1 to: matches size) do: [ :index | 
+            (self match: index) ifTrue: [ 
+                dictionary 
+                    at: (tokens at: index)
+                    put: (matches at: index)
+            ]
+        ].
+        ^ dictionary
+    ].
+
+    dictionary := IdentityDictionary new.
+    match isNil ifFalse: [ 
+        dictionary at: match put: matchPosition.
+    ].
+
+    ^ dictionary
+!
+
+result
+    ^ match
+!
+
+resultPosition
+    ^ matchPosition
+!
+
+resultPosition: symbolNumber
+    ^ matches at: symbolNumber
+!
+
+resultPositionForSymbol: symbol
+    tokens isNil ifTrue: [ ^ false ].
+    (1 to: tokens size) do: [ :index | (tokens at: index) == symbol ifTrue: [
+        ^ matches at: index
+    ] ]. 
+! !
+
+!PPCScanner methodsFor:'results - distinct'!
+
+recordDistinctMatch: matchValue
+    match := matchValue.
+    matchPosition := stream position.
+!
+
+recordDistinctMatch: matchValue offset: offset
+    match := matchValue.
+    currentChar isNil ifFalse: [ 
+        matchPosition := stream position - offset.
+    ] ifTrue: [ 
+        matchPosition := stream position.
+    ]
+!
+
+returnDistinct
+    ^ match isNotNil
+! !
+
+!PPCScanner methodsFor:'results - universal'!
+
+recordFailure: index
+    matches at: index put: -1.
+!
+
+recordFailure: index offset: offset
+    matches at: index put: -1.
+!
+
+recordMatch: index
+ 	matches at: index put: stream position.
+!
+
+recordMatch: index offset: offset
+    currentChar isNil ifFalse: [ 
+        matches at: index put: stream position - offset.
+    ] ifTrue: [ 
+        matches at: index put: stream position.
+    ].
+ 
+!
+
+return
+    ^ matches
 ! !
 
 !PPCScanner methodsFor:'scanning'!
 
-consumeConditionally: character
-    (stream peek == character) ifTrue: [ stream next. ^ true ] ifFalse: [ ^ false ]
-!
-
 next
+    self error: 'deprecated?'.
     stream next
 !
 
@@ -71,10 +228,16 @@
 
 peekBetween: start and: stop
     (currentChar == nil) ifTrue: [ ^ false ].
-    ^ start <= currentChar codePoint and: [ currentChar codePoint <= stop ]
+    ^ (start <= currentChar codePoint) and: [ currentChar codePoint <= stop ]
 !
 
 step
     currentChar := stream next
 ! !
 
+!PPCScanner methodsFor:'testing'!
+
+isSingleMatch
+    ^ (matchPosition == nil) not
+! !
+
--- a/compiler/PPCScannerCodeGenerator.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCScannerCodeGenerator.st	Mon Aug 17 12:56:02 2015 +0100
@@ -4,7 +4,7 @@
 
 Object subclass:#PPCScannerCodeGenerator
 	instanceVariableNames:'codeGen fsa backlinkStates backlinkTransitions arguments openSet
-		joinPoints incommingTransitions methodCache id'
+		incommingTransitions methodCache id resultStrategy fsaCache'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-Scanner'
@@ -18,6 +18,14 @@
 
 arguments: anObject
     arguments := anObject
+!
+
+codeGen
+    ^ codeGen 
+!
+
+compiler
+    ^ self codeGen 
 ! !
 
 !PPCScannerCodeGenerator methodsFor:'analysis'!
@@ -31,16 +39,17 @@
     ].
 !
 
-analyzeJoinPoints
-    | joinTransitions |
-    joinTransitions := fsa joinTransitions.
-    joinTransitions := joinTransitions reject: [ :t | self isBacklinkDestination: t destination ].
-    joinPoints := IdentityDictionary new.
-    
-    joinTransitions do: [ :t |
-        (joinPoints at: t destination ifAbsentPut: [ IdentitySet new ]) add: t.
+analyzeDistinctRetvals
+    (fsa hasDistinctRetvals) ifTrue: [
+        resultStrategy := PPCDistinctResultStrategy new
+            codeGen: codeGen;
+            yourself
+    ] ifFalse: [ 
+        resultStrategy := PPCUniversalResultStrategy new
+            codeGen: codeGen;
+            tokens: fsa retvals asArray;
+            yourself
     ]
-    
 !
 
 analyzeTransitions
@@ -58,17 +67,6 @@
     ^ backlinkStates at: state ifAbsentPut: [ OrderedCollection new ] 
 !
 
-closedJoinPoints
-    | closed |
-    closed := IdentitySet new.
-    
-    joinPoints keysAndValuesDo: [ :key :value | 
-        value isEmpty ifTrue: [ closed add: key ].
-    ].
-
-    ^ closed
-!
-
 containsBacklink: state
     state transitions do: [ :t |
         (self isBacklink:  t) ifTrue: [ ^ true ]
@@ -93,37 +91,62 @@
     ^ (self backlinksTo: state)  isEmpty not
 !
 
-isJoinPoint: state
-    "Please note that joinPoints are removed as the compilaction proceeds"
-    ^ joinPoints keys includes: state
+startsSimpleLoop: state
+    |   |
+
+    "
+        This accepts more or less something like $a star
+        for now.. might extend later
+    "
+    ((self incommingTransitionsFor: state) size == 2) ifFalse: [ ^ false ].
+    ^ (state transitions select: [ :t | t destination == state ]) size == 1
+    
+! !
+
+!PPCScannerCodeGenerator methodsFor:'caching'!
+
+cache: anFsa method: method
+    fsaCache at: anFsa put: method
 !
 
-joinTransitionsTo: joinPoint "state"
-    ^ joinPoints at: joinPoint ifAbsent: [ #() ]
+cachedValueForIsomorphicFsa: anFsa
+    | key |
+    key := fsaCache keys detect: [ :e | e isIsomorphicTo: anFsa ].
+    ^ fsaCache at: key
+!
+
+isomorphicIsCached: anFsa
+    ^ fsaCache keys anySatisfy: [ :e | e isIsomorphicTo: anFsa ]
 ! !
 
 !PPCScannerCodeGenerator methodsFor:'code generation'!
 
 generate
+    | method |
     self assert: fsa isDeterministic.
     self assert: fsa isWithoutEpsilons.
     self assert: fsa checkConsistency.
 
+    (self isomorphicIsCached: fsa) ifTrue: [ 
+        ^ self cachedValueForIsomorphicFsa: fsa 
+    ].
 
     self analyzeBacklinks.
-    self analyzeJoinPoints.
     self analyzeTransitions.
+    self analyzeDistinctRetvals.
     
     openSet := IdentitySet new.
-    
     codeGen startMethod: (codeGen idFor: fsa).
     codeGen codeComment: (Character codePoint: 13) asString, fsa asString.
+    resultStrategy reset.
 
     self generateFor: fsa startState.
 
-    codeGen stopMethod.	
-        
-    ^ self compileScannerClass new
+    method := codeGen stopMethod.	
+    self cache: fsa method: method.
+    
+    ^ method.
+
 
 
 !
@@ -131,50 +154,66 @@
 generate: aPEGFsa
     fsa := aPEGFsa.
 
-    fsa compact.
+    self assert: fsa isDeterministic.
+    self assert: fsa isWithoutPriorities.
+    
+    fsa minimize.
     fsa checkSanity.
     
     ^ self generate
 !
 
+generateAndCompile
+    self generate.
+    ^ self compile
+!
+
+generateAndCompile: aPEGFsa
+    fsa := aPEGFsa.
+
+    fsa minimize.
+    fsa checkSanity.
+    
+    ^ self generateAndCompile
+!
+
 generateFinalFor: state
-    state isFinal ifFalse: [  ^ self ].
+    ^ self generateFinalFor: state offset: 0
+!
 
-    codeGen codeRecordMatch: state retval priority: state priority.
+generateFinalFor: state offset: offset
+    state retvalsAndInfosDo: [:retval :info |
+        info isFinal ifTrue: [ 
+            info isFsaFailure ifTrue: [ 
+                resultStrategy recordFailure: retval offset: offset
+            ] ifFalse: [ 
+                resultStrategy recordMatch: retval offset: offset
+            ]
+        ].
+    ]
 !
 
 generateFor: state
-"	(self isJoinPoint: state) ifTrue: [ 
-        ^ codeGen codeComment: 'join point generation postponed...'
-    ].
-"
     codeGen cachedValue: (codeGen idFor: state) ifPresent: [ :method | 
         "if state is already cached, it has multiple incomming links.
      	 In such a case, it is compiled as a method, thus return immediatelly"
         ^ codeGen codeAbsoluteReturn:  method call
     ].
 
-    self generateStartMethod: state.
-"	(self isBacklinkDestination: state) ifTrue: [ 
-        codeGen codeStartBlock.
+    (self startsSimpleLoop: state) ifTrue: [ 
+        ^ self generateSimpleLoopFor: state
     ].
-"
-    self generateFinalFor: state.
-    self generateNextFor: state.
-    self generateTransitionsFor: state.
-
-"	(self isBacklinkDestination: state) ifTrue: [ 
-        codeGen codeEndBlockWhileTrue.
-    ].
-"
-    self generateStopMethod: state.
+    
+    ^ self generateStandardFor: state
 !
 
 generateForSingleTransition: t from: state
     
     (self isJoinPoint: t destination) ifTrue: [ self removeJoinTransition: t ].
     
-    codeGen codeAssertPeek: (t characterSet) orReturn: state priority.
+    codeGen codeAssertPeek: t ifFalse: [ 
+        resultStrategy returnResult: state 
+    ].
 "	(self isBacklink: t) ifTrue: [ 
         codeGen add: 'true'
     ] ifFalse: [ 
@@ -184,20 +223,18 @@
     self generateFor: t destination
 !
 
-generateForTransition: t from: state	
-    (self isJoinPoint: t destination) ifTrue: [ self removeJoinTransition: t   ].
-    
+generateForTransition: t from: state		
 "	(self isBacklink: t) ifTrue: [ 
         codeGen codeAssertPeek: (t characterSet) ifTrue: [ 
             codeGen add: 'true'
         ]
     ] ifFalse: [ 
-        codeGen codeAssertPeek: (t characterSet) ifTrue: [
+        codeGen codeAssertPeek: (t characterSet) ifTrue: [.
             self generateFor: t destination.
         ].
     ].
 "
-    codeGen codeAssertPeek: (t characterSet) ifTrue: [
+    codeGen codeAssertPeek: t ifTrue: [
         self generateFor: t destination.
     ].
     codeGen codeIfFalse.
@@ -209,7 +246,33 @@
 !
 
 generateReturnFor: state
-    codeGen codeNlReturnResult: state priority.
+    codeGen codeNl.
+    resultStrategy returnResult: state.
+!
+
+generateSimpleLoopFor: state
+    | selfTransition |
+    selfTransition := state transitions detect: [ :t | t destination == state ].
+    
+    codeGen codeStartBlock.
+    codeGen codeNextChar.
+    codeGen codeNl.
+    codeGen codeAssertPeek: selfTransition.
+    codeGen codeEndBlockWhileTrue.
+
+    "Last transition did not passed the loop, therefore, we have to record succes with offset -1"
+    self generateFinalFor: state offset: 1.
+    self generateTransitions: (state transitions reject: [ :t | t == selfTransition  ]) for: state.
+    
+!
+
+generateStandardFor: state
+    self generateStartMethod: state.
+    self generateFinalFor: state.
+    self generateNextFor: state.
+    self generateTransitionsFor: state.
+
+    self generateStopMethod: state.
 !
 
 generateStartMethod: state
@@ -234,20 +297,19 @@
     codeGen codeComment: 'STOP - Generated from state: ', state asString.
 !
 
-generateTransitionsFor: state
-    (state transitions size = 0) ifTrue: [  
+generateTransitions: transitions for: state
+    (transitions size = 0) ifTrue: [  
         self generateReturnFor: state.
         ^ self	
     ].
 
-    (state transitions size = 1) ifTrue: [  
+"	(state transitions size = 1) ifTrue: [  
         self generateForSingleTransition: state transitions anyOne from: state.
         ^ self
-    ].
-
+    ]."
 
     codeGen codeNl.
-    state transitions do: [ :t |
+    transitions do: [ :t |
         self generateForTransition: t from: state
     ].
 
@@ -255,7 +317,7 @@
     self generateReturnFor: state.
     codeGen dedent.
     codeGen codeNl.
-    state transitions size timesRepeat: [ codeGen addOnLine: ']' ].
+    transitions size timesRepeat: [ codeGen addOnLine: ']' ].
     codeGen addOnLine: '.'.
     
 
@@ -268,12 +330,38 @@
         self generateFor: jp.
     ]
 "
+!
+
+generateTransitionsFor: state
+    ^ self generateTransitions: state transitions for: state
+!
+
+setMaxNumericId
+    codeGen addConstant: codeGen idGen numericIds size as: #MaxSymbolNumber 
+!
+
+setTokens
+    | tokens |
+    tokens := Array new: codeGen idGen numericIdCache size.
+    
+    codeGen idGen numericIdCache keysAndValuesDo: [ :key :value |
+        tokens at: value put: key
+    ].
+
+    codeGen addConstant: tokens as: #Tokens 
 ! !
 
 !PPCScannerCodeGenerator methodsFor:'compiling'!
 
+compile
+    ^ self compileScannerClass new
+!
+
 compileScannerClass
     | builder |
+    self setMaxNumericId.
+    self setTokens.
+    
     builder := PPCClassBuilder new.
     
     builder compiledClassName: arguments scannerName.
@@ -291,16 +379,6 @@
     
     codeGen := PPCFSACodeGen new.
     arguments := PPCArguments default.
+    fsaCache := IdentityDictionary new.
 ! !
 
-!PPCScannerCodeGenerator methodsFor:'support'!
-
-removeJoinPoint: state
-    self assert: (joinPoints at: state) size = 0.
-    joinPoints removeKey: state
-!
-
-removeJoinTransition: t
-    (self joinTransitionsTo: t destination) remove: t ifAbsent: [ self error: 'this should not happen' ].
-! !
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PPCScannerResultStrategy.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,21 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#PPCScannerResultStrategy
+	instanceVariableNames:'codeGen'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-Scanner'
+!
+
+!PPCScannerResultStrategy methodsFor:'accessing'!
+
+codeGen
+    ^ codeGen
+!
+
+codeGen: anObject
+    codeGen := anObject
+! !
+
--- a/compiler/PPCSequenceNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCSequenceNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -12,6 +12,10 @@
 
 !PPCSequenceNode methodsFor:'accessing'!
 
+defaultName
+    ^ #seq
+!
+
 preferredChildrenVariableNames
     "Return an array of preferred variable names of variables where to store
      particular child's result value."
@@ -50,10 +54,6 @@
     "Created: / 04-06-2015 / 23:09:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-prefix
-    ^ #seq
-!
-
 returnParsedObjectsAsCollection
     ^ self propertyAt: #returnParsedObjectsAsCollection ifAbsent:[ true ]
 
@@ -118,7 +118,7 @@
         child recognizedSentences do: [ :suffix |
             retval do: [ :prefix |
                 set add: prefix, suffix.
-         		]
+         				]
         ].
         retval := set.
     ].
--- a/compiler/PPCSpecializingVisitor.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCSpecializingVisitor.st	Mon Aug 17 12:56:02 2015 +0100
@@ -182,6 +182,17 @@
     ^ node
 !
 
+visitTokenConsumeNode: node
+    "Let the Scanner to handle this stuff"
+    ^ node
+!
+
+visitTokenizingParserNode: node
+    self visitChild: node whitespace of: node.
+    self visitChild: node parser of: node.
+    ^ node
+!
+
 visitTrimmingTokenNode: node
 
     self visitChildren: node.
--- a/compiler/PPCStarAnyNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCStarAnyNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,7 +11,7 @@
 
 !PPCStarAnyNode methodsFor:'as yet unclassified'!
 
-prefix
+defaultName
     ^ #starAny
 ! !
 
--- a/compiler/PPCStarCharSetPredicateNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCStarCharSetPredicateNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -28,10 +28,6 @@
 predicate: anObject
     
     predicate := anObject
-!
-
-prefix
-    ^ #starPredicate
 ! !
 
 !PPCStarCharSetPredicateNode methodsFor:'comparing'!
--- a/compiler/PPCStarMessagePredicateNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCStarMessagePredicateNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,6 +11,10 @@
 
 !PPCStarMessagePredicateNode methodsFor:'accessing'!
 
+defaultName
+    ^ #starPredicate
+!
+
 firstCharSet
     ^ PPCharSetPredicate on: [:char | char perform: message ] 	
 !
@@ -23,10 +27,6 @@
 message: anObject
     
     message := anObject
-!
-
-prefix
-    ^ #starPredicate
 ! !
 
 !PPCStarMessagePredicateNode methodsFor:'comparing'!
--- a/compiler/PPCStarNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCStarNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -19,7 +19,7 @@
     ^ true
 !
 
-prefix
+defaultName
     ^ #star
 ! !
 
--- a/compiler/PPCTokenCodeGenerator.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCTokenCodeGenerator.st	Mon Aug 17 12:56:02 2015 +0100
@@ -2,89 +2,281 @@
 
 "{ NameSpace: Smalltalk }"
 
-PPCCodeGenerator subclass:#PPCTokenCodeGenerator
-	instanceVariableNames:''
+PPCNodeVisitor subclass:#PPCTokenCodeGenerator
+	instanceVariableNames:'compiler scannerGenerator fsaCache'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-Visitors'
 !
 
+!PPCTokenCodeGenerator methodsFor:'accessing'!
 
-!PPCTokenCodeGenerator methodsFor:'as yet unclassified'!
+arguments: args
+    super arguments: args.
+    scannerGenerator arguments: args
+!
+
+compiler
+    ^ compiler
+!
+
+compiler: anObject
+    compiler := anObject.
+    
+    scannerGenerator compiler idGen: compiler idGen.
+! !
+
+!PPCTokenCodeGenerator methodsFor:'code support'!
+
+consumeWhitespace: node
+    self assert: node isTokenNode.
+
+    node isTrimmingTokenNode ifTrue: [ 
+        compiler code: 'self consumeWhitespace.'
+    ]
+!
 
-afterAccept: node retval: retval
-    | return |
-    return := super afterAccept: node retval: retval.
-    return category: 'generated - tokens'.
-    ^ return
+createTokenInsance: node id: idCode start: startVar end: endVar
+    compiler codeTranscriptShow: 'current token type: ', idCode.
+    compiler codeAssign: idCode, '.' to: 'currentTokenType'.
+    compiler codeAssign: node tokenClass asString, ' on: (context collection) 
+                                                            start: ', startVar, ' 
+                                                            stop: ', endVar, '
+                                                            value: nil.'
+               to: 'currentTokenValue'.
+!
+
+scan: node start: startVar end: endVar
+    node child hasName ifFalse: [ 
+        node child name: node name
+    ].
+
+    compiler codeAssign: 'context position + 1.' to: startVar.
+    compiler add: ((self generateScan: node child) callOn: 'scanner').
+!
+
+unorderedChoiceFromFollowSet: followSet
+    | followFsas  |
+    
+    ^ fsaCache at: followSet ifAbsentPut: [ 
+        followFsas := followSet collect: [ :followNode | 
+                (followNode asFsa) 
+                    name: (compiler idFor: followNode);
+                    retval: (compiler idFor: followNode); 
+                    yourself
+        ].
+        self unorderedChoiceFromFsas: followFsas.
+    ]
+     
 !
 
-fromTokenMode
-    compiler rememberStrategy: (PPCCompilerTokenizingRememberStrategy on: compiler).
-    compiler errorStrategy: (PPCCompilerTokenizingErrorStrategy on: compiler).
+unorderedChoiceFromFsas: fsas
+    | result startState |
+    result := PEGFsa new.
+    startState := PEGFsaState new.
+    
+    result addState: startState.
+    result startState: startState.
+
+    fsas do: [ :fsa | 
+        result adopt: fsa.
+        result addTransitionFrom: startState to: fsa startState.
+    ].
+
+    result determinizeStandard.
+    ^ result
+! !
+
+!PPCTokenCodeGenerator methodsFor:'compiling support'!
+
+compileScanner
+    ^ scannerGenerator compileScannerClass
+!
+
+retvalVar
+    ^ compiler currentReturnVariable
+!
+
+startMethodForNode:node
+    node isMarkedForInline ifTrue:[ 
+        compiler startInline: (compiler idFor: node).
+        compiler codeComment: 'BEGIN inlined code of ' , node printString.
+        compiler indent.
+    ] ifFalse:[ 
+        compiler startMethod: (compiler idFor: node).
+        compiler currentMethod category: 'generated - tokens'.
+        compiler codeComment: 'GENERATED by ' , node printString.
+        compiler allocateReturnVariable.
+    ]
 !
 
-toTokenMode
-    compiler rememberStrategy: (PPCCompilerTokenRememberStrategy on: compiler).	
-    compiler errorStrategy: (PPCCompilerTokenErrorStrategy on: compiler).
+stopMethodForNode:aPPCNode
+    ^ aPPCNode isMarkedForInline ifTrue:[ 
+                compiler dedent.
+                compiler add: '"END inlined code of ' , aPPCNode printString , '"'.
+                compiler stopInline.
+    ] ifFalse:[ 
+                compiler stopMethod
+    ].
+! !
+
+!PPCTokenCodeGenerator methodsFor:'initialization'!
+
+initialize
+    super initialize.
+    
+    scannerGenerator := PPCScannerCodeGenerator new.
+    scannerGenerator arguments: arguments.
+    
+    "for the given set of nodes, remember the unordered choice fsa
+        see `unorderedChoiceFromFollowSet:`
+    "
+    fsaCache := Dictionary new.
+! !
+
+!PPCTokenCodeGenerator methodsFor:'scanning'!
+
+generateNextScan: node
+    | epsilon followSet  anFsa |
+    followSet := node followSetWithTokens.
+    
+    epsilon := followSet anySatisfy: [ :e | e acceptsEpsilon ].
+    followSet := followSet reject: [ :e | e acceptsEpsilon ].
+    epsilon ifTrue: [ followSet add: PPCEndOfFileNode instance ].
+    
+    anFsa := self unorderedChoiceFromFollowSet: followSet.
+
+    anFsa name: 'nextToken_', (compiler idFor: node).
+    node nextFsa: anFsa.
+    ^ scannerGenerator generate: anFsa.
+!
+
+generateScan: node
+    | anFsa |
+    anFsa := node asFsa determinize.
+    anFsa name: (compiler idFor: node).
+    anFsa retval: (compiler idFor: node).
+    
+    ^ scannerGenerator generate: anFsa.
 ! !
 
 !PPCTokenCodeGenerator methodsFor:'visiting'!
 
-visitOptionalNode: node
-    compiler 
-          codeAssignParsedValueOf:[ self visit:node child ]
-          to:self retvalVar.
-    compiler codeAssign: 'false.' to: 'error'.
-    compiler codeReturn.
-!
+visitToken: tokenNode
+    |  id  startVar endVar  numberId |
+    self startMethodForNode: tokenNode.
 
-visitTokenNode: node
-    | id startVar endVar  |
     "Tokens cannot be inlined, 
         - their result is true/false
         - the return value is always stored in currentTokenValue
         - the current token type is always stored in currentTokenType
     "
-    self assert: node isMarkedForInline not.	
+    self assert: tokenNode isMarkedForInline not.
     
     startVar := compiler allocateTemporaryVariableNamed: 'start'.
-    endVar := compiler allocateTemporaryVariableNamed: 'end'.
-
-    id := compiler idFor: node.
-    self toTokenMode.
-
-    compiler add: 'currentTokenType isNil ifFalse: [ ^ currentTokenType == ', id storeString, '].'.	
+    endVar := compiler allocateTemporaryVariableNamed:  'end'.
+    
+    id := compiler idFor: tokenNode.
+    numberId := compiler numberIdFor: id.
+    
+    compiler add: 'currentTokenType isNil ifFalse: [ ^ currentTokenType == ', id storeString, '].'.
+    
+"	compiler codeComment: 'number for: ', id storeString, ' is: ', numberId storeString.
+    compiler codeIf: 'scanner match: ', numberId storeString then: [ 
+        compiler codeAssign: '(scanner resultPosition: ', numberId storeString, ').' to: endVar.
+        self createTokenInsance: tokenNode 
+                id: id storeString 
+                start: '(context position + 1)' 
+                end: endVar.
+        
+        compiler code: 'context position: ', endVar, '.'.
+        
+        self consumeWhitespace: tokenNode.
+        compiler codeReturn: 'true'.
+    ].
+    compiler codeIf: 'scanner backtracked not' then: [ 
+        compiler codeReturn: 'false'.
+    ].
+    compiler codeComment: 'No match, no fail, scanner does not know about this...'.	
+"
     compiler profileTokenRead: id.
     
-    node allNodes size > 2 ifTrue: [ 
-        self addGuard: node ifTrue: nil  ifFalse: [ compiler addOnLine: '^ false' ].
+"	self scan: tokenNode start: startVar end: endVar."
+    "	compiler add: 'self assert: scanner isSingleMatch.'."
+"	compiler codeIf: 'scanner match ' then: ["
+
+    tokenNode child hasName ifFalse: [ 
+        tokenNode child name: tokenNode name
     ].
 
+    compiler codeAssign: 'context position + 1.' to: startVar.
+    compiler codeIf: [ compiler code: ((self generateScan: tokenNode child) callOn: 'scanner') ] then: [ 
+        compiler add: 'context position: scanner resultPosition.'.
+        compiler codeAssign: 'context position.' to: endVar.	
+        self consumeWhitespace: tokenNode.
+        self createTokenInsance: tokenNode id: id storeString start: startVar end: endVar.
+        compiler codeReturn: 'true'.
+    ] else: [ 
+        compiler code: 'scanner backtrackDistinct.'.
+        compiler code: 'context position: ', startVar, ' - 1.'. 
+        compiler codeReturn: 'false'.
+    ].
     
-    compiler codeAssign: 'context position + 1.' to: startVar.
-    compiler codeAssignParsedValueOf:[ self visit:node child ] to:#whatever.
-    compiler add: 'error ifTrue: [ ^ error := false ].'.
+    ^ self stopMethodForNode: tokenNode
+!
 
-    compiler codeAssign: 'context position.' to: endVar.
+visitTokenConsumeNode: node
+    | id   nextScan |
+    self startMethodForNode: node.
+    id := (compiler idFor: node child).
+
+    compiler add: 'self ', id asString, ' ifTrue: ['.
+        compiler indent.
 
-    compiler codeTranscriptShow: 'current token type: ', id storeString.
-    compiler codeAssign: id storeString, '.' to: 'currentTokenType'.
-    compiler codeAssign: node tokenClass asString, ' on: (context collection) 
-                                                                start: ', startVar, '  
-                                                                stop: ', endVar, '
-                                                                value: nil.'
-                to: 'currentTokenValue := ', self retvalVar.
-    
+        nextScan := self generateNextScan: node.
+        
+        node nextFsa hasDistinctRetvals ifTrue: [ 
+            compiler codeAssign: 'currentTokenValue.' to: self retvalVar.
         
-    compiler codeClearError.
-    compiler add: '^ true'.
+            compiler add: (nextScan callOn: 'scanner'), '.'.
+            compiler codeIf: 'scanner match' then: [ 
+            compiler add: 'context position: scanner resultPosition.'.
+                self createTokenInsance: node child 
+                        id: 'scanner result' 
+                        start: 'scanner position + 1' 
+                        end: 'scanner resultPosition'.
+                self consumeWhitespace: node child.
+                compiler codeReturn.
+            ] else: [ 
+                compiler codeComment: 'Looks like there is an error on its way...'.
+                compiler code: 'context position: scanner position.'.
+                compiler codeAssign: 'nil.' to: 'currentTokenType'.
+                compiler codeReturn.
+            ]
 
-    self fromTokenMode.
+        ] ifFalse: [ 
+            compiler codeAssign: 'nil.' to: 'currentTokenType'.
+            compiler codeReturn: 'currentTokenValue'.
+        ].
+        compiler dedent.
+
+    "Token not found"
+    compiler add: '] ifFalse: ['.
+        compiler indent.
+        compiler codeError: id asString, ' expected'.
+        compiler dedent.
+    compiler add: '].'.
+
+    ^ self stopMethodForNode: node
+!
+
+visitTokenNode: node
+    ^ self visitToken: node
 !
 
 visitTrimmingTokenCharacterNode: node
     |  id     |
+    self startMethodForNode:node.
 
     "Tokens cannot be inlined, 
         - their result is true/false
@@ -94,89 +286,22 @@
     self assert: node isMarkedForInline not.
     
     id := compiler idFor: node.
-    self toTokenMode.
     
     compiler add: 'currentTokenType isNil ifFalse: [ ^ currentTokenType == ', id storeString, '].'.
     compiler profileTokenRead: id.
 
-    self addGuard: node ifTrue: nil ifFalse: [ compiler addOnLine: ' ^ false' ].
-
+    compiler add: '(context peek == ', node child character storeString, ') ifFalse: [ ^ false ].'.
     compiler add: 'context next.'.
 
-    compiler codeTranscriptShow: 'current token type: ', id storeString.
-    compiler codeAssign: id storeString, '.' to: 'currentTokenType'.
-    compiler codeAssign: node tokenClass asString, ' on: (context collection) 
-                                                            start: context position 
-                                                            stop: context position
-                                                            value: nil.'
-               to: 'currentTokenValue := ', self retvalVar.
+    self createTokenInsance: node id: id storeString  start: 'context position' end: 'context position'.
+    self consumeWhitespace: node.
     
-    compiler addComment: 'Consume Whitespace:'.
-    compiler 
-          codeAssignParsedValueOf:[ self visit:node whitespace ]
-          to:#whatever.
-    compiler nl.
-    
-    compiler add: '^ true'.
+    compiler codeReturn: 'true'.
 
-    self fromTokenMode.
+    ^ self stopMethodForNode: node
 !
 
 visitTrimmingTokenNode: node
-    |  id  startVar endVar  |
-
-    "Tokens cannot be inlined, 
-        - their result is true/false
-        - the return value is always stored in currentTokenValue
-        - the current token type is always stored in currentTokenType
-    "
-    self assert: node isMarkedForInline not.
-    
-    startVar := compiler allocateTemporaryVariableNamed: 'start'.
-    endVar := compiler allocateTemporaryVariableNamed:  'end'.
-    
-    id := compiler idFor: node.
-    self toTokenMode.
-    
-    compiler add: 'currentTokenType isNil ifFalse: [ ^ currentTokenType == ', id storeString, '].'.
-    compiler profileTokenRead: id.
-    
-    node allNodes size > 2 ifTrue: [ 
-        self addGuard: node ifTrue: nil  ifFalse: [ compiler addOnLine: '^ false' ].
-    ].
-
-    compiler codeAssign: 'context position + 1.' to: startVar.
-    compiler codeAssignParsedValueOf:[ self visit:node child ] to:#whatever.
-
-    compiler add: 'error ifTrue: [ ^ error := false ].'.
-
-        compiler codeAssign: 'context position.' to: endVar.
-    
-        compiler addComment: 'Consume Whitespace:'.
-        compiler 
-              codeAssignParsedValueOf:[ self visit:node whitespace ]
-              to:#whatever.
-        compiler nl.
-    
-    
-        compiler codeTranscriptShow: 'current token type: ', id storeString.
-        compiler codeAssign: id storeString, '.' to: 'currentTokenType'.
-        compiler codeAssign: node tokenClass asString, ' on: (context collection) 
-                                                                start: ', startVar, ' 
-                                                                stop: ', endVar, '
-                                                                value: nil.'
-                   to: 'currentTokenValue := ', self retvalVar.
-
-    compiler codeClearError.
-    compiler add: '^ true'.
-
-    self fromTokenMode.
+    ^ self visitToken: node
 ! !
 
-!PPCTokenCodeGenerator class methodsFor:'documentation'!
-
-version_HG
-
-    ^ '$Changeset: <not expanded> $'
-! !
-
--- a/compiler/PPCTokenConsumeNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCTokenConsumeNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -15,10 +15,31 @@
     super name: value.
     
     self child name isNil ifTrue: [ 
-        self child name: self child prefix, '_', value.
+        self child name: value.
     ]
 !
 
+nextFsa
+    ^ self propertyAt: #nextFsa
+!
+
+nextFsa: aPEGFsa
+    self propertyAt: #nextFsa put: aPEGFsa
+! !
+
+!PPCTokenConsumeNode methodsFor:'as yet unclassified'!
+
+markForInline
+    self error: 'current infrastructure does not allow for this!!'.
+    ^ super markForInline
+! !
+
+!PPCTokenConsumeNode methodsFor:'ids'!
+
+defaultName
+    ^ #token
+!
+
 prefix
     ^ #consume
 ! !
--- a/compiler/PPCTokenDetector.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCTokenDetector.st	Mon Aug 17 12:56:02 2015 +0100
@@ -43,7 +43,7 @@
 
 visitTrimNode: node
     self visitChildren: node.
-    
+
     (node child isKindOf: PPCTokenNode) ifTrue: [  
         self change.
         ^ PPCTrimmingTokenNode new
@@ -51,11 +51,13 @@
             child: node child child;
             tokenClass: node child tokenClass;
             whitespace: node trimmer;
+            parser: node parser;
             yourself
     ]. 
 
     (node child isKindOf: PPCTokenConsumeNode) ifTrue: [  
         self change.
+        self halt: 'JK: this can happen???'.
         ^ PPCTrimmingTokenNode new
             name: node name;
             child: node child;
--- a/compiler/PPCTokenNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCTokenNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,10 +11,6 @@
 
 !PPCTokenNode methodsFor:'accessing'!
 
-prefix
-    ^ #token
-!
-
 tokenClass
     
     ^ tokenClass
@@ -40,6 +36,12 @@
     ^ super hash bitXor: tokenClass hash
 ! !
 
+!PPCTokenNode methodsFor:'ids'!
+
+defaultName
+    ^ #token
+! !
+
 !PPCTokenNode methodsFor:'testing'!
 
 isTokenNode
--- a/compiler/PPCTokenVisitor.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCTokenVisitor.st	Mon Aug 17 12:56:02 2015 +0100
@@ -44,7 +44,7 @@
         ^ node child
     ].
 
- 		self change.
+ 	self change.
     ^ PPCForwardNode new
         child: node child;
         name: node name;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PPCTokenizingCodeGen.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,59 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+PPCCodeGen subclass:#PPCTokenizingCodeGen
+	instanceVariableNames:'rememberStrategy errorStrategy'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-Compiler-Codegen'
+!
+
+!PPCTokenizingCodeGen methodsFor:'code generation'!
+
+codeClearError
+    errorStrategy codeClearError
+!
+
+codeError
+    errorStrategy codeError
+!
+
+codeError: message
+    errorStrategy codeError: message.
+!
+
+smartRemember: parser to: variableName 
+    rememberStrategy smartRemember: parser to: variableName
+!
+
+smartRestore: parser from: mementoName
+    rememberStrategy smartRestore: parser from: mementoName
+! !
+
+!PPCTokenizingCodeGen methodsFor:'hooks'!
+
+errorStrategy
+    ^ errorStrategy ifNil: [ PPCCompilerTokenizingErrorStrategy on: self  ]
+!
+
+errorStrategy: whatever
+    errorStrategy := whatever 
+!
+
+rememberStrategy
+    ^ rememberStrategy ifNil: [ PPCCompilerTokenizingRememberStrategy on: self  ]
+!
+
+rememberStrategy: whatever
+    rememberStrategy := whatever 
+! !
+
+!PPCTokenizingCodeGen methodsFor:'initialization'!
+
+initialize
+    super initialize.
+    rememberStrategy := PPCCompilerTokenizingRememberStrategy on: self.
+    errorStrategy := PPCCompilerTokenizingErrorStrategy on: self.
+! !
+
--- a/compiler/PPCTokenizingCodeGenerator.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCTokenizingCodeGenerator.st	Mon Aug 17 12:56:02 2015 +0100
@@ -18,9 +18,12 @@
 !
 
 tokenGenerator
+    self error: 'deprecated'.
+    
     tokenGenerator isNil ifTrue: [ 
-        tokenGenerator := PPCTokenCodeGenerator on: compiler.
-        tokenGenerator arguments: arguments.
+        tokenGenerator := (PPCTokenCodeGenerator on: compiler)
+            arguments: arguments;
+            yourself.
     ].
     ^ tokenGenerator
 !
@@ -63,6 +66,12 @@
     ^ true
 ! !
 
+!PPCTokenizingCodeGenerator methodsFor:'scanner'!
+
+compileScanner
+    compiler addConstant: self tokenGenerator compileScanner as: #scannerClass.
+! !
+
 !PPCTokenizingCodeGenerator methodsFor:'visiting'!
 
 visitAndNode: node
@@ -95,10 +104,12 @@
 
         "TODO: JK: fix this in a proper way. Commented for now to make LRPParser cimpilable 
          with tokenizing"
-        "child acceptsEpsilon"false ifTrue: [  
+        child acceptsEpsilon "false" ifTrue: [  
             possibleError := false.
-            compiler codeAssignParsedValueOf:[ self visit:child ] to:self retvalVar.
-            compiler codeReturn
+            compiler codeIf: 'true' then: [ 
+                compiler codeAssignParsedValueOf:[ self visit:child ] to:self retvalVar.
+                compiler codeReturn
+            ].
         ] ifFalse: [
             child firstSetWithTokens do: [ :first |
                 "For each child, for each first compile this:"
@@ -186,30 +197,15 @@
 !
 
 visitTokenConsumeNode: node
-    | id |
-    id := (compiler idFor: node child).
-    compiler add: 'self ', id asString, ' ifTrue: ['.
-        compiler indent.
-        compiler codeAssign: 'nil.' to: 'currentTokenType'.
-        compiler codeReturn: 'currentTokenValue'.
-        compiler dedent.
-    compiler add: '] ifFalse: ['.
-    compiler indent.
-    compiler codeError: id asString, ' expected'.
-    compiler dedent.
-    compiler add: '].'.
-
-"
-    compiler codeReturn: 'self consume: ', (compiler idFor: node child) storeString, '.'
-"
+    "dont do anything here"
+    ^ node
 !
 
 visitTokenNode: node
-    self error: 'shoudl not happend!!'
+    self error: 'should not happen!!'
 !
 
 visitTokenizingParserNode: node
-    self visit: node tokenizer.
     self visit: node whitespace.
     
     compiler codeHaltIfShiftPressed.
@@ -219,8 +215,12 @@
     compiler codeReturn.
 !
 
+visitTrimmingTokenCharacterNode: node
+    self error: 'should not happen!!'
+!
+
 visitTrimmingTokenNode: node
-    self error: 'shoudl not happend!!'
+    self error: 'should not happen!!'
 ! !
 
 !PPCTokenizingCodeGenerator class methodsFor:'documentation'!
--- a/compiler/PPCTokenizingConfiguration.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCTokenizingConfiguration.st	Mon Aug 17 12:56:02 2015 +0100
@@ -3,7 +3,7 @@
 "{ NameSpace: Smalltalk }"
 
 PPCConfiguration subclass:#PPCTokenizingConfiguration
-	instanceVariableNames:''
+	instanceVariableNames:'codeGen'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-Core'
@@ -12,6 +12,18 @@
 
 !PPCTokenizingConfiguration methodsFor:'compiling'!
 
+buildClass: compiler
+    |  builder |
+    builder := PPCClassBuilder new.
+    
+    builder compiledClassName: arguments parserName.
+    builder compiledSuperclass: PPTokenizingCompiledParser.
+    builder methodDictionary: compiler methodDictionary.
+    builder constants: compiler constants.
+
+    ^ builder compileClass.	
+!
+
 invokePhases
     self toPPCIr.
     self createTokens.
@@ -26,11 +38,17 @@
     self merge.
     self check.	
     self cacheFirstFollow.
+    self generateScanner.		"Please note that codeGen is shared between these two phases"
     self generate.
 ! !
 
 !PPCTokenizingConfiguration methodsFor:'hooks'!
 
+codeCompiler
+    codeGen isNil ifTrue: [ codeGen := PPCTokenizingCodeGen on: arguments ].
+    ^ codeGen
+!
+
 codeCompilerOn: args
     ^ PPCTokenizingCompiler on: args
 !
@@ -48,6 +66,19 @@
     self remember: #LL1
 !
 
+generateScanner
+    | generator scanner |
+    generator :=  PPCTokenCodeGenerator new
+        compiler: self codeCompiler;
+        arguments: arguments;
+        yourself.
+
+    generator visit: ir.
+    
+    scanner := generator compileScanner.	
+    self codeCompiler addConstant: scanner as: #scannerClass.
+!
+
 tokenize
     "
         This will try transform the parser into the tokenizing parser
--- a/compiler/PPCTokenizingParserNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCTokenizingParserNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,6 +11,10 @@
 
 !PPCTokenizingParserNode methodsFor:'accessing'!
 
+defaultName
+    ^ #tokenizingParser
+!
+
 initialize
     super initialize.
     children := Array new: 3
@@ -24,10 +28,6 @@
     children at: 1 put: node
 !
 
-prefix
-    ^ #tokenizingParser
-!
-
 tokenizer
     ^ children at: 2
 !
@@ -36,12 +36,20 @@
     ^ children at: 2 put: node
 !
 
-whitespace
+tokens
     ^ children at: 3
 !
 
+tokens: anObject
+    children at: 3 put: anObject
+!
+
+whitespace
+    ^ children at: 2
+!
+
 whitespace: node
-    children at: 3 put: node
+    children at: 2 put: node
 ! !
 
 !PPCTokenizingParserNode methodsFor:'visiting'!
--- a/compiler/PPCTokenizingVisitor.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCTokenizingVisitor.st	Mon Aug 17 12:56:02 2015 +0100
@@ -14,41 +14,44 @@
 
 afterAccept: node retval: parserNode
     self isRoot ifTrue: [ 
-        | tokenizerNode whitespaceNode |
+        | tokensNode whitespaceNode |
         self change.
-        tokens addLast: self eofToken.
-        tokens do: [ :token | token unmarkForInline  ].
+"		tokens addLast: self eofToken."
+        tokens do: [ :token | token unmarkForInline ].
+        whitespaceNode := tokens detect: [ :e | e isTrimmingTokenNode ] ifNone: [ nil ].
+        whitespaceNode notNil ifTrue: [ 
+                whitespaceNode := whitespaceNode whitespace copy
+                    unmarkForInline;
+                    name: 'consumeWhitespace';
+                    yourself.
+                "whitespaceNode := PPCTokenWhitespaceNode new
+                    child: whitespaceNode;
+                    yourself"
+        ] ifFalse: [ 
+                whitespaceNode := PPCNilNode new
+                    name: 'consumeWhitespace';
+                    yourself 
+        ].
         
-        whitespaceNode := tokens detect: [ :e | e isTrimmingTokenNode ] ifNone:[nil]. 
-        whitespaceNode notNil ifTrue:[
-            whitespaceNode := whitespaceNode whitespace copy
-                                unmarkForInline;
-                                name: 'consumeWhitespace';
-                                yourself 
-        ] ifFalse:[
-            whitespaceNode := (PPCNilNode new)
-                                name: 'consumeWhitespace';
-                                yourself
-        ].        
-        tokenizerNode := PPCTokenChoiceNode new
+        tokensNode := PPCListNode new
             children: tokens asArray;
             name: 'nextToken';
             yourself.
-    
+            
         ^ PPCTokenizingParserNode new
             parser: parserNode;
-            tokenizer: tokenizerNode;
             whitespace: whitespaceNode;
-            name: #'mainParser';
-            yourself
-    ].
+            tokens: tokensNode;
+            name: #mainParser;
+            yourself ].
     ^ parserNode
-
+    
     "Modified: / 12-05-2015 / 01:37:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 eofToken
     | ws  |
+    self error: 'deprecated?'.
     ws := PPCStarNode new
         child: (PPCMessagePredicateNode new
             message: #isSeparator;
@@ -59,6 +62,7 @@
         child: PPCEndOfFileNode new;
         whitespace: ws;
         tokenClass: PPToken;
+        name: 'eof'
         yourself.
 ! !
 
@@ -87,6 +91,7 @@
 
 visitActionNode: node
     (node hasProperty: #trimmingToken) ifTrue: [ 
+        self halt: 'can this happen?'.
         self change.
         self addToken: node.
         
@@ -98,10 +103,21 @@
     ^ super visitActionNode: node
 !
 
+visitTokenConsumeNode: node
+    "
+        Seems, it might happen, that if I create the consume node, 
+        I will ge to it later. This would create a token consume node for the
+        child, thus having tokenConsumNode with tokenConsumNode as a child...
+    "
+    ^ node
+!
+
 visitTokenNode: node
     self change.
     self addToken: node.
     
+    self assert: node acceptsEpsilon not description: 'Sorry, but the epsilon tokens are not allowed'.
+    
     ^ PPCTokenConsumeNode new
         child: node;
         yourself.
@@ -113,6 +129,7 @@
     
     ^ PPCTokenConsumeNode new
         child: node;
+        name: node name;
         yourself.
 ! !
 
--- a/compiler/PPCTrimNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCTrimNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -21,7 +21,7 @@
     children at: 2 put: anObject
 !
 
-prefix
+defaultName
     ^ #trim
 !
 
@@ -53,6 +53,7 @@
     | message |
     message := PPCMessagePredicateNode new 
             message: #isSeparator;
+            predicate: [ :char | char isSeparator ]
             yourself.
     ^ PPCStarNode new
         child: message;
--- a/compiler/PPCTrimmingTokenNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCTrimmingTokenNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -21,10 +21,6 @@
     children at: 2 put: anObject
 !
 
-prefix
-    ^ #token
-!
-
 tokenClass
     
     ^ tokenClass
@@ -93,6 +89,12 @@
     ^ super hash bitXor: tokenClass hash
 ! !
 
+!PPCTrimmingTokenNode methodsFor:'ids'!
+
+defaultName
+    ^ #token
+! !
+
 !PPCTrimmingTokenNode methodsFor:'initialization'!
 
 initialize
--- a/compiler/PPCUniversalConfiguration.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCUniversalConfiguration.st	Mon Aug 17 12:56:02 2015 +0100
@@ -11,6 +11,18 @@
 
 !PPCUniversalConfiguration methodsFor:'compiling'!
 
+buildClass: compiler
+    |  builder |
+    builder := PPCClassBuilder new.
+    
+    builder compiledClassName: arguments parserName.
+    builder compiledSuperclass: PPCompiledParser.
+    builder methodDictionary: compiler methodDictionary.
+    builder constants: compiler constants.
+
+    ^ builder compileClass.	
+!
+
 invokePhases
     self toPPCIr.
     self createTokens.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PPCUniversalResultStrategy.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,62 @@
+"{ Package: 'stx:goodies/petitparser/compiler' }"
+
+"{ NameSpace: Smalltalk }"
+
+PPCScannerResultStrategy subclass:#PPCUniversalResultStrategy
+	instanceVariableNames:'tokens'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-Scanner'
+!
+
+!PPCUniversalResultStrategy methodsFor:'accessing'!
+
+indexForRetval: retval
+"	tokens withIndexDo: [ :e :index | 
+        (e == retval) ifTrue: [ ^ index ]
+    ].
+
+    self error: 'This should not happen!!'
+"
+    ^ codeGen idGen numericIdFor: retval
+!
+
+tokens
+    ^ tokens
+!
+
+tokens: array
+    self assert: (array isArray).
+    tokens := array 
+! !
+
+!PPCUniversalResultStrategy methodsFor:'as yet unclassified'!
+
+recordFailure: retval
+    codeGen codeRecordFailure: (self indexForRetval: retval)
+!
+
+recordFailure: retval offset: offset
+    codeGen codeRecordFailure: (self indexForRetval: retval)
+!
+
+recordMatch: retval
+    codeGen codeComment: 'symbol: ', retval storeString.
+    codeGen codeRecordMatch: (self indexForRetval: retval)
+!
+
+recordMatch: retval offset: offset
+    codeGen codeComment: 'symbol: ', retval storeString.
+    codeGen codeRecordMatch: (self indexForRetval: retval) offset: offset
+!
+
+reset
+"	^ codeGen code: 'self reset:', tokens storeString, '.'"
+    ^ codeGen code: 'self reset.'	
+!
+
+returnResult: state
+    self assert: (state isKindOf: PEGFsaState).
+    codeGen codeReturn.
+! !
+
--- a/compiler/PPCUnknownNode.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCUnknownNode.st	Mon Aug 17 12:56:02 2015 +0100
@@ -30,6 +30,10 @@
     ^ parser children
 !
 
+defaultName
+    ^ #parser
+!
+
 isContextFreePrim
     ^ parser isContextFreePrim
 !
@@ -46,10 +50,6 @@
 parser: anObject
     
     parser := anObject
-!
-
-prefix
-    ^ #parser
 ! !
 
 !PPCUnknownNode methodsFor:'analysis'!
--- a/compiler/PPCompiledParser.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCompiledParser.st	Mon Aug 17 12:56:02 2015 +0100
@@ -18,6 +18,10 @@
 
 !PPCompiledParser class methodsFor:'as yet unclassified'!
 
+acceptsLoggingOfCompilation
+    ^ true
+!
+
 addConstant: value as: id
     self constants at: id ifPresent: [ 
         ((self constants at: id) = value) ifFalse: [self error: 'ooups']].	
@@ -84,9 +88,10 @@
 initialize
     super initialize.
     
-    self class constants keysAndValuesDo: [ :key :value |
+"	self class constants keysAndValuesDo: [ :key :value |
         self instVarNamed: key put: value.
     ].
+"
 
     startSymbol := self class startSymbol.
 
--- a/compiler/PPTokenizingCompiledParser.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPTokenizingCompiledParser.st	Mon Aug 17 12:56:02 2015 +0100
@@ -9,6 +9,19 @@
 	category:'PetitCompiler-Parsers'
 !
 
+!PPTokenizingCompiledParser class methodsFor:'as yet unclassified'!
+
+acceptsLoggingOfCompilation
+    ^ self == PPTokenizingCompiledParser
+! !
+
+!PPTokenizingCompiledParser methodsFor:'initialization'!
+
+initialize
+    super initialize.
+    
+! !
+
 !PPTokenizingCompiledParser methodsFor:'tokenizing'!
 
 consume: tokenType
@@ -22,7 +35,7 @@
 !
 
 consumeWhitespace
-    self shouldBeImplemented 
+    "self shouldBeImplemented "
 !
 
 currentTokenType
@@ -57,7 +70,9 @@
     context noteFailure: failure.
     error := false.
     currentTokenType := nil.
-    scanner := PPCScanner new.
+    scanner := (self class classVarNamed: #scannerClass) new.
+    scanner stream: aPPContext.
+
 
     self consumeWhitespace.
     retval := self perform: startSymbol.
--- a/compiler/abbrev.stc	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/abbrev.stc	Mon Aug 17 12:56:02 2015 +0100
@@ -2,10 +2,14 @@
 # this file is needed for stc to be able to compile modules independently.
 # it provides information about a classes filename, category and especially namespace.
 PEGFsa PEGFsa stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
-PEGFsaFailure PEGFsaFailure stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
+PEGFsaAbstractDeterminizator PEGFsaAbstractDeterminizator stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
+PEGFsaFailure PEGFsaFailure stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 1
 PEGFsaInterpret PEGFsaInterpret stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
+PEGFsaInterpretRecord PEGFsaInterpretRecord stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
+PEGFsaMinimizator PEGFsaMinimizator stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
 PEGFsaPair PEGFsaPair stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
 PEGFsaState PEGFsaState stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
+PEGFsaStateInfo PEGFsaStateInfo stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
 PEGFsaTransition PEGFsaTransition stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
 PPCASTUtilities PPCASTUtilities stx:goodies/petitparser/compiler 'PetitCompiler-Support' 0
 PPCArguments PPCArguments stx:goodies/petitparser/compiler 'PetitCompiler-Core' 0
@@ -17,33 +21,43 @@
 PPCCompilationWarning PPCCompilationWarning stx:goodies/petitparser/compiler 'PetitCompiler-Exceptions' 1
 PPCCompiledMethod PPCCompiledMethod stx:goodies/petitparser/compiler 'PetitCompiler-Core' 0
 PPCCompiler PPCCompiler stx:goodies/petitparser/compiler 'PetitCompiler-Compiler' 0
-PPCCompilerTokenErrorStrategy PPCCompilerTokenErrorStrategy stx:goodies/petitparser/compiler 'PetitCompiler-Compiler' 0
-PPCCompilerTokenRememberStrategy PPCCompilerTokenRememberStrategy stx:goodies/petitparser/compiler 'PetitCompiler-Compiler' 0
-PPCCompilerTokenizingErrorStrategy PPCCompilerTokenizingErrorStrategy stx:goodies/petitparser/compiler 'PetitCompiler-Compiler' 0
-PPCCompilerTokenizingRememberStrategy PPCCompilerTokenizingRememberStrategy stx:goodies/petitparser/compiler 'PetitCompiler-Compiler' 0
+PPCCompilerTokenErrorStrategy PPCCompilerTokenErrorStrategy stx:goodies/petitparser/compiler 'PetitCompiler-Compiler-Codegen-Straregies' 0
+PPCCompilerTokenRememberStrategy PPCCompilerTokenRememberStrategy stx:goodies/petitparser/compiler 'PetitCompiler-Compiler-Codegen-Straregies' 0
+PPCCompilerTokenizingErrorStrategy PPCCompilerTokenizingErrorStrategy stx:goodies/petitparser/compiler 'PetitCompiler-Compiler-Codegen-Straregies' 0
+PPCCompilerTokenizingRememberStrategy PPCCompilerTokenizingRememberStrategy stx:goodies/petitparser/compiler 'PetitCompiler-Compiler-Codegen-Straregies' 0
 PPCConfiguration PPCConfiguration stx:goodies/petitparser/compiler 'PetitCompiler-Core' 0
 PPCContext PPCContext stx:goodies/petitparser/compiler 'PetitCompiler-Context' 0
 PPCContextMemento PPCContextMemento stx:goodies/petitparser/compiler 'PetitCompiler-Context' 0
 PPCGuard PPCGuard stx:goodies/petitparser/compiler 'PetitCompiler-Guards' 0
+PPCIdGenerator PPCIdGenerator stx:goodies/petitparser/compiler 'PetitCompiler-Compiler-Codegen' 0
 PPCMethod PPCMethod stx:goodies/petitparser/compiler 'PetitCompiler-Compiler-Codegen' 0
 PPCNode PPCNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
 PPCNodeVisitor PPCNodeVisitor stx:goodies/petitparser/compiler 'PetitCompiler-Visitors' 0
 PPCPluggableConfiguration PPCPluggableConfiguration stx:goodies/petitparser/compiler 'PetitCompiler-Core' 0
 PPCScanner PPCScanner stx:goodies/petitparser/compiler 'PetitCompiler-Scanner' 0
 PPCScannerCodeGenerator PPCScannerCodeGenerator stx:goodies/petitparser/compiler 'PetitCompiler-Scanner' 0
+PPCScannerResultStrategy PPCScannerResultStrategy stx:goodies/petitparser/compiler 'PetitCompiler-Scanner' 0
 PPCTokenGuard PPCTokenGuard stx:goodies/petitparser/compiler 'PetitCompiler-Guards' 0
 PPCompiledParser PPCompiledParser stx:goodies/petitparser/compiler 'PetitCompiler-Parsers' 4
 PPMappedActionParser PPMappedActionParser stx:goodies/petitparser/compiler 'PetitCompiler-Parsers' 0
 stx_goodies_petitparser_compiler stx_goodies_petitparser_compiler stx:goodies/petitparser/compiler '* Projects & Packages *' 3
 FooScanner FooScanner stx:goodies/petitparser/compiler 'PetitCompiler-Scanner' 0
+PEGFsaCharacterTransition PEGFsaCharacterTransition stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
+PEGFsaChoiceDeterminizator PEGFsaChoiceDeterminizator stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
+PEGFsaDeterminizator PEGFsaDeterminizator stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
+PEGFsaEpsilonTransition PEGFsaEpsilonTransition stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
 PEGFsaGenerator PEGFsaGenerator stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
+PEGFsaPredicateTransition PEGFsaPredicateTransition stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
+PEGFsaSequenceDeterminizator PEGFsaSequenceDeterminizator stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
+PEGFsaUncopiableState PEGFsaUncopiableState stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
 PPCAbstractLiteralNode PPCAbstractLiteralNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
 PPCAbstractPredicateNode PPCAbstractPredicateNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
 PPCAnyNode PPCAnyNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
 PPCCharacterNode PPCCharacterNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
 PPCCodeGenerator PPCCodeGenerator stx:goodies/petitparser/compiler 'PetitCompiler-Visitors' 0
 PPCDelegateNode PPCDelegateNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
-PPCEndOfFileNode PPCEndOfFileNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
+PPCDistinctResultStrategy PPCDistinctResultStrategy stx:goodies/petitparser/compiler 'PetitCompiler-Scanner' 0
+PPCEndOfFileNode PPCEndOfFileNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 1
 PPCFSACodeGen PPCFSACodeGen stx:goodies/petitparser/compiler 'PetitCompiler-Scanner' 0
 PPCInlinedMethod PPCInlinedMethod stx:goodies/petitparser/compiler 'PetitCompiler-Compiler-Codegen' 0
 PPCInliningVisitor PPCInliningVisitor stx:goodies/petitparser/compiler 'PetitCompiler-Visitors' 0
@@ -52,11 +66,15 @@
 PPCPluggableNode PPCPluggableNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
 PPCProfilingContext PPCProfilingContext stx:goodies/petitparser/compiler 'PetitCompiler-Context' 0
 PPCRewritingVisitor PPCRewritingVisitor stx:goodies/petitparser/compiler 'PetitCompiler-Visitors' 0
+PPCTokenCodeGenerator PPCTokenCodeGenerator stx:goodies/petitparser/compiler 'PetitCompiler-Visitors' 0
+PPCTokenizingCodeGen PPCTokenizingCodeGen stx:goodies/petitparser/compiler 'PetitCompiler-Compiler-Codegen' 0
 PPCTokenizingCompiler PPCTokenizingCompiler stx:goodies/petitparser/compiler 'PetitCompiler-Compiler' 0
 PPCTokenizingConfiguration PPCTokenizingConfiguration stx:goodies/petitparser/compiler 'PetitCompiler-Core' 0
 PPCUniversalConfiguration PPCUniversalConfiguration stx:goodies/petitparser/compiler 'PetitCompiler-Core' 0
+PPCUniversalResultStrategy PPCUniversalResultStrategy stx:goodies/petitparser/compiler 'PetitCompiler-Scanner' 0
 PPCUnknownNode PPCUnknownNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
 PPTokenizingCompiledParser PPTokenizingCompiledParser stx:goodies/petitparser/compiler 'PetitCompiler-Parsers' 4
+PEGFsaEOFTransition PEGFsaEOFTransition stx:goodies/petitparser/compiler 'PetitCompiler-FSA' 0
 PPCAbstractActionNode PPCAbstractActionNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
 PPCAndNode PPCAndNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
 PPCCharSetPredicateNode PPCCharSetPredicateNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
@@ -84,7 +102,6 @@
 PPCSequenceNode PPCSequenceNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
 PPCSpecializingVisitor PPCSpecializingVisitor stx:goodies/petitparser/compiler 'PetitCompiler-Visitors' 0
 PPCStarNode PPCStarNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
-PPCTokenCodeGenerator PPCTokenCodeGenerator stx:goodies/petitparser/compiler 'PetitCompiler-Visitors' 0
 PPCTokenConsumeNode PPCTokenConsumeNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
 PPCTokenDetector PPCTokenDetector stx:goodies/petitparser/compiler 'PetitCompiler-Visitors' 0
 PPCTokenNode PPCTokenNode stx:goodies/petitparser/compiler 'PetitCompiler-Nodes' 0
--- a/compiler/bc.mak	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/bc.mak	Mon Aug 17 12:56:02 2015 +0100
@@ -78,10 +78,14 @@
 
 # BEGINMAKEDEPEND --- do not remove this line; make depend needs it
 $(OUTDIR)PEGFsa.$(O) PEGFsa.$(H): PEGFsa.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaAbstractDeterminizator.$(O) PEGFsaAbstractDeterminizator.$(H): PEGFsaAbstractDeterminizator.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaFailure.$(O) PEGFsaFailure.$(H): PEGFsaFailure.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaInterpret.$(O) PEGFsaInterpret.$(H): PEGFsaInterpret.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaInterpretRecord.$(O) PEGFsaInterpretRecord.$(H): PEGFsaInterpretRecord.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaMinimizator.$(O) PEGFsaMinimizator.$(H): PEGFsaMinimizator.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaPair.$(O) PEGFsaPair.$(H): PEGFsaPair.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaState.$(O) PEGFsaState.$(H): PEGFsaState.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaStateInfo.$(O) PEGFsaStateInfo.$(H): PEGFsaStateInfo.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaTransition.$(O) PEGFsaTransition.$(H): PEGFsaTransition.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCASTUtilities.$(O) PPCASTUtilities.$(H): PPCASTUtilities.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCArguments.$(O) PPCArguments.$(H): PPCArguments.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
@@ -101,24 +105,34 @@
 $(OUTDIR)PPCContext.$(O) PPCContext.$(H): PPCContext.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPStream.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\PeekableStream.$(H) $(INCLUDE_TOP)\stx\libbasic\PositionableStream.$(H) $(INCLUDE_TOP)\stx\libbasic\ReadStream.$(H) $(INCLUDE_TOP)\stx\libbasic\Stream.$(H) $(STCHDR)
 $(OUTDIR)PPCContextMemento.$(O) PPCContextMemento.$(H): PPCContextMemento.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCGuard.$(O) PPCGuard.$(H): PPCGuard.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PPCIdGenerator.$(O) PPCIdGenerator.$(H): PPCIdGenerator.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCMethod.$(O) PPCMethod.$(H): PPCMethod.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCNode.$(O) PPCNode.$(H): PPCNode.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCNodeVisitor.$(O) PPCNodeVisitor.$(H): PPCNodeVisitor.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCPluggableConfiguration.$(O) PPCPluggableConfiguration.$(H): PPCPluggableConfiguration.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCScanner.$(O) PPCScanner.$(H): PPCScanner.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCScannerCodeGenerator.$(O) PPCScannerCodeGenerator.$(H): PPCScannerCodeGenerator.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PPCScannerResultStrategy.$(O) PPCScannerResultStrategy.$(H): PPCScannerResultStrategy.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenGuard.$(O) PPCTokenGuard.$(H): PPCTokenGuard.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCompiledParser.$(O) PPCompiledParser.$(H): PPCompiledParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPMappedActionParser.$(O) PPMappedActionParser.$(H): PPMappedActionParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPActionParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPDelegateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)stx_goodies_petitparser_compiler.$(O) stx_goodies_petitparser_compiler.$(H): stx_goodies_petitparser_compiler.st $(INCLUDE_TOP)\stx\libbasic\LibraryDefinition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProjectDefinition.$(H) $(STCHDR)
 $(OUTDIR)FooScanner.$(O) FooScanner.$(H): FooScanner.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCScanner.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaCharacterTransition.$(O) PEGFsaCharacterTransition.$(H): PEGFsaCharacterTransition.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PEGFsaTransition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaChoiceDeterminizator.$(O) PEGFsaChoiceDeterminizator.$(H): PEGFsaChoiceDeterminizator.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PEGFsaAbstractDeterminizator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaDeterminizator.$(O) PEGFsaDeterminizator.$(H): PEGFsaDeterminizator.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PEGFsaAbstractDeterminizator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaEpsilonTransition.$(O) PEGFsaEpsilonTransition.$(H): PEGFsaEpsilonTransition.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PEGFsaTransition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaGenerator.$(O) PEGFsaGenerator.$(H): PEGFsaGenerator.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNodeVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaPredicateTransition.$(O) PEGFsaPredicateTransition.$(H): PEGFsaPredicateTransition.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PEGFsaTransition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaSequenceDeterminizator.$(O) PEGFsaSequenceDeterminizator.$(H): PEGFsaSequenceDeterminizator.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PEGFsaAbstractDeterminizator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaUncopiableState.$(O) PEGFsaUncopiableState.$(H): PEGFsaUncopiableState.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PEGFsaState.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCAbstractLiteralNode.$(O) PPCAbstractLiteralNode.$(H): PPCAbstractLiteralNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCAbstractPredicateNode.$(O) PPCAbstractPredicateNode.$(H): PPCAbstractPredicateNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCAnyNode.$(O) PPCAnyNode.$(H): PPCAnyNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCCharacterNode.$(O) PPCCharacterNode.$(H): PPCCharacterNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCCodeGenerator.$(O) PPCCodeGenerator.$(H): PPCCodeGenerator.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNodeVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCDelegateNode.$(O) PPCDelegateNode.$(H): PPCDelegateNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PPCDistinctResultStrategy.$(O) PPCDistinctResultStrategy.$(H): PPCDistinctResultStrategy.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCScannerResultStrategy.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCEndOfFileNode.$(O) PPCEndOfFileNode.$(H): PPCEndOfFileNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCFSACodeGen.$(O) PPCFSACodeGen.$(H): PPCFSACodeGen.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCCodeGen.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCInlinedMethod.$(O) PPCInlinedMethod.$(H): PPCInlinedMethod.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCMethod.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
@@ -128,11 +142,15 @@
 $(OUTDIR)PPCPluggableNode.$(O) PPCPluggableNode.$(H): PPCPluggableNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCProfilingContext.$(O) PPCProfilingContext.$(H): PPCProfilingContext.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPStream.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCContext.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\PeekableStream.$(H) $(INCLUDE_TOP)\stx\libbasic\PositionableStream.$(H) $(INCLUDE_TOP)\stx\libbasic\ReadStream.$(H) $(INCLUDE_TOP)\stx\libbasic\Stream.$(H) $(STCHDR)
 $(OUTDIR)PPCRewritingVisitor.$(O) PPCRewritingVisitor.$(H): PPCRewritingVisitor.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNodeVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PPCTokenCodeGenerator.$(O) PPCTokenCodeGenerator.$(H): PPCTokenCodeGenerator.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNodeVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PPCTokenizingCodeGen.$(O) PPCTokenizingCodeGen.$(H): PPCTokenizingCodeGen.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCCodeGen.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenizingCompiler.$(O) PPCTokenizingCompiler.$(H): PPCTokenizingCompiler.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCCompiler.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenizingConfiguration.$(O) PPCTokenizingConfiguration.$(H): PPCTokenizingConfiguration.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCConfiguration.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCUniversalConfiguration.$(O) PPCUniversalConfiguration.$(H): PPCUniversalConfiguration.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCConfiguration.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PPCUniversalResultStrategy.$(O) PPCUniversalResultStrategy.$(H): PPCUniversalResultStrategy.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCScannerResultStrategy.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCUnknownNode.$(O) PPCUnknownNode.$(H): PPCUnknownNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPTokenizingCompiledParser.$(O) PPTokenizingCompiledParser.$(H): PPTokenizingCompiledParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCompiledParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaEOFTransition.$(O) PEGFsaEOFTransition.$(H): PEGFsaEOFTransition.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PEGFsaPredicateTransition.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PEGFsaTransition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCAbstractActionNode.$(O) PPCAbstractActionNode.$(H): PPCAbstractActionNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCDelegateNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCAndNode.$(O) PPCAndNode.$(H): PPCAndNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCDelegateNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCCharSetPredicateNode.$(O) PPCCharSetPredicateNode.$(H): PPCCharSetPredicateNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCAbstractPredicateNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
@@ -160,7 +178,6 @@
 $(OUTDIR)PPCSequenceNode.$(O) PPCSequenceNode.$(H): PPCSequenceNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCListNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCSpecializingVisitor.$(O) PPCSpecializingVisitor.$(H): PPCSpecializingVisitor.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNodeVisitor.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCRewritingVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCStarNode.$(O) PPCStarNode.$(H): PPCStarNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCDelegateNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
-$(OUTDIR)PPCTokenCodeGenerator.$(O) PPCTokenCodeGenerator.$(H): PPCTokenCodeGenerator.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNodeVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenConsumeNode.$(O) PPCTokenConsumeNode.$(H): PPCTokenConsumeNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCDelegateNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenDetector.$(O) PPCTokenDetector.$(H): PPCTokenDetector.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNodeVisitor.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCRewritingVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenNode.$(O) PPCTokenNode.$(H): PPCTokenNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCDelegateNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
@@ -183,7 +200,7 @@
 $(OUTDIR)PPCMappedActionNode.$(O) PPCMappedActionNode.$(H): PPCMappedActionNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCAbstractActionNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCActionNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCDelegateNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenStarMessagePredicateNode.$(O) PPCTokenStarMessagePredicateNode.$(H): PPCTokenStarMessagePredicateNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCDelegateNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCStarMessagePredicateNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCStarNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCTokenStarSeparatorNode.$(O) PPCTokenStarSeparatorNode.$(H): PPCTokenStarSeparatorNode.st $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCDelegateNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCStarMessagePredicateNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCStarNode.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\compiler\PPCTokenStarMessagePredicateNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
-$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPActionParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPAndParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPCharSetPredicate.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPChoiceParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPCompositeParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPContext.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPDelegateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPEndOfInputParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPEpsilonParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPFailure.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPFlattenParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPListParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPLiteralObjectParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPLiteralParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPLiteralSequenceParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPNotParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPOptionalParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPPluggableParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPPossessiveRepeatingParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPPredicateObjectParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPPredicateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPRepeatingParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPSequenceParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPStream.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPToken.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPTokenParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPTrimmingParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\parsers\java\PPJavaWhitespaceParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\parsers\smalltalk\PPSmalltalkGrammar.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\parsers\smalltalk\PPSmalltalkTokenParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\parsers\smalltalk\PPSmalltalkWhitespaceParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Character.$(H) $(INCLUDE_TOP)\stx\libbasic\Magnitude.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\PeekableStream.$(H) $(INCLUDE_TOP)\stx\libbasic\PositionableStream.$(H) $(INCLUDE_TOP)\stx\libbasic\ReadStream.$(H) $(INCLUDE_TOP)\stx\libbasic\Stream.$(H) $(INCLUDE_TOP)\stx\libbasic\UndefinedObject.$(H) $(STCHDR)
+$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPActionParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPAndParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPCharSetPredicate.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPChoiceParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPCompositeParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPContext.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPDelegateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPEndOfFileParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPEndOfInputParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPEpsilonParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPFailure.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPFlattenParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPListParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPLiteralObjectParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPLiteralParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPLiteralSequenceParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPNotParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPOptionalParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPPluggableParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPPossessiveRepeatingParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPPredicateObjectParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPPredicateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPRepeatingParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPSequenceParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPStream.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPToken.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPTokenParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPTrimmingParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\parsers\java\PPJavaWhitespaceParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\parsers\smalltalk\PPSmalltalkGrammar.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\parsers\smalltalk\PPSmalltalkTokenParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\parsers\smalltalk\PPSmalltalkWhitespaceParser.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBLiteralNode.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBLiteralValueNode.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBProgramNode.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBStatementNode.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBValueNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Character.$(H) $(INCLUDE_TOP)\stx\libbasic\Magnitude.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\PeekableStream.$(H) $(INCLUDE_TOP)\stx\libbasic\PositionableStream.$(H) $(INCLUDE_TOP)\stx\libbasic\ReadStream.$(H) $(INCLUDE_TOP)\stx\libbasic\Stream.$(H) $(INCLUDE_TOP)\stx\libbasic\UndefinedObject.$(H) $(STCHDR)
 
 # ENDMAKEDEPEND --- do not remove this line
 
--- a/compiler/benchmarks/PPCBenchmark.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/benchmarks/PPCBenchmark.st	Mon Aug 17 12:56:02 2015 +0100
@@ -4,7 +4,7 @@
 
 Object subclass:#PPCBenchmark
 	instanceVariableNames:'sources report contextClass compile parser context input
-		configuration profile'
+		configuration profile repetitions'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-Benchmarks-Core'
@@ -63,6 +63,16 @@
     "Modified: / 16-05-2015 / 19:19:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
+!PPCBenchmark methodsFor:'accessing'!
+
+repetitions
+    ^ repetitions
+!
+
+repetitions: anObject
+    repetitions := anObject
+! !
+
 !PPCBenchmark methodsFor:'benchmark support'!
 
 compile: value
@@ -263,15 +273,12 @@
 
     self setupSmalltalkGrammarCompiled.
 
-    time := [ input do: [ :source | parser parse: source withContext: context ]] timeToRun asMilliSeconds.
-    
-    self reportInput: input time: time name: 'Compiled Smalltalk Grammar'.
-
-"	
-    size := input inject: 0 into: [:r :e | r + e size  ].
-    Transcript crShow: 'Compiled Grammar time: ', time asString.
-    Transcript crShow: 'Time per character: ', (time / size * 1000.0) asString, ' microseconds'.
-"
+    repetitions timesRepeat: [ 
+        time := [ input do: [ :source | 
+            parser parse: source withContext: context 
+        ]] timeToRun asMilliSeconds.
+        self reportInput: input time: time name: 'Compiled Smalltalk Grammar'.
+    ]
 !
 
 benchmarkSmalltalkGrammarTokenized
@@ -279,12 +286,12 @@
 
     self setupSmalltalkGrammarTokenized.
     
-    time := [ input do: [ :source | 
-            parser parse: source withContext: context ] 
-    ] timeToRun asMilliSeconds.
-    
-    self reportInput: input time: time name: 'Tokenized Smalltalk Grammar'.
-
+    repetitions timesRepeat: [ 	
+        time := [ input do: [ :source | 
+                parser parse: source withContext: context ] 
+        ] timeToRun asMilliSeconds.
+        self reportInput: input time: time name: 'Tokenized Smalltalk Grammar'.
+    ]
 "	
     size := input inject: 0 into: [:r :e | r + e size  ].
     Transcript crShow: 'Compiled Grammar time: ', time asString.
@@ -443,6 +450,8 @@
 
     compile := false.
     profile := false.
+    
+    repetitions := 3
 ! !
 
 !PPCBenchmark methodsFor:'meta'!
@@ -497,7 +506,8 @@
 setupExpressionGrammarCompiled
     
     configuration := PPCConfiguration universal.
-    configuration arguments name: #PPCompiledExpressionGrammar.
+    configuration arguments parserName: #PPCompiledExpressionGrammar.
+    configuration arguments scannerName: #PPCompiledExpressionScanner.
     parser := PPExpressionGrammar new compileWithConfiguration: configuration.
     context := self context.
     context initializeFor: parser.
@@ -507,7 +517,8 @@
 setupExpressionGrammarTokenized
     
     configuration := PPCConfiguration tokenizing.
-    configuration arguments name: #PPTokenizedExpressionGrammar.
+    configuration arguments parserName: #PPTokenizedExpressionGrammar.
+    configuration arguments scannerName: #PPTokenizedExpressionScanner.
     parser := PPExpressionGrammar new compileWithConfiguration: configuration.
     context := self context.
     context initializeFor: parser.
@@ -546,7 +557,8 @@
 setupLL1ExpressionGrammarCompiled
     
     configuration := PPCConfiguration universal.
-    configuration arguments name: #PPCompiledLL1ExpressionGrammar.
+    configuration arguments parserName: #PPCompiledLL1ExpressionGrammar.
+    configuration arguments scannerName: #PPCompiledLL1ExpressionScanner.
     parser := PPLL1ExpressionGrammar new compileWithConfiguration: configuration.
     context := self context.
     context initializeFor: parser.
@@ -556,7 +568,8 @@
 setupLL1ExpressionGrammarTokenized
     
     configuration := PPCConfiguration tokenizing.
-    configuration arguments name: #PPTokenizedLL1ExpressionGrammar.
+    configuration arguments parserName: #PPTokenizedLL1ExpressionGrammar.
+    configuration arguments scannerName: #PPTokenizedLL1ExpressionScanner.
     parser := PPLL1ExpressionGrammar new compileWithConfiguration: configuration.
     context := self context.
     context initializeFor: parser.
@@ -579,7 +592,8 @@
 setupSmalltalkGrammarCompiled
 
     configuration := PPCConfiguration universal.
-    configuration arguments name: #PPCompiledSmalltalkGrammar.
+    configuration arguments parserName: #PPCompiledSmalltalkGrammar.
+    configuration arguments scannerName: #PPCompiledSmalltalkScanner.
     configuration arguments profile: profile.
     
     parser := PPSmalltalkGrammar new compileWithConfiguration: configuration.
@@ -596,7 +610,8 @@
 setupSmalltalkGrammarTokenized
 
     configuration := PPCConfiguration tokenizing.
-    configuration arguments name: #PPTokenizedSmalltalkGrammar.
+    configuration arguments parserName: #PPTokenizedSmalltalkGrammar.
+    configuration arguments scannerName: #PPTokenizedSmalltalkScanner.
     configuration arguments profile: profile.
     
     parser := PPSmalltalkGrammar new compileWithConfiguration: configuration.
@@ -622,7 +637,7 @@
 
 setupSmalltalkNoopParserTokenized
 
-    configuration := PPCConfiguration LL1.
+    configuration := PPCConfiguration tokenizing.
     parser := PPCSmalltalkNoopParser new compileWithConfiguration: configuration.
     context := PPCContext new.
     context initializeFor: parser.
--- a/compiler/extensions.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/extensions.st	Mon Aug 17 12:56:02 2015 +0100
@@ -14,6 +14,12 @@
 
 !Object methodsFor:'*petitcompiler'!
 
+isFsaFailure
+    ^ false
+! !
+
+!Object methodsFor:'*petitcompiler'!
+
 isInlinedMethod
     ^ false
 ! !
@@ -163,6 +169,12 @@
 
 !PPContext methodsFor:'*petitcompiler'!
 
+methodFinished: whatever
+    "nothing to do"
+! !
+
+!PPContext methodsFor:'*petitcompiler'!
+
 methodInvoked: whatever
     "nothing to do"
 ! !
@@ -187,6 +199,12 @@
 
 !PPContext methodsFor:'*petitcompiler'!
 
+tokenRead: whatever
+    "nothing to do"
+! !
+
+!PPContext methodsFor:'*petitcompiler'!
+
 whitespace
     ^ self globalAt: #whitespace ifAbsent: [ nil ].
 ! !
@@ -227,6 +245,14 @@
     ^ super compileWith: aPetitCompiler.
 ! !
 
+!PPEndOfFileParser methodsFor:'*petitcompiler'!
+
+asCompilerNode
+    ^ PPCEndOfFileNode new
+        name: self name;
+        yourself
+! !
+
 !PPEndOfInputParser methodsFor:'*petitcompiler'!
 
 asCompilerNode
@@ -649,6 +675,21 @@
 
 !PPSmalltalkGrammar methodsFor:'*petitcompiler'!
 
+number
+    | numberChars |
+    numberChars := #hex asParser / 'r' asParser / 's' asParser / '-' asParser.
+    ^ $- asParser optional, #digit asParser, numberChars star, ('.' asParser, numberChars plus) optional.
+    
+"	^ ($- asParser optional , #digit asParser) and , [ :context | 
+        [ (NumberParser on: context stream) nextNumber ] 
+            on: Error
+            do: [ :err | PPFailure message: err messageText at: context position ] ] 
+                asParser
+"
+! !
+
+!PPSmalltalkGrammar methodsFor:'*petitcompiler'!
+
 whitespace
     ^ #space asParser plus
 ! !
@@ -717,6 +758,20 @@
     ^ self name hash
 ! !
 
+!PPSmalltalkWhitespaceParser methodsFor:'*petitcompiler'!
+
+parseOn: aPPContext
+    [ [aPPContext atEnd not and: [ aPPContext uncheckedPeek isSeparator ] ]
+        whileTrue: [ aPPContext next ].
+        
+     aPPContext atEnd not and: [ aPPContext uncheckedPeek = $" ] ] whileTrue: [
+        aPPContext next.
+        "aPPContext upTo: $".
+        
+        [aPPContext atEnd or: [aPPContext next == $"]] whileFalse
+    ].
+! !
+
 !PPStream methodsFor:'*petitcompiler'!
 
 peek: anInteger
@@ -805,14 +860,51 @@
         yourself
 ! !
 
+!RBLiteralValueNode methodsFor:'*petitcompiler'!
+
+isLiteralNumber
+    ((Smalltalk respondsTo: #isSmalltalk/X) and: [Smalltalk isSmalltalkX]) ifTrue:[
+    	^super isLiteralNumber
+    ] ifFalse:[
+    	"Assume Pharo..."
+         [(NumberParser on: self sourceText ) nextNumber] on: Exception do: [ ^ false ].
+         ^ true
+    ].
+    
+! !
+
+!RBProgramNode methodsFor:'*petitcompiler'!
+
+isLiteralNumber
+    ^ false
+! !
+
 !UndefinedObject methodsFor:'*petitcompiler'!
 
 asInteger
+    "
+        because nil is returned as and of text on stream
+        
+        JK: This should be obviously rewritten in future!!
+    "
+    self flag: 'JK: Hack alert!!'.
     ^ 256
 ! !
 
 !UndefinedObject methodsFor:'*petitcompiler'!
 
+codePoint
+    "
+        because nil is returned as and of text on stream
+        
+        JK: This should be obviously rewritten in future!!
+    "
+    self flag: 'JK: Hack alert!!'.
+    ^ 0
+! !
+
+!UndefinedObject methodsFor:'*petitcompiler'!
+
 isAlphaNumeric
     ^ false
 ! !
--- a/compiler/libInit.cc	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/libInit.cc	Mon Aug 17 12:56:02 2015 +0100
@@ -28,10 +28,14 @@
 OBJ snd; struct __vmData__ *__pRT__; {
 __BEGIN_PACKAGE2__("libstx_goodies_petitparser_compiler", _libstx_goodies_petitparser_compiler_Init, "stx:goodies/petitparser/compiler");
 _PEGFsa_Init(pass,__pRT__,snd);
+_PEGFsaAbstractDeterminizator_Init(pass,__pRT__,snd);
 _PEGFsaFailure_Init(pass,__pRT__,snd);
 _PEGFsaInterpret_Init(pass,__pRT__,snd);
+_PEGFsaInterpretRecord_Init(pass,__pRT__,snd);
+_PEGFsaMinimizator_Init(pass,__pRT__,snd);
 _PEGFsaPair_Init(pass,__pRT__,snd);
 _PEGFsaState_Init(pass,__pRT__,snd);
+_PEGFsaStateInfo_Init(pass,__pRT__,snd);
 _PEGFsaTransition_Init(pass,__pRT__,snd);
 _PPCASTUtilities_Init(pass,__pRT__,snd);
 _PPCArguments_Init(pass,__pRT__,snd);
@@ -51,24 +55,34 @@
 _PPCContext_Init(pass,__pRT__,snd);
 _PPCContextMemento_Init(pass,__pRT__,snd);
 _PPCGuard_Init(pass,__pRT__,snd);
+_PPCIdGenerator_Init(pass,__pRT__,snd);
 _PPCMethod_Init(pass,__pRT__,snd);
 _PPCNode_Init(pass,__pRT__,snd);
 _PPCNodeVisitor_Init(pass,__pRT__,snd);
 _PPCPluggableConfiguration_Init(pass,__pRT__,snd);
 _PPCScanner_Init(pass,__pRT__,snd);
 _PPCScannerCodeGenerator_Init(pass,__pRT__,snd);
+_PPCScannerResultStrategy_Init(pass,__pRT__,snd);
 _PPCTokenGuard_Init(pass,__pRT__,snd);
 _PPCompiledParser_Init(pass,__pRT__,snd);
 _PPMappedActionParser_Init(pass,__pRT__,snd);
 _stx_137goodies_137petitparser_137compiler_Init(pass,__pRT__,snd);
 _FooScanner_Init(pass,__pRT__,snd);
+_PEGFsaCharacterTransition_Init(pass,__pRT__,snd);
+_PEGFsaChoiceDeterminizator_Init(pass,__pRT__,snd);
+_PEGFsaDeterminizator_Init(pass,__pRT__,snd);
+_PEGFsaEpsilonTransition_Init(pass,__pRT__,snd);
 _PEGFsaGenerator_Init(pass,__pRT__,snd);
+_PEGFsaPredicateTransition_Init(pass,__pRT__,snd);
+_PEGFsaSequenceDeterminizator_Init(pass,__pRT__,snd);
+_PEGFsaUncopiableState_Init(pass,__pRT__,snd);
 _PPCAbstractLiteralNode_Init(pass,__pRT__,snd);
 _PPCAbstractPredicateNode_Init(pass,__pRT__,snd);
 _PPCAnyNode_Init(pass,__pRT__,snd);
 _PPCCharacterNode_Init(pass,__pRT__,snd);
 _PPCCodeGenerator_Init(pass,__pRT__,snd);
 _PPCDelegateNode_Init(pass,__pRT__,snd);
+_PPCDistinctResultStrategy_Init(pass,__pRT__,snd);
 _PPCEndOfFileNode_Init(pass,__pRT__,snd);
 _PPCFSACodeGen_Init(pass,__pRT__,snd);
 _PPCInlinedMethod_Init(pass,__pRT__,snd);
@@ -78,11 +92,15 @@
 _PPCPluggableNode_Init(pass,__pRT__,snd);
 _PPCProfilingContext_Init(pass,__pRT__,snd);
 _PPCRewritingVisitor_Init(pass,__pRT__,snd);
+_PPCTokenCodeGenerator_Init(pass,__pRT__,snd);
+_PPCTokenizingCodeGen_Init(pass,__pRT__,snd);
 _PPCTokenizingCompiler_Init(pass,__pRT__,snd);
 _PPCTokenizingConfiguration_Init(pass,__pRT__,snd);
 _PPCUniversalConfiguration_Init(pass,__pRT__,snd);
+_PPCUniversalResultStrategy_Init(pass,__pRT__,snd);
 _PPCUnknownNode_Init(pass,__pRT__,snd);
 _PPTokenizingCompiledParser_Init(pass,__pRT__,snd);
+_PEGFsaEOFTransition_Init(pass,__pRT__,snd);
 _PPCAbstractActionNode_Init(pass,__pRT__,snd);
 _PPCAndNode_Init(pass,__pRT__,snd);
 _PPCCharSetPredicateNode_Init(pass,__pRT__,snd);
@@ -110,7 +128,6 @@
 _PPCSequenceNode_Init(pass,__pRT__,snd);
 _PPCSpecializingVisitor_Init(pass,__pRT__,snd);
 _PPCStarNode_Init(pass,__pRT__,snd);
-_PPCTokenCodeGenerator_Init(pass,__pRT__,snd);
 _PPCTokenConsumeNode_Init(pass,__pRT__,snd);
 _PPCTokenDetector_Init(pass,__pRT__,snd);
 _PPCTokenNode_Init(pass,__pRT__,snd);
--- a/compiler/stx_goodies_petitparser_compiler.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/stx_goodies_petitparser_compiler.st	Mon Aug 17 12:56:02 2015 +0100
@@ -60,6 +60,7 @@
         #'stx:goodies/petitparser/parsers/java'    "PPJavaWhitespaceParser - extended"
         #'stx:goodies/petitparser/parsers/smalltalk'    "PPSmalltalkGrammar - extended"
         #'stx:libbasic'    "Autoload - superclass of PPCASTUtilitiesTests"
+        #'stx:goodies/refactoryBrowser/parser'    "RBLiteralNode - extended"
     )
 !
 
@@ -75,7 +76,6 @@
 
     ^ #(
         #'stx:goodies/petitparser/analyzer'    "PPSentinel - referenced by PPCompiledParser class>>referringParser"
-        #'stx:goodies/refactoryBrowser/parser'    "RBAssignmentNode - referenced by PPCCodeGenerator>>visitActionNode:"
         #'stx:libbasic2'    "IdentityBag - referenced by PEGFsa>>checkTransitionsIdentity"
         #'stx:libview'    "Color - referenced by PEGFsa>>viewGraphOn:"
         #'stx:libwidg'    "ScrollableView - referenced by PPCNode>>inspector2TabTree"
@@ -112,10 +112,14 @@
     ^ #(
         "<className> or (<className> attributes...) in load order"
         PEGFsa
+        PEGFsaAbstractDeterminizator
         PEGFsaFailure
         PEGFsaInterpret
+        PEGFsaInterpretRecord
+        PEGFsaMinimizator
         PEGFsaPair
         PEGFsaState
+        PEGFsaStateInfo
         PEGFsaTransition
         PPCASTUtilities
         PPCArguments
@@ -135,24 +139,34 @@
         PPCContext
         PPCContextMemento
         PPCGuard
+        PPCIdGenerator
         PPCMethod
         PPCNode
         PPCNodeVisitor
         PPCPluggableConfiguration
         PPCScanner
         PPCScannerCodeGenerator
+        PPCScannerResultStrategy
         PPCTokenGuard
         PPCompiledParser
         PPMappedActionParser
         #'stx_goodies_petitparser_compiler'
         FooScanner
+        PEGFsaCharacterTransition
+        PEGFsaChoiceDeterminizator
+        PEGFsaDeterminizator
+        PEGFsaEpsilonTransition
         PEGFsaGenerator
+        PEGFsaPredicateTransition
+        PEGFsaSequenceDeterminizator
+        PEGFsaUncopiableState
         PPCAbstractLiteralNode
         PPCAbstractPredicateNode
         PPCAnyNode
         PPCCharacterNode
         PPCCodeGenerator
         PPCDelegateNode
+        PPCDistinctResultStrategy
         PPCEndOfFileNode
         PPCFSACodeGen
         PPCInlinedMethod
@@ -162,11 +176,15 @@
         PPCPluggableNode
         PPCProfilingContext
         PPCRewritingVisitor
+        PPCTokenCodeGenerator
+        PPCTokenizingCodeGen
         PPCTokenizingCompiler
         PPCTokenizingConfiguration
         PPCUniversalConfiguration
+        PPCUniversalResultStrategy
         PPCUnknownNode
         PPTokenizingCompiledParser
+        PEGFsaEOFTransition
         PPCAbstractActionNode
         PPCAndNode
         PPCCharSetPredicateNode
@@ -194,7 +212,6 @@
         PPCSequenceNode
         PPCSpecializingVisitor
         PPCStarNode
-        PPCTokenCodeGenerator
         PPCTokenConsumeNode
         PPCTokenDetector
         PPCTokenNode
@@ -337,6 +354,15 @@
         Object canHavePPCId
         PPCompositeParser asCompilerNode
         PPSequenceParser map:
+        Object isFsaFailure
+        PPContext methodFinished:
+        PPContext tokenRead:
+        PPEndOfFileParser asCompilerNode
+        PPSmalltalkGrammar number
+        PPSmalltalkWhitespaceParser parseOn:
+        RBLiteralValueNode isLiteralNumber
+        RBProgramNode isLiteralNumber
+        UndefinedObject codePoint
     )
 ! !
 
--- a/compiler/tests/FooScannerTest.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/tests/FooScannerTest.st	Mon Aug 17 12:56:02 2015 +0100
@@ -14,7 +14,8 @@
 fail: stream rule: rule 
     scanner initialize.
     scanner stream: stream asPetitStream. 
-    result := scanner perform: rule.
+    scanner perform: rule.
+    result := scanner polyResult.
         
     self assert: result isEmpty
 !
@@ -26,8 +27,9 @@
 fail: stream token: token rule: rule position: position
     scanner initialize.
     scanner stream: stream asPetitStream. 
-    result := scanner perform: rule.
-        
+    scanner perform: rule.
+    
+    result := scanner polyResult.	
     self assert: (result at: token ifAbsent: [nil]) isNil.
 !
 
@@ -38,7 +40,8 @@
 parse: stream token: token rule: rule position: position
     scanner initialize.
     scanner stream: stream asPetitStream. 
-    result := scanner perform: rule.
+    scanner perform: rule.
+    result := scanner polyResult.
     
     self assert: (result includesKey: token).	
     self assert: (result at: token) = position.
@@ -85,7 +88,7 @@
 !
 
 testAB
-    self parse: 'ab' token: #b rule: #nextTokenAB position: 2.
+    self parse: 'ab' token: #B rule: #nextTokenAB position: 2.
 !
 
 testABorBC
@@ -151,12 +154,21 @@
     self parse: 'aaab' token: #AstarB rule: #nextTokenAstarB.
 
     self fail: 'c' rule: #nextTokenAstarB.	
-!
+! !
+
+!FooScannerTest methodsFor:'multivalues'!
 
 testAuorA
-    self parse: 'a' token: #a1 rule: #nextTokenAuorA.
-    self parse: 'a' token: #a2 rule: #nextTokenAuorA.
+    self parse: 'a' token: #A1 rule: #nextTokenAuorA.
+    self parse: 'a' token: #A2 rule: #nextTokenAuorA.
 
     self fail: 'b' rule: #nextTokenAuorA.	
+!
+
+testMultiA
+    self parse: 'a' token: #A1 rule: #nextMultiTokenA position: 1.	
+    self parse: 'a' token: #A2 rule: #nextMultiTokenA position: 1.
+    
+    self fail: 'b' rule: #nextMultiTokenA.
 ! !
 
--- a/compiler/tests/Make.proto	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/tests/Make.proto	Mon Aug 17 12:56:02 2015 +0100
@@ -128,13 +128,18 @@
 
 # BEGINMAKEDEPEND --- do not remove this line; make depend needs it
 $(OUTDIR)FooScannerTest.$(O) FooScannerTest.$(H): FooScannerTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaChoiceDeterminizationTest.$(O) PEGFsaChoiceDeterminizationTest.$(H): PEGFsaChoiceDeterminizationTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaDeterminizationTest.$(O) PEGFsaDeterminizationTest.$(H): PEGFsaDeterminizationTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaGeneratorTest.$(O) PEGFsaGeneratorTest.$(H): PEGFsaGeneratorTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaIntegrationTest.$(O) PEGFsaIntegrationTest.$(H): PEGFsaIntegrationTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaInterpretTest.$(O) PEGFsaInterpretTest.$(H): PEGFsaInterpretTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaMinimizationTest.$(O) PEGFsaMinimizationTest.$(H): PEGFsaMinimizationTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaScannerIntegrationTest.$(O) PEGFsaScannerIntegrationTest.$(H): PEGFsaScannerIntegrationTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PEGFsaSequenceDeterminizationTest.$(O) PEGFsaSequenceDeterminizationTest.$(H): PEGFsaSequenceDeterminizationTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaStateTest.$(O) PEGFsaStateTest.$(H): PEGFsaStateTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaTest.$(O) PEGFsaTest.$(H): PEGFsaTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PEGFsaTransitionTest.$(O) PEGFsaTransitionTest.$(H): PEGFsaTransitionTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPCASTUtilitiesTests.$(O) PPCASTUtilitiesTests.$(H): PPCASTUtilitiesTests.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCClassBuilderTest.$(O) PPCClassBuilderTest.$(H): PPCClassBuilderTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCCodeGeneratorTest.$(O) PPCCodeGeneratorTest.$(H): PPCCodeGeneratorTest.st $(INCLUDE_TOP)/stx/goodies/petitparser/tests/PPAbstractParserTest.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCCompilerTest.$(O) PPCCompilerTest.$(H): PPCCompilerTest.st $(INCLUDE_TOP)/stx/goodies/petitparser/tests/PPAbstractParserTest.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
@@ -142,6 +147,7 @@
 $(OUTDIR)PPCContextTest.$(O) PPCContextTest.$(H): PPCContextTest.st $(INCLUDE_TOP)/stx/goodies/petitparser/tests/PPContextTest.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCCopyVisitorTest.$(O) PPCCopyVisitorTest.$(H): PPCCopyVisitorTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCGuardTest.$(O) PPCGuardTest.$(H): PPCGuardTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPCIdGeneratorTest.$(O) PPCIdGeneratorTest.$(H): PPCIdGeneratorTest.st $(INCLUDE_TOP)/stx/goodies/petitparser/tests/PPAbstractParserTest.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCInliningVisitorTest.$(O) PPCInliningVisitorTest.$(H): PPCInliningVisitorTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCLL1VisitorTest.$(O) PPCLL1VisitorTest.$(H): PPCLL1VisitorTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCLTokenizingOptimizationTest.$(O) PPCLTokenizingOptimizationTest.$(H): PPCLTokenizingOptimizationTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
@@ -150,6 +156,7 @@
 $(OUTDIR)PPCNodeFirstFollowNextTests.$(O) PPCNodeFirstFollowNextTests.$(H): PPCNodeFirstFollowNextTests.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCNodeTest.$(O) PPCNodeTest.$(H): PPCNodeTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCOptimizeChoicesTest.$(O) PPCOptimizeChoicesTest.$(H): PPCOptimizeChoicesTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPCOverlappingTokensTest.$(O) PPCOverlappingTokensTest.$(H): PPCOverlappingTokensTest.st $(INCLUDE_TOP)/stx/goodies/petitparser/tests/PPAbstractParserTest.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCRecognizerComponentDetectorTest.$(O) PPCRecognizerComponentDetectorTest.$(H): PPCRecognizerComponentDetectorTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCRecognizerComponentVisitorTest.$(O) PPCRecognizerComponentVisitorTest.$(H): PPCRecognizerComponentVisitorTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCScannerCodeGeneratorTest.$(O) PPCScannerCodeGeneratorTest.$(H): PPCScannerCodeGeneratorTest.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
--- a/compiler/tests/Make.spec	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/tests/Make.spec	Mon Aug 17 12:56:02 2015 +0100
@@ -52,13 +52,18 @@
 
 COMMON_CLASSES= \
 	FooScannerTest \
+	PEGFsaChoiceDeterminizationTest \
 	PEGFsaDeterminizationTest \
 	PEGFsaGeneratorTest \
+	PEGFsaIntegrationTest \
 	PEGFsaInterpretTest \
+	PEGFsaMinimizationTest \
 	PEGFsaScannerIntegrationTest \
+	PEGFsaSequenceDeterminizationTest \
 	PEGFsaStateTest \
 	PEGFsaTest \
 	PEGFsaTransitionTest \
+	PPCASTUtilitiesTests \
 	PPCClassBuilderTest \
 	PPCCodeGeneratorTest \
 	PPCCompilerTest \
@@ -66,6 +71,7 @@
 	PPCContextTest \
 	PPCCopyVisitorTest \
 	PPCGuardTest \
+	PPCIdGeneratorTest \
 	PPCInliningVisitorTest \
 	PPCLL1VisitorTest \
 	PPCLTokenizingOptimizationTest \
@@ -74,6 +80,7 @@
 	PPCNodeFirstFollowNextTests \
 	PPCNodeTest \
 	PPCOptimizeChoicesTest \
+	PPCOverlappingTokensTest \
 	PPCRecognizerComponentDetectorTest \
 	PPCRecognizerComponentVisitorTest \
 	PPCScannerCodeGeneratorTest \
@@ -92,13 +99,18 @@
 
 COMMON_OBJS= \
     $(OUTDIR_SLASH)FooScannerTest.$(O) \
+    $(OUTDIR_SLASH)PEGFsaChoiceDeterminizationTest.$(O) \
     $(OUTDIR_SLASH)PEGFsaDeterminizationTest.$(O) \
     $(OUTDIR_SLASH)PEGFsaGeneratorTest.$(O) \
+    $(OUTDIR_SLASH)PEGFsaIntegrationTest.$(O) \
     $(OUTDIR_SLASH)PEGFsaInterpretTest.$(O) \
+    $(OUTDIR_SLASH)PEGFsaMinimizationTest.$(O) \
     $(OUTDIR_SLASH)PEGFsaScannerIntegrationTest.$(O) \
+    $(OUTDIR_SLASH)PEGFsaSequenceDeterminizationTest.$(O) \
     $(OUTDIR_SLASH)PEGFsaStateTest.$(O) \
     $(OUTDIR_SLASH)PEGFsaTest.$(O) \
     $(OUTDIR_SLASH)PEGFsaTransitionTest.$(O) \
+    $(OUTDIR_SLASH)PPCASTUtilitiesTests.$(O) \
     $(OUTDIR_SLASH)PPCClassBuilderTest.$(O) \
     $(OUTDIR_SLASH)PPCCodeGeneratorTest.$(O) \
     $(OUTDIR_SLASH)PPCCompilerTest.$(O) \
@@ -106,6 +118,7 @@
     $(OUTDIR_SLASH)PPCContextTest.$(O) \
     $(OUTDIR_SLASH)PPCCopyVisitorTest.$(O) \
     $(OUTDIR_SLASH)PPCGuardTest.$(O) \
+    $(OUTDIR_SLASH)PPCIdGeneratorTest.$(O) \
     $(OUTDIR_SLASH)PPCInliningVisitorTest.$(O) \
     $(OUTDIR_SLASH)PPCLL1VisitorTest.$(O) \
     $(OUTDIR_SLASH)PPCLTokenizingOptimizationTest.$(O) \
@@ -114,6 +127,7 @@
     $(OUTDIR_SLASH)PPCNodeFirstFollowNextTests.$(O) \
     $(OUTDIR_SLASH)PPCNodeTest.$(O) \
     $(OUTDIR_SLASH)PPCOptimizeChoicesTest.$(O) \
+    $(OUTDIR_SLASH)PPCOverlappingTokensTest.$(O) \
     $(OUTDIR_SLASH)PPCRecognizerComponentDetectorTest.$(O) \
     $(OUTDIR_SLASH)PPCRecognizerComponentVisitorTest.$(O) \
     $(OUTDIR_SLASH)PPCScannerCodeGeneratorTest.$(O) \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/tests/PEGFsaChoiceDeterminizationTest.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,194 @@
+"{ Package: 'stx:goodies/petitparser/compiler/tests' }"
+
+"{ NameSpace: Smalltalk }"
+
+TestCase subclass:#PEGFsaChoiceDeterminizationTest
+	instanceVariableNames:'fsa a b c result d interpreter e t1 t2 state anotherState parser
+		generator'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-Tests-FSA'
+!
+
+!PEGFsaChoiceDeterminizationTest methodsFor:'as yet unclassified'!
+
+assert: anFsa fail: input
+    | stream |
+    stream := input asPetitStream.
+
+    result := interpreter interpret: anFsa on: stream.
+
+    self assert: result isEmpty.
+    ^ result
+!
+
+assert: anFsa parse: input
+    ^ self assert: anFsa parse: input end: input size
+!
+
+assert: anFsa parse: input end: end
+    | stream |
+    stream := input asPetitStream.
+
+    result := interpreter interpret: anFsa on: stream.
+
+    self assert: result size = 1.
+    self assert: ((result anyOne) = end) description: 'wrong position'.
+    
+    ^ result anyOne
+!
+
+determinizator
+    ^ PEGFsaChoiceDeterminizator new
+!
+
+determinize: anFsa
+    ^ self determinizator determinize: anFsa
+!
+
+fsaFrom: aNode
+    ^ (aNode accept: generator)
+        yourself
+!
+
+joinState: s1 with: s2
+    ^ self determinizator joinState: s1 with: s2 
+!
+
+setUp
+    a := PEGFsaState new name: #a; retval: #token; yourself.
+    b := PEGFsaState new name: #b; retval: #token; yourself.
+    c := PEGFsaState new name: #c; retval: #token; yourself.
+    d := PEGFsaState new name: #d; retval: #token; yourself.
+    e := PEGFsaState new name: #e; retval: #token; yourself.
+
+    state := PEGFsaState new name: #state; retval: #token; yourself.
+    anotherState := PEGFsaState new name: #anotherState; retval: #token; yourself.
+
+    t1 := PEGFsaCharacterTransition new.
+    t2 := PEGFsaCharacterTransition new.
+
+    fsa := PEGFsa new.
+    generator := PEGFsaGenerator new.
+
+    interpreter := PEGFsaInterpret new
+        yourself.
+!
+
+testAAorA
+    parser := 'aa' asParser / 'a' asParser.
+    fsa := self fsaFrom: parser asCompilerTree.
+    
+"	self assert: fsa states size = 2."
+    self assert: fsa isDeterministic.
+    self assert: fsa isWithoutEpsilons.	
+    
+    self assert: fsa parse: 'a'.
+    self assert: fsa parse: 'aa'.
+    self assert: fsa fail: 'b'.
+!
+
+testAorAA
+    parser := 'a' asParser / 'aa' asParser.
+    fsa := self fsaFrom: parser asCompilerTree.
+    
+"	self assert: fsa states size = 2."
+    self assert: fsa isDeterministic.
+    self assert: fsa isWithoutEpsilons.	
+    
+    self assert: fsa parse: 'a'.
+    self assert: fsa parse: 'aa' end: 1.
+    self assert: fsa fail: 'b'.
+!
+
+testDeterminizeFsa
+    fsa addState: a.
+    fsa addState: b.
+    fsa addState: c.
+    fsa addState: d.
+    fsa addState: e.
+    fsa startState: a.
+    fsa finalState: c.
+    fsa finalState: e.
+    
+    fsa addTransitionFrom: a to: b on: $a.
+    fsa addTransitionFrom: b to: c on: $b.
+
+    b final: true.
+    b priority: 0.
+    c final: true.
+    c priority: 0.
+    c failure: true.
+
+    fsa addTransitionFrom: a to: d on: $a priority: -1.
+    fsa addTransitionFrom: d to: e on: $a priority: -1.
+
+    d priority: -1.
+    e final: true.
+    e priority: -1.
+    e failure: true.
+
+
+    self determinize: fsa.
+        
+    self assert: fsa states size = 3.
+    self assert: a transitions size = 1.	
+    self assert: a destination isFinal.
+    self assert: a destination destination isFinal.
+!
+
+testDeterminizeFsa2
+    fsa addState: a.
+    fsa addState: b.
+    fsa addState: c.
+    fsa addState: d.
+    fsa addState: e.
+    fsa startState: a.
+    fsa finalState: c.
+    fsa finalState: e.
+    
+    fsa addTransitionFrom: a to: b on: $a.
+    fsa addTransitionFrom: b to: c on: $b.
+
+    b final: true.
+    b priority: 0.
+    c final: true.
+    c priority: 0.
+    c failure: true.
+
+    fsa addTransitionFrom: a to: d on: $a priority: -1.
+    fsa addTransitionFrom: d to: e on: $b priority: -1.
+
+    d priority: -1.
+    e final: true.
+    e priority: -1.
+    e failure: true.
+
+    self determinize: fsa.
+        
+    self assert: fsa states size = 3.
+    self assert: a transitions size = 1.	
+    self assert: a destination isFinal.
+    self assert: a destination transitions size = 1.
+    self assert: a destination destination isFsaFailure.
+!
+
+testNot
+    parser := ('aa' asParser, 'aa' asParser not) / ('aa' asParser, 'aa' asParser).
+    fsa := self fsaFrom: parser asCompilerTree.
+    
+
+"	self assert: fsa states size = 2."
+    self assert: fsa isDeterministic.
+    self assert: fsa isWithoutEpsilons.	
+    
+    self assert: fsa parse: 'aabc' end: 2.
+    self assert: fsa parse: 'aaa' end: 2.
+    self assert: fsa parse: 'aa'.
+
+    self assert: fsa parse: 'aaaa'.
+    self assert: fsa parse: 'aaaaa' end: 4.
+
+    self assert: fsa fail: 'ab'.
+! !
+
--- a/compiler/tests/PEGFsaDeterminizationTest.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/tests/PEGFsaDeterminizationTest.st	Mon Aug 17 12:56:02 2015 +0100
@@ -3,7 +3,7 @@
 "{ NameSpace: Smalltalk }"
 
 TestCase subclass:#PEGFsaDeterminizationTest
-	instanceVariableNames:'fsa a b c result d interpreter e'
+	instanceVariableNames:'parser1 parser2 fsa generator'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-Tests-FSA'
@@ -11,249 +11,107 @@
 
 !PEGFsaDeterminizationTest methodsFor:'as yet unclassified'!
 
-assert: anFsa fail: input
-    | stream |
-    stream := input asPetitStream.
-
-    result := interpreter interpret: anFsa on: stream.
-
-    self assert: result isEmpty.
-    ^ result
+determinizator
+    ^ PEGFsaDeterminizator new
 !
 
-assert: anFsa parse: input retval: name
-    ^ self assert: anFsa parse: input retval: name end: input size
+fsaFrom: aNode
+    ^ (aNode accept: generator)
+        determinize;
+        yourself
 !
 
-assert: anFsa parse: input retval: name end: end
-    | stream |
-    stream := input asPetitStream.
+merge
+    | startState fsa1 fsa2 |
+    fsa := PEGFsa new.
+    startState := PEGFsaState new.
 
-    result := interpreter interpret: anFsa on: stream.
+    fsa addState: startState.	
+    fsa startState: startState.
 
-    self assert: result isEmpty not.
-    self assert: ((result at: name) = end) description: 'wrong position'.
+    fsa1 := self fsaFrom: parser1 asCompilerTree.
+    fsa1 retval: #token1.
+    fsa adopt: fsa1.
+    fsa addTransitionFrom: startState to: fsa1 startState.
     
-    ^ result
-!
 
-assertFail: name
-    self assert: (result includesKey: name) not
-!
-
-assertPass: name
-    self assert: (result includesKey: name)
+    fsa2 := self fsaFrom: parser2 asCompilerTree.
+    fsa2 retval: #token2.
+    fsa adopt: fsa2.
+    fsa addTransitionFrom: startState to: fsa2 startState.
+    
+    self determinizator determinize: fsa 
 !
 
 setUp
-    a := PEGFsaState new name: #a; retval: #a; yourself.
-    b := PEGFsaState new name: #b; retval: #b; yourself.
-    c := PEGFsaState new name: #c; retval: #c; yourself.
-    d := PEGFsaState new name: #d; retval: #d; yourself.
-    e := PEGFsaState new name: #e; retval: #e; yourself.
-
-    fsa := PEGFsa new.
-
-    interpreter := PEGFsaInterpret new
-        yourself.
-!
-
-testAAplusA
-    fsa addState: a.
-    fsa addState: b.
-    fsa addState: c.
-    fsa addState: d.
-    fsa addState: e.
-    fsa startState: a.
-    fsa finalState: e.
-    
-    fsa addTransitionFrom: a to: b on: $a.
-    fsa addTransitionFrom: b to: c on: $a.
-    fsa addTransitionFrom: c to: a.	
-    fsa addTransitionFrom: c to: d priority: -1. 
-    fsa addTransitionFrom: d to: e on: $a.
-    
-    c priority: 0.
-    
-    fsa determinize.
-
-"	self assert: fsa states size = 3."
-    self assert: fsa isDeterministic.
-    self assert: fsa isWithoutEpsilons.	
-    
-    self assert: fsa fail: 'a'.
-    self assert: fsa fail: 'aa'.
-    self assert: fsa fail: 'aaaa'.
-
-    self assert: fsa parse: 'aaa' retval: #e.
-    self assert: fsa parse: 'aaaaa' retval: #e.
-    self assert: fsa parse: 'aaaaaaa' retval: #e.
+    super setUp.
+    generator := PEGFsaGenerator new.
 !
 
-testAB
-    fsa addState: a.
-    fsa addState: b.
-    fsa addState: c.
-    fsa addState: d.
-    fsa startState: a.
-    fsa finalState: d.
+testA_A
+    parser1 := 'a' asParser.
+    parser2 := 'a' asParser.
+    
+    self merge.
     
-    fsa addTransitionFrom: a to: b on: $a.
-    fsa addTransitionFrom: c to: d on: $b.	
-    fsa addTransitionFrom: b to: c priority: -1. 
-    
-    fsa determinize.
-
-    self assert: fsa states size = 3.
-    self assert: fsa isDeterministic.
-    self assert: fsa isWithoutEpsilons.	
-    
-    self assert: fsa parse: 'ab' retval: #d.
-    self assert: fsa parse: 'abc' retval: #d end: 2.
-    
-    self assert: fsa fail: 'ac'.
+    self assert: fsa states size = 2.
+    self assert: fsa finalStates size = 1.
+    self assert: fsa finalStates anyOne retvals size = 2.
+    self assert: (fsa finalStates anyOne retvals includes: #token1).	
+    self assert: (fsa finalStates anyOne retvals includes: #token2).		
 !
 
-testAPlusA
-    fsa addState: a.
-    fsa addState: b.
-    fsa addState: c.
-    fsa addState: d.
-    fsa startState: a.
-    fsa finalState: d.
+testA_AB
+    parser1 := 'a' asParser.
+    parser2 := 'ab' asParser.
+    
+    self merge.
     
-    fsa addTransitionFrom: a to: b on: $a.
-    fsa addTransitionFrom: b to: a.	
-    fsa addTransitionFrom: b to: c priority: -1. 
-    fsa addTransitionFrom: c to: d on: $a.
-    
-    b priority: 0.
-    
-    fsa determinize.
+    self assert: fsa states size = 3.
+    self assert: fsa finalStates size = 2.
+    self assert: fsa startState destination retvals size = 1.
+    self assert: fsa startState destination retval = #token1.
 
-"	self assert: fsa states size = 2."
-    self assert: fsa isDeterministic.
-    self assert: fsa isWithoutEpsilons.	
-    
-    self assert: fsa fail: 'a'.
-    self assert: fsa fail: 'aa'.
-    self assert: fsa fail: 'b'.
+    self assert: fsa startState destination destination retvals size = 1.
+    self assert: fsa startState destination destination retval = #token2.
 !
 
-testAPlusB
-    fsa addState: a.
-    fsa addState: b.
-    fsa addState: c.
-    fsa addState: d.
-    fsa startState: a.
-    fsa finalState: d.
-    
-    fsa addTransitionFrom: a to: b on: $a.
-    fsa addTransitionFrom: b to: a.	
-    fsa addTransitionFrom: b to: c priority: -1. 
-    fsa addTransitionFrom: c to: d on: $b.
+testID_KW
+    parser1 := #word asParser plus.
+    parser2 := #word asParser plus, $: asParser.
     
-    fsa determinize.
-
-    self assert: fsa states size = 3.
-    self assert: fsa isDeterministic.
-    self assert: fsa isWithoutEpsilons.	
+    self merge.
     
-    self assert: fsa parse: 'ab' retval: #d.
-    self assert: fsa parse: 'aaaab' retval: #d.
-    self assert: fsa parse: 'aaaabc' retval: #d end: 5.
-    
-    self assert: fsa fail: 'b'.
-!
+    self assert: fsa states size = 3.
+    self assert: fsa finalStates size = 2.
 
-testAorA
-    fsa addState: a.
-    fsa addState: b.
-    fsa addState: c.
-    fsa addState: d.
-    fsa addState: e.
-    fsa startState: a.
-    fsa finalState: c.
-    fsa finalState: e.
-    
-    fsa addTransitionFrom: a to: b.
-    fsa addTransitionFrom: a to: d.	
-    fsa addTransitionFrom: b to: c on: $a. 
-    fsa addTransitionFrom: d to: e on: $a. 
+    self assert: (fsa finalStates anySatisfy: [ :fs | fs retvals includes: #token1 ]).	
+    self assert: (fsa finalStates anySatisfy: [ :fs | fs retvals includes: #token2 ]).	
     
-    c priority: 0.
-    e priority: 0.
-    
-    fsa determinize.
-
-    self assert: fsa states size = 2.
-    self assert: fsa isDeterministic.
-    self assert: fsa isWithoutEpsilons.	
-    
-    self assert: fsa parse: 'a' retval: #c.
-    self assert: fsa parse: 'a' retval: #e.
-    self assert: (a transitions allSatisfy: [:t | t priority = 0]).
-    
-    self assert: fsa fail: 'b'.
 !
 
-testApriorityOrA
-    fsa addState: a.
-    fsa addState: b.
-    fsa addState: c.
-    fsa addState: d.
-    fsa addState: e.
-    fsa startState: a.
-    fsa finalState: c.
-    fsa finalState: e.
-    
-    c priority: 0.
-    e priority: 0.
+testTrue_ID
+    parser1 := 'true' asParser.
+    parser2 := #word asParser plus.
     
-    fsa addTransitionFrom: a to: b priority: -1.
-    fsa addTransitionFrom: a to: d.	
-    fsa addTransitionFrom: b to: c on: $a. 
-    fsa addTransitionFrom: d to: e on: $a. 
+    self merge.
     
-    fsa determinize.
-
-    self assert: fsa states size = 2.
-    self assert: fsa isDeterministic.
-    self assert: fsa isWithoutEpsilons.	
-    
-    self assert: fsa parse: 'a' retval: #e.
-    self assertFail: #c.
-    
-    self assert: fsa fail: 'b'.
+    self assert: fsa states size = 6.
+    self assert: fsa finalStates size = 5.
+    "Only 1 state with both #token1 and #token2"
+    self assert: ((fsa finalStates select: [:fs | fs retvals size = 2]) size = 1).	
 !
 
-testApriorityOrA2
-    fsa addState: a.
-    fsa addState: b.
-    fsa addState: c.
-    fsa addState: d.
-    fsa addState: e.
-    fsa startState: a.
-    fsa finalState: c.
-    fsa finalState: e.
+testTrue_True
+    parser1 := 'true' asParser.
+    parser2 := 'true' asParser.
     
-    c priority: 0.
-    e priority: 0.
+    self merge.
     
-    fsa addTransitionFrom: a to: b.
-    fsa addTransitionFrom: a to: d priority: -1.	
-    fsa addTransitionFrom: b to: c on: $a. 
-    fsa addTransitionFrom: d to: e on: $a. 
-    
-    fsa determinize.
-
-    self assert: fsa states size = 2.
-    self assert: fsa isDeterministic.
-    self assert: fsa isWithoutEpsilons.	
-    
-    self assert: fsa parse: 'a' retval: #c.
-    self assertFail: #e.
-    
-    self assert: fsa fail: 'b'.
+    self assert: fsa states size = 5.
+    self assert: fsa finalStates size = 1.
+    self assert: fsa finalStates anyOne retvals size = 2.
+    self assert: (fsa finalStates anyOne retvals includes: #token1).	
+    self assert: (fsa finalStates anyOne retvals includes: #token2).		
 ! !
 
--- a/compiler/tests/PEGFsaGeneratorTest.st	Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/tests/PEGFsaGeneratorTest.st	Mon Aug 17 12:56:02 2015 +0100
@@ -40,7 +40,8 @@
 
 fsaFrom: aNode
     ^ (aNode accept: generator)
-        compact;
+        determinize;
+        minimize;
         yourself
 !
 
@@ -48,208 +49,20 @@
     super setUp.
     generator := PEGFsaGenerator new.
     interpreter := PEGFsaInterpret new.	
-!
+! !
 
-testAAA_Aplusnot
-    | parser |
-    parser := 'aaa' asParser not, $a asParser plus.
-    node := parser asCompilerTree.
-        
-    fsa := self fsaFrom: node.
-    
-    self assert: fsa parse: 'a'.	
-    self assert: fsa parse: 'aa'.	
-    self assert: fsa fail: ''.
-    self assert: fsa fail: 'aaa'.
-    self assert: fsa fail: 'aaaa'.
-    self assert: fsa fail: 'aaaaa'.
-!
-
-testAAplusA
-    | parser |
-    parser := 'aa' asParser plus, $a asParser.
-    node := parser asCompilerTree.
-        
-    fsa := self fsaFrom: node.
-
-    self assert: fsa parse: 'aaa'.	
-    self assert: fsa parse: 'aaaaa'.	
-    self assert: fsa parse: 'aaaaaaa'.	
-    self assert: fsa fail: 'a'.
-    self assert: fsa fail: 'aa'.
-    self assert: fsa fail: 'aaaa'.
-!
+!PEGFsaGeneratorTest methodsFor:'basic'!
 
-testAAplusB
-    | parser |
-    parser := 'aa' asParser plus, $b asParser.
-    node := parser asCompilerTree.
-        
-    fsa := self fsaFrom: node.
-    
-    self assert: fsa parse: 'aab'.	
-    self assert: fsa parse: 'aaaab'.	
-    self assert: fsa fail: 'a'.
-    self assert: fsa fail: 'aa'.
-    self assert: fsa fail: 'aaaa'.
-    self assert: fsa fail: 'aaaac'.
-!
-
-testAB
-    | parser |
-    parser := $a asParser, $b asParser.
-    node := parser asCompilerTree.
-        
-    fsa := self fsaFrom: node.
-    
-    self assert: fsa parse: 'ab'.	
-    self assert: fsa fail: 'a'.
-    self assert: fsa fail: 'b'.
-    self assert: fsa fail: 'ac'.
-!
-
-testA_Boptional
-    | parser |
-    parser := $a asParser, $b asParser optional.
-    node := parser asCompilerTree.
-    
-    fsa := self fsaFrom: node.
-    
-    self assert: fsa parse: 'ab'.	
-    self assert: fsa parse: 'ac' end: 1.	
-    self assert: fsa parse: 'a'.
-    self assert: fsa fail: 'b'.
-!
-
-testA_Boptionaloptional
-    | parser |
-    parser := ($a asParser, $b asParser optional) optional.
-    node := parser asCompilerTree.
-        
-    fsa := self fsaFrom: node.
-
-    self assert: fsa parse: ''.	
-    self assert: fsa parse: 'a'.	
-    self assert: fsa parse: 'ab'.	
-    self assert: fsa parse: 'b' end: 0.
-!
-
-testA_BorC_D
-    | parser |
-    parser := $a asParser, ($b asParser / $c asParser), $d asParser.
-    node := parser asCompilerTree.
+testAnyNode
+    node := PPCAnyNode new
+        yourself.
         
     fsa := self fsaFrom: node.
     
-    self assert: fsa parse: 'abd'.	
-    self assert: fsa parse: 'acd'.	
-    self assert: fsa fail: 'abc'.
-    self assert: fsa fail: 'add'.
-    self assert: fsa fail: 'ad'.
-!
-
-testAorAA
-    | parser |
-    parser := 'a' asParser / 'aa' asParser.
-    node := parser asCompilerTree.
-        
-    fsa := self fsaFrom: node.
-    
-    self assert: fsa parse: 'a'.	
-    self assert: fsa parse: 'aa' end: 1.	
-    self assert: fsa parse: 'aaaaaaa' end: 1.	
-    self assert: fsa fail: ''.
-    self assert: fsa fail: 'b'.
-!
-
-testAorAX_X
-    | parser |
-    parser := ('a' asParser / 'ax' asParser), $x asParser.
-    node := parser asCompilerTree.
-    
-    fsa := self fsaFrom: node.
-
-    self assert: fsa parse: 'ax'.	
-    self assert: fsa parse: 'axx' end: 2.	
-    self assert: fsa fail: 'a'.
-    self assert: fsa fail: 'x'.
-    self assert: fsa fail: ''.
-!
-
-testAorBC_X
-    | parser |
-    parser := ('a' asParser / 'bc' asParser), $x asParser.
-    node := parser asCompilerTree.
-        
-    fsa := self fsaFrom: node.
-
-    self assert: fsa parse: 'ax'.	
-    self assert: fsa parse: 'bcx' end: 3.	
-    self assert: fsa fail: 'bx'.
-    self assert: fsa fail: 'cx'.
-    self assert: fsa fail: 'a'.	
-    self assert: fsa fail: 'bc'.		
-!
-
-testAorB_Coptionaloptional
-    | parser |
-    parser := (($a asParser / $b asParser), $c asParser optional) optional.
-    node := parser asCompilerTree.
-        
-    fsa := self fsaFrom: node.
-
-    self assert: fsa parse: ''.	
-    self assert: fsa parse: 'a'.	
-    self assert: fsa parse: 'b'.	
-    self assert: fsa parse: 'ac'.	
-    self assert: fsa parse: 'bc'.	
-    self assert: fsa parse: 'ad' end: 1.	
-    self assert: fsa parse: 'bd' end: 1.	
-    self assert: fsa parse: 'd' end: 0.	
-    self assert: fsa parse: 'c' end: 0.
-!
-
-testAstarA
-    | parser |
-    parser := $a asParser star, $a asParser.
-    node := parser asCompilerTree.
-        
-    fsa := self fsaFrom: node.
-    
-    self assert: fsa fail: 'a'.
-    self assert: fsa fail: 'aa'.
-    self assert: fsa fail: 'aaa'.
-!
-
-testAstarB
-    | parser |
-    parser := $a asParser star, $b asParser.
-    node := parser asCompilerTree.
-        
-    fsa := self fsaFrom: node.
-    
-    self assert: fsa parse: 'b'.	
-    self assert: fsa parse: 'ab'.	
-    self assert: fsa parse: 'aaab'.	
-    self assert: fsa fail: 'a'.
-    self assert: fsa fail: 'ac'.
-    self assert: fsa fail: 'aac'.
-!
-
-testCharSet
-    | parser |
-    parser := #letter asParser.
-    node := parser asCompilerTree.
-        
-    fsa := self fsaFrom: node.
-    
-    self assert: fsa parse: 'a'.	
-    self assert: fsa parse: 'z'.	
-    self assert: fsa parse: 'A'.	
-    self assert: fsa parse: 'Z'.	
-    self assert: fsa fail: '_'.
-    self assert: fsa fail: '()'.
-    self assert: fsa fail: ''.
+    self assert: fsa parse: 'a'.
+    self assert: fsa parse: 'b'.
+    self assert: fsa parse: String cr.
+    self assert: fsa parse: String tab.
 !
 
 testCharSetPredicateNode
@@ -309,18 +122,14 @@
 self assert: fsa fail: 'fof'.		
 !
 
-testChoicePriorities
-    | parser |
-    parser := ($a asParser optional, $b asParser optional) / $a asParser.
-    node := parser asCompilerTree.
+testEndOfFileNode
+    node := PPCEndOfFileNode new
+        yourself.
         
     fsa := self fsaFrom: node.
     
-    self assert: fsa parse: 'ab'.	
-    self assert: fsa parse: 'a' end: 1.	
-    self assert: fsa parse: 'b' end: 1.	
-    self assert: fsa parse: ''.
-    self assert: fsa parse: 'c' end: 0.
+    self assert: fsa parse: '' end: 1.
+    self assert: fsa fail: 'a'.	
 !
 
 testLiteralNode
@@ -346,19 +155,6 @@
     self assert: fsa parse: ''.
 !
 
-testNot
-    | parser |
-    parser := 'aaa' asParser not, $a asParser plus.
-    node := parser asCompilerTree.
-    fsa := self fsaFrom: node.
-    
-    self assert: fsa parse: 'a'.	
-    self assert: fsa parse: 'aa'.	
-    self assert: fsa fail: 'aaa'.
-    self assert: fsa fail: 'aaaa'.
-    self assert: fsa fail: ''.
-!
-
 testNotNode
     | literal  |
     literal := PPCLiteralNode new
@@ -440,6 +236,38 @@
     self assert: fsa fail: 'boz'.				
 !
 
+testSequenceNode3
+    | literal1 literal2 literal3 choice |
+    literal1 := PPCLiteralNode new
+        literal: 'a';
+        yourself.
+    literal2 := PPCLiteralNode new
+        literal: 'b';
+        yourself.
+
+    literal3 := PPCLiteralNode new
+        literal: 'c';
+        yourself.
+
+
+    choice := PPCChoiceNode new
+        children: { literal1 . literal2 };
+        yourself.
+    
+    node := PPCSequenceNode new
+        children: { choice . literal3 };
+        yourself.
+        
+    fsa := self fsaFrom: node.
+    
+
+    self assert: fsa parse: 'ac'.
+    self assert: fsa parse: 'bc'.
+    self assert: fsa fail: 'a'.	
+    self assert: fsa fail: 'b'.		
+    self assert: fsa fail: 'c'.		
+!
+
 testStarNode
     | literal |
     literal := PPCLiteralNode new
@@ -457,6 +285,758 @@
     self assert: fsa parse: 'foofoofoo'.		
 ! !
 
+!PEGFsaGeneratorTest methodsFor:'complex'!
+
+testAAAAnot_Astar
+    | parser |
+    parser := 'aaaa' asParser not, ($a asParser star).
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: ''.	
+    self assert: fsa parse: 'a'.	
+    self assert: fsa parse: 'aa'.	
+    self assert: fsa parse: 'aaa'.
+
+    self assert: fsa fail: 'aaaa'.
+    self assert: fsa fail: 'aaaaa'.
+    self assert: fsa fail: 'aaaaaa'.
+    self assert: fsa fail: 'aaaaaaa'.
+!
+
+testAAAAorA_AA
+    | parser |
+    parser := ('aaaaa' asParser / 'a' asParser), 'aa' asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aaaaaaa'.	
+    self assert: fsa parse: 'aaa'.	
+    self assert: fsa parse: 'aaaa' end: 3.
+
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'aa'.
+    self assert: fsa fail: 'aaaaa'.
+    self assert: fsa fail: 'aaaaaa'.
+!
+
+testAAAnot_Aplus
+    | parser |
+    parser := 'aaa' asParser not, $a asParser plus.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'a'.	
+    self assert: fsa parse: 'aa'.	
+    self assert: fsa fail: ''.
+    self assert: fsa fail: 'aaa'.
+    self assert: fsa fail: 'aaaa'.
+    self assert: fsa fail: 'aaaaa'.
+!
+
+testAAAorA_A
+    | parser |
+    parser := ('aaa' asParser / 'a' asParser), 'a' asParser.
+    node := parser asCompilerTree.
+
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aaaa'.	
+    self assert: fsa parse: 'aa'.
+    self assert: fsa fail: 'aaa'.
+    self assert: fsa fail: 'a'.
+!
+
+testAAAorA_AA
+    | parser |
+    parser := ('aaa' asParser / 'a' asParser), 'aa' asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aaaaa'.	
+    self assert: fsa parse: 'aaaaaa' end: 5.	
+    self assert: fsa parse: 'aaaaaaa' end: 5.	
+
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'aa'.
+    self assert: fsa fail: 'aaa'.
+    self assert: fsa fail: 'aaaa'.
+!
+
+testAAAorA_Astar
+    | parser |
+    parser := (('aaa' asParser / 'a' asParser), 'a' asParser) star.
+    node := parser asCompilerTree.
+
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: ''.
+    self assert: fsa parse: 'aa'.
+    self assert: fsa parse: 'aaaa'.	
+    self assert: fsa parse: 'aaaaaa'.	
+    self assert: fsa parse: 'aaaaaaaa'.	
+
+    "So far the FSA cannot handle loops with such as tokens as aaa/a, a"
+    self flag: 'not working :('.
+    self assert: fsa parse: 'aaaaaaa' end: 4.	
+
+    self assert: fsa fail: 'aaa'.
+    self assert: fsa fail: 'a'.
+!
+
+testAAAstar_AA
+    | parser |
+    parser := ('aaa' asParser) star, 'aa' asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aa'.
+    self assert: fsa parse: 'aaaaa'.	
+    self assert: fsa parse: 'aaaaaaaa'.
+    
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'aaa'.
+    self assert: fsa fail: 'aaaa'.
+    self assert: fsa fail: 'aaaaaaa'.
+!
+
+testAAorA_A
+    | parser |
+    parser := ('aa' asParser / 'a' asParser), 'a' asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aaa'.	
+    self assert: fsa fail: 'aa'.
+    self assert: fsa fail: 'a'.
+!
+
+testAAorA_AAorA
+    | parser |
+    parser := ('aa' asParser / 'a' asParser), ('aa' asParser / 'a' asParser).
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aaaa'.	
+    self assert: fsa parse: 'aaa'.	
+
+    self assert: fsa fail: ''.
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'aa'.
+!
+
+testAAorA_A_B
+    | parser |
+    parser := ('aa' asParser / 'a' asParser), 'a' asParser, 'b' asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aaab'.	
+    self assert: fsa fail: 'aab'.
+!
+
+testAAplusA
+    | parser |
+    parser := 'aa' asParser plus, $a asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+
+    self assert: fsa parse: 'aaa'.	
+    self assert: fsa parse: 'aaaaa'.	
+    self assert: fsa parse: 'aaaaaaa'.	
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'aa'.
+    self assert: fsa fail: 'aaaa'.
+!
+
+testAAplusB
+    | parser |
+    parser := 'aa' asParser plus, $b asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aab'.	
+    self assert: fsa parse: 'aaaab'.	
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'aa'.
+    self assert: fsa fail: 'aaaa'.
+    self assert: fsa fail: 'aaaac'.
+!
+
+testAB
+    | parser |
+    parser := $a asParser, $b asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'ab'.	
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'b'.
+    self assert: fsa fail: 'ac'.
+!
+
+testA_Bnot
+    | parser |
+    parser := $a asParser, $b asParser not.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'a'.
+    self assert: fsa parse: 'ac' end: 1.	
+    self assert: fsa parse: 'aaa' end: 1.	
+    self assert: fsa fail: 'ab'.
+    self assert: fsa fail: 'b'.
+!
+
+testA_Boptional
+    | parser |
+    parser := $a asParser, $b asParser optional.
+    node := parser asCompilerTree.
+    
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'ab'.	
+    self assert: fsa parse: 'ac' end: 1.	
+    self assert: fsa parse: 'a'.
+    self assert: fsa fail: 'b'.
+!
+
+testA_Boptionaloptional
+    | parser |
+    parser := ($a asParser, $b asParser optional) optional.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+
+    self assert: fsa parse: ''.	
+    self assert: fsa parse: 'a'.	
+    self assert: fsa parse: 'ab'.	
+    self assert: fsa parse: 'b' end: 0.
+!
+
+testA_BorC_D
+    | parser |
+    parser := $a asParser, ($b asParser / $c asParser), $d asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'abd'.	
+    self assert: fsa parse: 'acd'.	
+    self assert: fsa fail: 'abc'.
+    self assert: fsa fail: 'add'.
+    self assert: fsa fail: 'ad'.
+!
+
+testAoptional_Boptional
+    | parser |
+    parser := $a asParser optional, $b asParser optional.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    self assert: fsa parse: 'ab'.	
+    self assert: fsa parse: 'ac' end: 1.	
+    self assert: fsa parse: 'bc' end: 1.	
+    self assert: fsa parse: 'a'.
+    self assert: fsa parse: 'b'.
+    self assert: fsa parse: 'c' end: 0.
+    self assert: fsa parse: ''.
+!
+
+testAoptionalstar
+    | parser |
+    parser := 'a' asParser optional star.
+    node := parser asCompilerTree.
+        
+    self should: [fsa := self fsaFrom: node] raise: Exception.
+    
+!
+
+testAorAA
+    | parser |
+    parser := 'a' asParser / 'aa' asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'a'.	
+    self assert: fsa parse: 'aa' end: 1.	
+    self assert: fsa parse: 'aaaaaaa' end: 1.	
+    self assert: fsa fail: ''.
+    self assert: fsa fail: 'b'.
+!
+
+testAorAX_X
+    | parser |
+    parser := ('a' asParser / 'ax' asParser), $x asParser.
+    node := parser asCompilerTree.
+    
+    fsa := self fsaFrom: node.
+
+    self assert: fsa parse: 'ax'.	
+    self assert: fsa parse: 'axx' end: 2.	
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'x'.
+    self assert: fsa fail: ''.
+!
+
+testAorBC_X
+    | parser |
+    parser := ('a' asParser / 'bc' asParser), $x asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+
+    self assert: fsa parse: 'ax'.	
+    self assert: fsa parse: 'bcx' end: 3.	
+    self assert: fsa fail: 'bx'.
+    self assert: fsa fail: 'cx'.
+    self assert: fsa fail: 'a'.	
+    self assert: fsa fail: 'bc'.		
+!
+
+testAorB_Coptionaloptional
+    | parser |
+    parser := (($a asParser / $b asParser), $c asParser optional) optional.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+
+    self assert: fsa parse: ''.	
+    self assert: fsa parse: 'a'.	
+    self assert: fsa parse: 'b'.	
+    self assert: fsa parse: 'ac'.	
+    self assert: fsa parse: 'bc'.	
+    self assert: fsa parse: 'ad' end: 1.	
+    self assert: fsa parse: 'bd' end: 1.	
+    self assert: fsa parse: 'd' end: 0.	
+    self assert: fsa parse: 'c' end: 0.
+!
+
+testAplusA
+    | parser |
+    parser := $a asParser plus, $a asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'aa'.
+    self assert: fsa fail: 'aaa'.
+!
+
+testAplusB
+    | parser |
+    parser := $a asParser plus, $b asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'ab'.	
+    self assert: fsa parse: 'aaab'.	
+    self assert: fsa parse: 'ab'.	
+
+    self assert: fsa fail: 'b'.
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'ac'.
+    self assert: fsa fail: 'aac'.
+!
+
+testAstarA
+    | parser |
+    parser := $a asParser star, $a asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'aa'.
+    self assert: fsa fail: 'aaa'.
+!
+
+testAstarB
+    | parser |
+    parser := $a asParser star, $b asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'b'.	
+    self assert: fsa parse: 'ab'.	
+    self assert: fsa parse: 'aaab'.	
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'ac'.
+    self assert: fsa fail: 'aac'.
+!
+
+testAstar_Bplus
+    | parser |
+    parser := 'a' asParser star, 'b' asParser plus.
+    node := parser asCompilerTree.
+        
+    
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'b'.
+    self assert: fsa parse: 'bbbb'.
+    self assert: fsa parse: 'aaaab'.
+
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'aaa'.
+!
+
+testCharSet
+    | parser |
+    parser := #letter asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'a'.	
+    self assert: fsa parse: 'z'.	
+    self assert: fsa parse: 'A'.	
+    self assert: fsa parse: 'Z'.	
+    self assert: fsa fail: '_'.
+    self assert: fsa fail: '()'.
+    self assert: fsa fail: ''.
+!
+
+testChoice
+    | parser |
+    parser := ($a asParser optional, $b asParser optional) / $a asParser.
+    node := parser asCompilerTree.
+    
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'ab'.	
+    self assert: fsa parse: 'a' end: 1.	
+    self assert: fsa parse: 'b' end: 1.	
+    self assert: fsa parse: ''.
+    self assert: fsa parse: 'c' end: 0.
+!
+
+testChoice2
+    | parser |
+    parser := 'aaa' asParser / 'aa' asParser / 'a' asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aaa'.	
+    self assert: fsa parse: 'aa'.
+    self assert: fsa parse: 'a'
+!
+
+testIdentity
+    | parser quot |
+    quot := $" asParser.
+    parser := quot, $a asParser star, quot.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: '""'.
+    self assert: fsa parse: '"a"'.
+    self assert: fsa parse: '"aa"'.
+    self assert: fsa parse: '"aaaaaaaa"'.
+!
+
+testKwPlus
+    | parser |
+    parser := (#word asParser plus, $: asParser) plus.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'foo:bar:baz:'.	
+    self assert: fsa parse: 'foo:bar:baz' end: 8.	
+
+    self assert: fsa fail: ''.
+    self assert: fsa fail: 'foo'.
+!
+
+testNot
+    | parser |
+    parser := 'aaa' asParser not, $a asParser plus.
+    node := parser asCompilerTree.
+    
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'a'.	
+    self assert: fsa parse: 'aa'.	
+    self assert: fsa fail: 'aaa'.
+    self assert: fsa fail: 'aaaa'.
+    self assert: fsa fail: 'aaaaa'.
+    self assert: fsa fail: ''.
+!
+
+testOptional
+    | parser |
+    parser := ($a asParser optional, $b asParser optional) / $a asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'ab'.	
+    self assert: fsa parse: 'a' end: 1.	
+    self assert: fsa parse: 'b' end: 1.	
+    self assert: fsa parse: ''.
+    self assert: fsa parse: 'c' end: 0.
+!
+
+testOptional2
+    | parser |
+    parser := ($a asParser, $b asParser optional) / 'ac' asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'ab'.	
+    self assert: fsa parse: 'a'.	
+    self assert: fsa fail: 'b'.	
+    self assert: fsa parse: 'ac' end: 1.	
+!
+
+testPlus
+    | parser |
+    parser := ('aa' asParser) plus, ('a' asParser / 'aa' asParser).
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aaa'.	
+    self assert: fsa parse: 'aaaaa'.
+
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'aa'.
+    self assert: fsa fail: 'aaaa'.
+!
+
+testPlus2
+    | parser |
+    parser := ('aaaaaa' asParser / 'a' asParser) plus.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'a'.	
+    self assert: fsa parse: 'aa'.
+    self assert: fsa parse: 'aaa'.
+    self assert: fsa parse: 'aaaa'.
+    self assert: fsa parse: 'aaaaa'.
+    self assert: fsa parse: 'aaaaaa'.
+    self assert: fsa parse: 'aaaaaaa'.
+
+    self assert: fsa fail: ''.
+!
+
+testPlus3
+    | parser |
+    parser := ('aaaaaa' asParser / 'aa' asParser) plus.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aa'.
+    self assert: fsa parse: 'aaaa'.
+    self assert: fsa parse: 'aaaaaa'.
+
+    self assert: fsa fail: ''.
+    self assert: fsa fail: 'a'.
+
+    self assert: fsa parse: 'aaa' end: 2.
+    self assert: fsa parse: 'aaaaa' end: 4.
+    self assert: fsa parse: 'aaaaaaa' end: 6.
+    
+!
+
+testPlus4
+    | parser |
+    parser := ('aaa' asParser / 'aa' asParser / 'a' asParser) plus.
+    node := parser asCompilerTree.
+        
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'a'.
+    self assert: fsa parse: 'aa'.
+    self assert: fsa parse: 'aaa'.
+    self assert: fsa parse: 'aaaa'.
+    self assert: fsa parse: 'aaaaa'.
+    self assert: fsa parse: 'aaaaaa'.
+!
+
+testPlus5
+    | parser |
+    parser := ('aaa' asParser / 'aa' asParser / 'b' asParser) plus.
+    node := parser asCompilerTree.
+        
+        
+    fsa := self fsaFrom: node.
+
+
+    self assert: fsa parse: 'b'.
+    self assert: fsa parse: 'bb'.
+    self assert: fsa parse: 'bbaaa'.
+    self assert: fsa parse: 'bbaaabbaa'.
+    
+    self assert: fsa parse: 'aa'.
+    self assert: fsa parse: 'aaa'.
+    self assert: fsa parse: 'aaaaa'.
+    self assert: fsa parse: 'aaaaaa'.
+    self assert: fsa parse: 'aaaaaab'.
+    
+    self assert: fsa parse: 'bba' end: 2.
+    self assert: fsa parse: 'aaaa' end: 3.
+!
+
+testSequence
+    | parser |
+    parser := ('aa' asParser plus), ('aa' asParser plus).
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa fail: 'a'.
+    self assert: fsa fail: 'aa'.
+    self assert: fsa fail: 'aaa'.
+    self assert: fsa fail: 'aaaa'.
+    self assert: fsa fail: 'aaaaa'.
+    self assert: fsa fail: 'aaaaaa'.
+!
+
+testSequence2
+    | parser |
+    parser := ('aa' asParser star), ('bb' asParser star).
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'aa'.
+    self assert: fsa parse: 'aaaa'.
+    self assert: fsa parse: 'aaaaaa'.
+    self assert: fsa parse: 'aaaaaaaa'.
+
+    self assert: fsa parse: 'a' end: 0.
+    self assert: fsa parse: 'aaa' end: 2.
+    self assert: fsa parse: 'aaaaa' end: 4.
+    self assert: fsa parse: 'aaaaaaa' end: 6.
+    self assert: fsa parse: 'aaaaaaaaa' end: 8.
+!
+
+testSequence3
+    | parser |
+    parser := 'a' asParser, 'b' asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: (fsa states noneSatisfy: [ :s | s isFsaFailure  ]).
+!
+
+testSequence4
+    | parser |
+    parser := 'a' asParser star, 'b' asParser.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: (fsa states noneSatisfy: [ :s | s isFsaFailure  ]).
+!
+
+testUnaryOrKw
+    | parser unary kw |
+    unary := #letter asParser plus, $: asParser not.
+    kw := #letter asParser plus, $: asParser.
+    parser := unary / kw.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'foo'.	
+    self assert: fsa parse: 'foo:'.	
+
+    self assert: fsa fail: '123'.
+!
+
+testUnaryOrKwPlus
+    | parser unary kw |
+    unary := #letter asParser plus, $: asParser not.
+    kw := #letter asParser plus, $: asParser.
+    parser := (unary / kw) plus.
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'foo'.	
+    self assert: fsa parse: 'foo:'.	
+    self assert: fsa parse: 'foo:bar:'.	
+    self assert: fsa fail: '123'.
+!
+
+testUnaryOrMultiword
+    | parser unary kw |
+    unary := #letter asParser plus, $: asParser not.
+    kw := #letter asParser plus, $: asParser.
+    parser := unary / (kw plus).
+    node := parser asCompilerTree.
+        
+    fsa := self fsaFrom: node.
+    
+    self assert: fsa parse: 'foo'.	
+    self assert: fsa parse: 'foo:'.	
+    self assert: fsa parse: 'foo:bar:'.	
+    self assert: fsa fail: '123'.
+! !
+
+!PEGFsaGeneratorTest methodsFor:'recursive'!
+
+testRecursive
+    | parser |
+    parser := PPDelegateParser new.
+    
+    parser setParser: ($a asParser, parser) / $b asParser.
+    node := parser asCompilerTree.
+
+    fsa :=	 self fsaFrom: node.
+
+    self assert: fsa parse: 'b'.
+    self assert: fsa parse: 'ab'.
+    self assert: fsa parse: 'aaab'.
+    self assert: fsa fail: 'aaa'.
+    self assert: fsa fail: ''.	
+    self assert: fsa fail: 'aac'.		
+!
+
+testRecursive2
+    | parser |
+    parser := PPDelegateParser new.
+    
+    parser setParser: (($a asParser / $b asParser), parser) / $c asParser.
+    node := parser asCompilerTree.
+
+    fsa :=	 self fsaFrom: node.
+
+    self assert: fsa parse: 'c'.
+    self assert: fsa parse: 'ac'.
+    self assert: fsa parse: 'bc'.
+    self assert: fsa parse: 'ababc'.
+    self assert: fsa fail: 'aaab'.
+    self assert: fsa fail: 'ab'.	
+! !
+
 !PEGFsaGeneratorTest class methodsFor:'documentation'!
 
 version_HG
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/tests/PEGFsaIntegrationTest.st	Mon Aug 17 12:56:02 2015 +0100
@@ -0,0 +1,174 @@
+"{ Package: 'stx:goodies/petitparser/compiler/tests' }"
+
+"{ NameSpace: Smalltalk }"
+
+TestCase subclass:#PEGFsaIntegrationTest
+	instanceVariableNames:'result node fsa generator interpreter parser1 parser2 parser3'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitCompiler-Tests-FSA'
+!
+
+
+!PEGFsaIntegrationTest methodsFor:'as yet unclassified'!
+
+determinizator
+    ^ PEGFsaDeterminizator new
+!
+
+failScan: input token: token
+    | stream |
+    stream := input asPetitStream.
+
+    result := interpreter interpret: fsa on: stream.
+    self assert: (result includes: token) not.
+
+    ^ result
+!
+
+fsaFrom: aNode
+    ^ (aNode accept: generator)
+        determinize;
+        minimize;
+        yourself
+!
+
+merge
+    | startState fsa1 fsa2 fsa3 |
+    fsa := PEGFsa new.
+    startState := PEGFsaState new.
+
+    fsa addState: startState.	
+    fsa startState: startState.
+
+    fsa1 := self fsaFrom: parser1 asCompilerTree.
+    fsa1 retval: #token1.
+    fsa adopt: fsa1.
+    fsa addTransitionFrom: startState to: fsa1 startState.
+
+    fsa2 := self fsaFrom: parser2 asCompilerTree.
+    fsa2 retval: #token2.
+    fsa adopt: fsa2.
+    fsa addTransitionFrom: startState to: fsa2 startState.
+
+    parser3 isNil ifFalse: [ 
+        fsa3 := self fsaFrom: parser3 asCompilerTree.
+        fsa3 retval: #token3.
+        fsa adopt: fsa3.
+        fsa addTransitionFrom: startState to: fsa3 startState.
+    ].
+    
+    self determinizator determinize: fsa.
+    fsa minimize.
+!
+
+scan: input token: token
+    ^ self scan: input token: token position: input size
+!
+
+scan: input token: token position: position
+    | stream |
+    stream := input asPetitStream.
+
+    result := interpreter interpret: fsa on: stream.
+
+    self assert: (result includesKey: token).
+    self assert: (result at: token) = position.
+
+    ^ result
+!
+
+setUp
+    super setUp.
+    generator := PEGFsaGenerator new.
+    interpreter := PEGFsaInterpret new.	
+!
+
+testFooOrId
+    parser1 := 'foo' asParser.