Merged JK's version from Monticello
authorJan Vrany <jan.vrany@fit.cvut.cz>
Mon, 13 Apr 2015 22:00:44 +0100
changeset 427 a7f5e6de19d2
parent 426 2a65c972b937
child 428 b879012e366e
Merged JK's version from Monticello Name: PetitParser-JanKurs.275 Author: JanKurs Time: 31-03-2015, 05:51:24.398 PM UUID: 9ab3be24-8393-4794-a7e6-e318f3195673 Name: PetitTests-JanKurs.73 Author: JanKurs Time: 21-02-2015, 01:10:13.115 PM UUID: de4f77e3-2d07-476b-855e-69f845edfc7c
.hgignore
Make.proto
Make.spec
PPCharSetPredicate.st
PPConditionalParser.st
PPContext.st
PPEndOfFileParser.st
PPExpressionParser.st
PPParser.st
PPPredicateObjectParser.st
PPStartOfLineParser.st
PPStartOfLogicalLineParser.st
PPStartOfWordParser.st
PPStream.st
abbrev.stc
bc.mak
bmake.bat
lccmake.bat
libInit.cc
mingwmake.bat
stx_goodies_petitparser.st
tests/Make.proto
tests/Make.spec
tests/PPAbstractParserTest.st
tests/PPArithmeticParser.st
tests/PPComposedTest.st
tests/PPConditionalParserTest.st
tests/PPConditionalParserTests.st
tests/PPContextMementoTest.st
tests/PPContextTest.st
tests/PPExtensionTest.st
tests/PPLambdaParser.st
tests/PPObjectTest.st
tests/PPParserTest.st
tests/PPPredicateTest.st
tests/PPTokenTest.st
tests/abbrev.stc
tests/bc.mak
tests/libInit.cc
tests/stx_goodies_petitparser_tests.st
vcmake.bat
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Mon Apr 13 22:00:44 2015 +0100
@@ -0,0 +1,16 @@
+
+syntax: glob
+*Init.c   
+makefile
+*.so
+*.H
+*.o
+*.STH
+*.sc
+objbc
+objvc
+*.class
+java/libs/*.jar
+java/libs-src/*.jar
+*-Test.xml
+st.chg
--- a/Make.proto	Mon Apr 13 14:19:55 2015 +0100
+++ b/Make.proto	Mon Apr 13 22:00:44 2015 +0100
@@ -140,7 +140,7 @@
 
 
 # build all packages containing referenced classes for this package
-# they are nor needed to compile the package
+# they are not needed to compile the package (but later, to load it)
 references:
 
 
@@ -165,6 +165,7 @@
 $(OUTDIR)PPToken.$(O) PPToken.$(H): PPToken.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)stx_goodies_petitparser.$(O) stx_goodies_petitparser.$(H): stx_goodies_petitparser.st $(INCLUDE_TOP)/stx/libbasic/LibraryDefinition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProjectDefinition.$(H) $(STCHDR)
 $(OUTDIR)PPDelegateParser.$(O) PPDelegateParser.$(H): PPDelegateParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPEndOfFileParser.$(O) PPEndOfFileParser.$(H): PPEndOfFileParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPEndOfLineParser.$(O) PPEndOfLineParser.$(H): PPEndOfLineParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPEpsilonParser.$(O) PPEpsilonParser.$(H): PPEpsilonParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPFailingParser.$(O) PPFailingParser.$(H): PPFailingParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
@@ -174,11 +175,14 @@
 $(OUTDIR)PPPredicateParser.$(O) PPPredicateParser.$(H): PPPredicateParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPStartOfLine.$(O) PPStartOfLine.$(H): PPStartOfLine.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPStartOfLineParser.$(O) PPStartOfLineParser.$(H): PPStartOfLineParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPStartOfLogicalLineParser.$(O) PPStartOfLogicalLineParser.$(H): PPStartOfLogicalLineParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPStartOfWordParser.$(O) PPStartOfWordParser.$(H): PPStartOfWordParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPUnresolvedParser.$(O) PPUnresolvedParser.$(H): PPUnresolvedParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPActionParser.$(O) PPActionParser.$(H): PPActionParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPDelegateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPAndParser.$(O) PPAndParser.$(H): PPAndParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPDelegateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPChoiceParser.$(O) PPChoiceParser.$(H): PPChoiceParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPListParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPCompositeParser.$(O) PPCompositeParser.$(H): PPCompositeParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPDelegateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)PPConditionalParser.$(O) PPConditionalParser.$(H): PPConditionalParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPDelegateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPEndOfInputParser.$(O) PPEndOfInputParser.$(H): PPEndOfInputParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPDelegateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPExpressionParser.$(O) PPExpressionParser.$(H): PPExpressionParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPDelegateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)PPFlattenParser.$(O) PPFlattenParser.$(H): PPFlattenParser.st $(INCLUDE_TOP)/stx/goodies/petitparser/PPDelegateParser.$(H) $(INCLUDE_TOP)/stx/goodies/petitparser/PPParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
--- a/Make.spec	Mon Apr 13 14:19:55 2015 +0100
+++ b/Make.spec	Mon Apr 13 22:00:44 2015 +0100
@@ -61,6 +61,7 @@
 	PPToken \
 	stx_goodies_petitparser \
 	PPDelegateParser \
+	PPEndOfFileParser \
 	PPEndOfLineParser \
 	PPEpsilonParser \
 	PPFailingParser \
@@ -70,11 +71,14 @@
 	PPPredicateParser \
 	PPStartOfLine \
 	PPStartOfLineParser \
+	PPStartOfLogicalLineParser \
+	PPStartOfWordParser \
 	PPUnresolvedParser \
 	PPActionParser \
 	PPAndParser \
 	PPChoiceParser \
 	PPCompositeParser \
+	PPConditionalParser \
 	PPEndOfInputParser \
 	PPExpressionParser \
 	PPFlattenParser \
@@ -110,6 +114,7 @@
     $(OUTDIR_SLASH)PPToken.$(O) \
     $(OUTDIR_SLASH)stx_goodies_petitparser.$(O) \
     $(OUTDIR_SLASH)PPDelegateParser.$(O) \
+    $(OUTDIR_SLASH)PPEndOfFileParser.$(O) \
     $(OUTDIR_SLASH)PPEndOfLineParser.$(O) \
     $(OUTDIR_SLASH)PPEpsilonParser.$(O) \
     $(OUTDIR_SLASH)PPFailingParser.$(O) \
@@ -119,11 +124,14 @@
     $(OUTDIR_SLASH)PPPredicateParser.$(O) \
     $(OUTDIR_SLASH)PPStartOfLine.$(O) \
     $(OUTDIR_SLASH)PPStartOfLineParser.$(O) \
+    $(OUTDIR_SLASH)PPStartOfLogicalLineParser.$(O) \
+    $(OUTDIR_SLASH)PPStartOfWordParser.$(O) \
     $(OUTDIR_SLASH)PPUnresolvedParser.$(O) \
     $(OUTDIR_SLASH)PPActionParser.$(O) \
     $(OUTDIR_SLASH)PPAndParser.$(O) \
     $(OUTDIR_SLASH)PPChoiceParser.$(O) \
     $(OUTDIR_SLASH)PPCompositeParser.$(O) \
+    $(OUTDIR_SLASH)PPConditionalParser.$(O) \
     $(OUTDIR_SLASH)PPEndOfInputParser.$(O) \
     $(OUTDIR_SLASH)PPExpressionParser.$(O) \
     $(OUTDIR_SLASH)PPFlattenParser.$(O) \
--- a/PPCharSetPredicate.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/PPCharSetPredicate.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser' }"
 
+"{ NameSpace: Smalltalk }"
+
 Object subclass:#PPCharSetPredicate
 	instanceVariableNames:'block classification'
 	classVariableNames:''
@@ -33,7 +35,7 @@
 	classification := Array new: 255.
 	1 to: classification size do: [ :index |
 		classification at: index put: (block
-			value: (Character value: index)) ]
+			value: (Character codePoint: index)) ]
 ! !
 
 !PPCharSetPredicate class methodsFor:'documentation'!
@@ -49,3 +51,4 @@
 version_SVN
     ^ '§Id: PPCharSetPredicate.st 4 2010-12-18 17:02:23Z kursjan §'
 ! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PPConditionalParser.st	Mon Apr 13 22:00:44 2015 +0100
@@ -0,0 +1,33 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+"{ NameSpace: Smalltalk }"
+
+PPDelegateParser subclass:#PPConditionalParser
+	instanceVariableNames:'block'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitParser-Parsers'
+!
+
+!PPConditionalParser class methodsFor:'as yet unclassified'!
+
+on: aPPParser block: block
+	^ (PPConditionalParser on: aPPParser)
+		block: block;
+		yourself
+! !
+
+!PPConditionalParser methodsFor:'accessing'!
+
+block: aBlock
+	block := aBlock
+! !
+
+!PPConditionalParser methodsFor:'parsing'!
+
+parseOn: aPPContext
+	^ (block value: aPPContext) 
+		ifTrue: [ parser parseOn: aPPContext ]
+		ifFalse: [ PPFailure message: block asString, ' was not evaluated to true.' context: aPPContext ]
+! !
+
--- a/PPContext.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/PPContext.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,7 +1,9 @@
 "{ Package: 'stx:goodies/petitparser' }"
 
+"{ NameSpace: Smalltalk }"
+
 Object subclass:#PPContext
-	instanceVariableNames:'stream root properties globals'
+	instanceVariableNames:'stream root properties globals furthestFailure'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitParser-Core'
@@ -17,8 +19,6 @@
 		yourself
 ! !
 
-
-
 !PPContext methodsFor:'accessing-globals'!
 
 globalAt: aKey
@@ -140,16 +140,16 @@
 furthestFailure
 	" the furthest failure encountered while parsing the input stream "
 	
-	^ self globalAt: #furthestFailure ifAbsent: [ nil ]
+	"^ self globalAt: #furthestFailure ifAbsent: [ nil ]"
+	"performance optimization:"
+	^ furthestFailure
 !
 
 noteFailure: aPPFailure
 	"record the furthest failure encountered while parsing the input stream "
 
-	| furthestFailure |
-	furthestFailure := self furthestFailure.
 	( furthestFailure isNil or: [ aPPFailure position > furthestFailure position ]) 
-		ifTrue: [ self globalAt: #furthestFailure put: aPPFailure ].
+		ifTrue: [ furthestFailure := aPPFailure ].
 ! !
 
 !PPContext methodsFor:'initialization'!
@@ -211,6 +211,15 @@
 	]
 ! !
 
+!PPContext methodsFor:'printing'!
+
+printOn: aStream
+	super printOn: aStream.
+	aStream nextPut: $:.
+	aStream nextPut: $ .
+	stream printOn: aStream
+! !
+
 !PPContext methodsFor:'stream mimicry'!
 
 atEnd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PPEndOfFileParser.st	Mon Apr 13 22:00:44 2015 +0100
@@ -0,0 +1,38 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+"{ NameSpace: Smalltalk }"
+
+PPParser subclass:#PPEndOfFileParser
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitParser-Parsers'
+!
+
+!PPEndOfFileParser methodsFor:'as yet unclassified'!
+
+acceptsEpsilon
+	^ true
+!
+
+exampleOn: aStream 
+	aStream nextPutAll: #'end-of-input'
+!
+
+isNullable 
+	^ true
+!
+
+nonEmpty
+	"I know I am empty, but it does not count in my case, I represent virtual non-existent character"
+	^ self
+!
+
+parseOn: aPPContext
+	(aPPContext atEnd) ifFalse:
+	[
+		^ PPFailure message: 'end of input expected' context: aPPContext.
+	].
+	^ #'end-of-input'
+! !
+
--- a/PPExpressionParser.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/PPExpressionParser.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser' }"
 
+"{ NameSpace: Smalltalk }"
+
 PPDelegateParser subclass:#PPExpressionParser
 	instanceVariableNames:'operators'
 	classVariableNames:''
@@ -19,7 +21,7 @@
 !
 
 build: aParser prefix: aChoiceParser
-	^ aChoiceParser star , aParser map: [ :ops :term | ops reversed inject: term into: [ :result :operator | operator first value: operator second value: result ] ]
+	^ aChoiceParser star , aParser map: [ :ops :term | ops reverse inject: term into: [ :result :operator | operator first value: operator second value: result ] ]
 !
 
 build: aParser right: aChoiceParser
@@ -113,3 +115,4 @@
 version_SVN
     ^ '§Id: PPExpressionParser.st 2 2010-12-17 18:44:23Z vranyj1 §'
 ! !
+
--- a/PPParser.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/PPParser.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser' }"
 
+"{ NameSpace: Smalltalk }"
+
 Object subclass:#PPParser
 	instanceVariableNames:'properties'
 	classVariableNames:''
@@ -18,15 +20,6 @@
 	^ self basicNew initialize
 ! !
 
-
-
-
-
-
-
-
-
-
 !PPParser methodsFor:'accessing'!
 
 children
@@ -111,7 +104,8 @@
 	result := self parseOn: context.
 	
 	"Return the furthest failure, it gives better results than the last failure"
-	result isPetitFailure ifTrue: [ ^ context furthestFailure ].
+	(result isPetitFailure and: [ context furthestFailure notNil]) 
+		ifTrue: [ ^ context furthestFailure ].
 	^ result
 	
 !
@@ -312,6 +306,10 @@
 	"
 	
 	^ PPLimitedChoiceParser with: self with: aParser
+!
+
+if: aBlock
+	^ PPConditionalParser on: self block: aBlock
 ! !
 
 !PPParser methodsFor:'operators-convenience'!
@@ -384,10 +382,34 @@
 	^ self trim: #blank asParser
 !
 
+trimLeft
+	"Answer a new parser that consumes spaces before the receiving parser."
+	
+	^ self trimSpacesLeft
+!
+
+trimRight
+	"Answer a new parser that consumes spaces after the receiving parser."
+	
+	^ self trimSpacesRight
+!
+
 trimSpaces
 	"Answer a new parser that consumes spaces before and after the receiving parser."
 	
 	^ self trim: #space asParser
+!
+
+trimSpacesLeft
+	"Answer a new parser that consumes spaces before the receiving parser."
+	
+	^ (#space asParser star, self) ==> #second
+!
+
+trimSpacesRight
+	"Answer a new parser that consumes spaces after the receiving parser."
+	
+	^ (self, #space asParser star) ==> #first
 ! !
 
 !PPParser methodsFor:'operators-repeating'!
--- a/PPPredicateObjectParser.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/PPPredicateObjectParser.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser' }"
 
+"{ NameSpace: Smalltalk }"
+
 PPPredicateParser subclass:#PPPredicateObjectParser
 	instanceVariableNames:''
 	classVariableNames:''
@@ -7,6 +9,13 @@
 	category:'PetitParser-Parsers'
 !
 
+PPPredicateObjectParser class instanceVariableNames:'cache'
+
+"
+ No other class instance variables are inherited by this class.
+"
+!
+
 
 !PPPredicateObjectParser class methodsFor:'instance creation'!
 
@@ -23,10 +32,33 @@
 	^ PPStartOfLineParser new.
 ! !
 
+!PPPredicateObjectParser class methodsFor:'cache'!
+
+cacheAt: aSymbol ifAbsentPut: aBlock
+
+	cache ifNil: [ ^aBlock value ].
+	^(cache
+		at: aSymbol
+		ifAbsentPut: aBlock) copy
+!
+
+useCache: aBoolean
+"
+	PPPredicateObjectParser useCache: true.
+	PPPredicateObjectParser useCache: false.
+"
+	cache := aBoolean 
+		ifTrue: [ Dictionary new ]
+		ifFalse: [ nil ]
+! !
+
 !PPPredicateObjectParser class methodsFor:'factory-chars'!
 
 blank
-	^ self chars: (String with: Character space with: Character tab) message: 'blank expected'
+	^self
+		cacheAt: #'blank'
+		ifAbsentPut: [ self
+			chars: (String with: Character space with: Character tab) message: 'blank expected' ]
 !
 
 char: aCharacter
@@ -42,64 +74,90 @@
 !
 
 cr
-	^ self char: (Character codePoint: 13) message: 'carriage return expected'
+	^self
+		cacheAt: #'cr'
+		ifAbsentPut: [ self char: (Character codePoint: 13) message: 'carriage return expected' ]
 !
 
 digit
-	^ self on: (PPCharSetPredicate on: [ :char | char isDigit ]) message: 'digit expected'
+	^self
+		cacheAt: #'digit'
+		ifAbsentPut: [ self on: (PPCharSetPredicate on: [ :char | char isDigit ]) message: 'digit expected' ]
 !
 
 hex
-	^ self 
+	^self
+		cacheAt: #'hex'
+		ifAbsentPut: [ self
 		on: (PPCharSetPredicate on: [ :char | 
 			(char between: $0 and: $9) 
 				or: [ (char between: $a and: $f) 
 				or: [ (char between: $A and: $F) ] ] ])
-		message: 'hex digit expected'
+		message: 'hex digit expected' ]
 !
 
 letter
-	^ self on: (PPCharSetPredicate on: [ :char | char isLetter ]) message: 'letter expected'
+	^self
+		cacheAt: #'letter'
+		ifAbsentPut: [ self on: (PPCharSetPredicate on: [ :char | char isLetter ]) message: 'letter expected' ]
 !
 
 lf
-	^ self char: (Character codePoint: 10)
+	^self
+		cacheAt: #'lf'
+		ifAbsentPut: [ self char: (Character codePoint: 10) ]
 !
 
 lowercase
-	^ self on: (PPCharSetPredicate on: [ :char | char isLowercase ]) message: 'lowercase letter expected'
+	^self
+		cacheAt: #'lowercase'
+		ifAbsentPut: [ self on: (PPCharSetPredicate on: [ :char | char isLowercase ]) message: 'lowercase letter expected' ]
 !
 
 newline
-	^ self chars: (String with: (Character codePoint: 13) with: (Character codePoint: 10)) message: 'newline expected'
+	^self
+		cacheAt: #'newline'
+		ifAbsentPut: [ self chars: (String with: (Character codePoint: 13) with: (Character codePoint: 10)) message: 'newline expected' ]
 !
 
 punctuation
-	^ self chars: '.,"''?!!;:#$%&()*+-/<>=@[]\^_{}|~' message: 'punctuation expected'
+	^self
+		cacheAt: #'punctuation'
+		ifAbsentPut: [ self chars: '.,"''?!!;:#$%&()*+-/<>=@[]\^_{}|~' message: 'punctuation expected' ]
 !
 
 space
-	^ self on: (PPCharSetPredicate on: [ :char | char isSeparator ]) message: 'separator expected'
+	^self
+		cacheAt: #'space'
+		ifAbsentPut: [ self on: (PPCharSetPredicate on: [ :char | char isSeparator ]) message: 'separator expected' ]
 !
 
 tab
-	^ self char: Character tab message: 'tab expected'
+	^self
+		cacheAt: #'tab'
+		ifAbsentPut: [ self char: Character tab message: 'tab expected' ]
 !
 
 uppercase
-	^ self on: (PPCharSetPredicate on: [ :char | char isUppercase ]) message: 'uppercase letter expected'
+	^self
+		cacheAt: #'uppercase'
+		ifAbsentPut: [ self on: (PPCharSetPredicate on: [ :char | char isUppercase ]) message: 'uppercase letter expected' ]
 !
 
 word
-	^ self on: (PPCharSetPredicate on: [ :char | char isAlphaNumeric ]) message: 'letter or digit expected'
+	^self
+		cacheAt: #'word'
+		ifAbsentPut: [ self on: (PPCharSetPredicate on: [ :char | char isAlphaNumeric ]) message: 'letter or digit expected' ]
 ! !
 
 !PPPredicateObjectParser class methodsFor:'factory-objects'!
 
 any
-	^ self
-		on: [ :each | true ] message: 'input expected'
-		negated: [ :each | false ] message: 'no input expected'
+	^self
+		cacheAt: #'any'
+		ifAbsentPut: [ self
+			on: [ :each | true ] message: 'input expected'
+			negated: [ :each | false ] message: 'no input expected' ]
 !
 
 anyExceptAnyOf: aCollection
@@ -125,6 +183,11 @@
 	^ PPEndOfLineParser new.
 !
 
+eof
+	
+	^ PPEndOfFileParser new
+!
+
 expect: anObject
 	^ self expect: anObject message: anObject printString , ' expected'
 !
@@ -133,9 +196,18 @@
 	^ self 
 		on: [ :each | each = anObject ] message: aString
 		negated: [ :each | each ~= anObject ] message: 'no ' , aString
+!
+
+startOfLogicalLine
+	
+	^ PPStartOfLogicalLineParser new.
+!
+
+startOfWord
+	
+	^ PPStartOfWordParser new.
 ! !
 
-
 !PPPredicateObjectParser methodsFor:'initialization'!
 
 initializeOn: aBlock message: aString negated: aNegatedBlock message: aNegatedString
--- a/PPStartOfLineParser.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/PPStartOfLineParser.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser' }"
 
+"{ NameSpace: Smalltalk }"
+
 PPParser subclass:#PPStartOfLineParser
 	instanceVariableNames:''
 	classVariableNames:''
@@ -7,6 +9,7 @@
 	category:'PetitParser-Parsers'
 !
 
+
 !PPStartOfLineParser methodsFor:'parsing'!
 
 parseOn: aPPContext
@@ -16,3 +19,10 @@
 	^ PPFailure message: 'Start of line expected' context: aPPContext at: aPPContext position
 ! !
 
+!PPStartOfLineParser class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PPStartOfLogicalLineParser.st	Mon Apr 13 22:00:44 2015 +0100
@@ -0,0 +1,34 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+"{ NameSpace: Smalltalk }"
+
+PPParser subclass:#PPStartOfLogicalLineParser
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitParser-Parsers'
+!
+
+!PPStartOfLogicalLineParser methodsFor:'as yet unclassified'!
+
+isBlank: character
+	^ (character == Character space or: [character == Character tab])
+!
+
+parseOn: aPPContext
+	aPPContext peek isAlphaNumeric ifFalse: [ 
+		^ PPFailure message: 'Start of logical line expected' context: aPPContext 
+	].
+
+	aPPContext isStartOfLine ifTrue: [ ^ #startOfLogicalLine ].
+	
+	
+	[ aPPContext position ~= 0 ] whileTrue: [  
+		aPPContext back.
+		(self isBlank: aPPContext peek) ifFalse: [ 
+			^ PPFailure message: 'Start of logical line expected' context: aPPContext
+		].
+		aPPContext isStartOfLine ifTrue: [ ^ #startOfLogicalLine ].
+	]
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PPStartOfWordParser.st	Mon Apr 13 22:00:44 2015 +0100
@@ -0,0 +1,42 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+"{ NameSpace: Smalltalk }"
+
+PPParser subclass:#PPStartOfWordParser
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitParser-Parsers'
+!
+
+!PPStartOfWordParser methodsFor:'as yet unclassified'!
+
+acceptsEpsilon
+	^ true
+!
+
+parseOn: aPPContext
+	aPPContext atEnd ifTrue: [  
+		^ PPFailure message: 'Start of word expected' context: aPPContext at: aPPContext position 
+	].
+
+	(aPPContext position == 0) ifTrue: [ 
+		(aPPContext peek isAlphaNumeric) ifTrue: [ 
+			^ #startOfWord
+		] ifFalse: [ 
+			^ PPFailure message: 'Start of word expected' context: aPPContext at: aPPContext position 
+	 	]
+	].
+
+	aPPContext back.
+	aPPContext peek isAlphaNumeric ifTrue: [
+		^ PPFailure message: 'Start of word expected' context: aPPContext at: aPPContext position 
+	].
+	aPPContext next.
+	
+	^ aPPContext peek isAlphaNumeric ifTrue: [ #startOfWord ] ifFalse: [ 
+		PPFailure message: 'Start of word expected' context: aPPContext at: aPPContext position 
+	]
+	
+! !
+
--- a/PPStream.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/PPStream.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,14 +1,15 @@
 "{ Package: 'stx:goodies/petitparser' }"
 
+"{ NameSpace: Smalltalk }"
+
 ReadStream subclass:#PPStream
-	instanceVariableNames:''
+	instanceVariableNames:'newlines'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitParser-Core'
 !
 
 
-
 !PPStream methodsFor:'accessing'!
 
 collection
@@ -59,6 +60,56 @@
 	^ self
 ! !
 
+!PPStream methodsFor:'positioning'!
+
+column: pos
+	| nl |
+	(pos = -1) ifTrue: [  ^ 0 ].
+	(pos > readLimit) ifTrue: [ ^ self error: 'Out of limit' ].
+	
+	nl := self newlines.
+	nl keysAndValuesDo: [ :index :value |
+		(value > pos) ifTrue: [ ^ pos - (nl at: (index - 1)) + 1]
+	].	
+
+	^ pos - (nl at: (nl size )) + 1
+!
+
+fillNewlines
+	| tmp line |
+	newlines := OrderedCollection new.	
+	
+	tmp := position.
+	line := 0.
+	
+	(0 to: readLimit) do: [:index |
+		position := index.
+		self isStartOfLine ifTrue: [ newlines add: position ]
+	].
+	position := tmp.
+	newlines := newlines asArray.
+	^ newlines
+!
+
+line: pos
+	| nl |
+	(pos = -1) ifTrue: [  ^ 0 ].
+	(pos > readLimit) ifTrue: [ ^ self error: 'Out of limit' ].
+	
+	nl := self newlines.
+	nl keysAndValuesDo: [ :index :value |
+		(value > pos) ifTrue: [ ^ (index - 1)]
+	].	
+
+	^ nl size
+!
+
+newlines
+	^ newlines ifNil: [ 
+		newlines := self fillNewlines.
+	]
+! !
+
 !PPStream methodsFor:'printing'!
 
 printOn: aStream
@@ -76,28 +127,6 @@
 	^ self column: position.
 !
 
-column: pos
-	| column clear tmp |
-	
-	pos > readLimit ifTrue: [ ^ Error signal: 'Oot of bounds' ].	
-
-	tmp := position.
-	column := 0.	
-	clear := true.
-
-	(0 to: pos) do: 
-	[:index |
-		position := index.
-		self isStartOfLine ifTrue: [ clear := true ].
-
-		clear ifTrue: [ column := 0. clear := false ].
-		column := column + 1.
-		(position > readLimit) ifTrue: [ position := tmp. ^ column ].
-	].
-	position := tmp.
-	^ column
-!
-
 insideCRLF
 	(position < 1) ifTrue: [ ^ false ].
 	
@@ -120,23 +149,6 @@
 
 line
 	^ self line: position
-!
-
-line: pos
-	| tmp line |
-	(pos = -1) ifTrue: [  ^ 0 ].
-	(pos > readLimit) ifTrue: [ ^ self error: 'Out of limit' ].
-	
-	tmp := position.
-	line := 0.
-	
-	(0 to: pos) do: 
-	[:index |
-		position := index.
-		self isStartOfLine ifTrue: [ line := line + 1 ]
-	].
-	position := tmp.
-	^ line
 ! !
 
 !PPStream class methodsFor:'documentation'!
--- a/abbrev.stc	Mon Apr 13 14:19:55 2015 +0100
+++ b/abbrev.stc	Mon Apr 13 22:00:44 2015 +0100
@@ -11,6 +11,7 @@
 PPToken PPToken stx:goodies/petitparser 'PetitParser-Core' 0
 stx_goodies_petitparser stx_goodies_petitparser stx:goodies/petitparser '* Projects & Packages *' 3
 PPDelegateParser PPDelegateParser stx:goodies/petitparser 'PetitParser-Parsers' 0
+PPEndOfFileParser PPEndOfFileParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPEndOfLineParser PPEndOfLineParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPEpsilonParser PPEpsilonParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPFailingParser PPFailingParser stx:goodies/petitparser 'PetitParser-Parsers' 0
@@ -20,11 +21,14 @@
 PPPredicateParser PPPredicateParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPStartOfLine PPStartOfLine stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPStartOfLineParser PPStartOfLineParser stx:goodies/petitparser 'PetitParser-Parsers' 0
+PPStartOfLogicalLineParser PPStartOfLogicalLineParser stx:goodies/petitparser 'PetitParser-Parsers' 0
+PPStartOfWordParser PPStartOfWordParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPUnresolvedParser PPUnresolvedParser stx:goodies/petitparser 'PetitParser-Tools' 0
 PPActionParser PPActionParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPAndParser PPAndParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPChoiceParser PPChoiceParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPCompositeParser PPCompositeParser stx:goodies/petitparser 'PetitParser-Tools' 0
+PPConditionalParser PPConditionalParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPEndOfInputParser PPEndOfInputParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPExpressionParser PPExpressionParser stx:goodies/petitparser 'PetitParser-Tools' 0
 PPFlattenParser PPFlattenParser stx:goodies/petitparser 'PetitParser-Parsers' 0
@@ -33,7 +37,7 @@
 PPMemoizedParser PPMemoizedParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPNotParser PPNotParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPOptionalParser PPOptionalParser stx:goodies/petitparser 'PetitParser-Parsers' 0
-PPPredicateObjectParser PPPredicateObjectParser stx:goodies/petitparser 'PetitParser-Parsers' 0
+PPPredicateObjectParser PPPredicateObjectParser stx:goodies/petitparser 'PetitParser-Parsers' 1
 PPPredicateSequenceParser PPPredicateSequenceParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPRepeatingParser PPRepeatingParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPSequenceParser PPSequenceParser stx:goodies/petitparser 'PetitParser-Parsers' 0
--- a/bc.mak	Mon Apr 13 14:19:55 2015 +0100
+++ b/bc.mak	Mon Apr 13 22:00:44 2015 +0100
@@ -79,6 +79,7 @@
 $(OUTDIR)PPToken.$(O) PPToken.$(H): PPToken.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)stx_goodies_petitparser.$(O) stx_goodies_petitparser.$(H): stx_goodies_petitparser.st $(INCLUDE_TOP)\stx\libbasic\LibraryDefinition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProjectDefinition.$(H) $(STCHDR)
 $(OUTDIR)PPDelegateParser.$(O) PPDelegateParser.$(H): PPDelegateParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PPEndOfFileParser.$(O) PPEndOfFileParser.$(H): PPEndOfFileParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPEndOfLineParser.$(O) PPEndOfLineParser.$(H): PPEndOfLineParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPEpsilonParser.$(O) PPEpsilonParser.$(H): PPEpsilonParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPFailingParser.$(O) PPFailingParser.$(H): PPFailingParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
@@ -88,11 +89,14 @@
 $(OUTDIR)PPPredicateParser.$(O) PPPredicateParser.$(H): PPPredicateParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPStartOfLine.$(O) PPStartOfLine.$(H): PPStartOfLine.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPStartOfLineParser.$(O) PPStartOfLineParser.$(H): PPStartOfLineParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PPStartOfLogicalLineParser.$(O) PPStartOfLogicalLineParser.$(H): PPStartOfLogicalLineParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PPStartOfWordParser.$(O) PPStartOfWordParser.$(H): PPStartOfWordParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPUnresolvedParser.$(O) PPUnresolvedParser.$(H): PPUnresolvedParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPActionParser.$(O) PPActionParser.$(H): PPActionParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPDelegateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPAndParser.$(O) PPAndParser.$(H): PPAndParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPDelegateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPChoiceParser.$(O) PPChoiceParser.$(H): PPChoiceParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPListParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPCompositeParser.$(O) PPCompositeParser.$(H): PPCompositeParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPDelegateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)PPConditionalParser.$(O) PPConditionalParser.$(H): PPConditionalParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPDelegateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPEndOfInputParser.$(O) PPEndOfInputParser.$(H): PPEndOfInputParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPDelegateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPExpressionParser.$(O) PPExpressionParser.$(H): PPExpressionParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPDelegateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)PPFlattenParser.$(O) PPFlattenParser.$(H): PPFlattenParser.st $(INCLUDE_TOP)\stx\goodies\petitparser\PPDelegateParser.$(H) $(INCLUDE_TOP)\stx\goodies\petitparser\PPParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
--- a/bmake.bat	Mon Apr 13 14:19:55 2015 +0100
+++ b/bmake.bat	Mon Apr 13 22:00:44 2015 +0100
@@ -12,15 +12,15 @@
 @echo "***********************************"
 @echo "Buildung stx/goodies/petitparser/analyzer
 @echo "***********************************"
-@cd analyzer
-@call bmake %1 %2
-@cd ..
+@pushd analyzer
+@call bmake %1 %2 || exit /b "%errorlevel%"
+@popd
 
 @echo "***********************************"
 @echo "Buildung stx/goodies/petitparser/tests
 @echo "***********************************"
-@cd tests
-@call bmake %1 %2
-@cd ..
+@pushd tests
+@call bmake %1 %2 || exit /b "%errorlevel%"
+@popd
 
 
--- a/lccmake.bat	Mon Apr 13 14:19:55 2015 +0100
+++ b/lccmake.bat	Mon Apr 13 22:00:44 2015 +0100
@@ -8,15 +8,15 @@
 @echo "***********************************"
 @echo "Buildung stx/goodies/petitparser/analyzer
 @echo "***********************************"
-@cd analyzer
-@call lccmake %1 %2
-@cd ..
+@pushd analyzer
+@call lccmake %1 %2 || exit /b "%errorlevel%"
+@popd
 
 @echo "***********************************"
 @echo "Buildung stx/goodies/petitparser/tests
 @echo "***********************************"
-@cd tests
-@call lccmake %1 %2
-@cd ..
+@pushd tests
+@call lccmake %1 %2 || exit /b "%errorlevel%"
+@popd
 
 
--- a/libInit.cc	Mon Apr 13 14:19:55 2015 +0100
+++ b/libInit.cc	Mon Apr 13 22:00:44 2015 +0100
@@ -37,6 +37,7 @@
 _PPToken_Init(pass,__pRT__,snd);
 _stx_137goodies_137petitparser_Init(pass,__pRT__,snd);
 _PPDelegateParser_Init(pass,__pRT__,snd);
+_PPEndOfFileParser_Init(pass,__pRT__,snd);
 _PPEndOfLineParser_Init(pass,__pRT__,snd);
 _PPEpsilonParser_Init(pass,__pRT__,snd);
 _PPFailingParser_Init(pass,__pRT__,snd);
@@ -46,11 +47,14 @@
 _PPPredicateParser_Init(pass,__pRT__,snd);
 _PPStartOfLine_Init(pass,__pRT__,snd);
 _PPStartOfLineParser_Init(pass,__pRT__,snd);
+_PPStartOfLogicalLineParser_Init(pass,__pRT__,snd);
+_PPStartOfWordParser_Init(pass,__pRT__,snd);
 _PPUnresolvedParser_Init(pass,__pRT__,snd);
 _PPActionParser_Init(pass,__pRT__,snd);
 _PPAndParser_Init(pass,__pRT__,snd);
 _PPChoiceParser_Init(pass,__pRT__,snd);
 _PPCompositeParser_Init(pass,__pRT__,snd);
+_PPConditionalParser_Init(pass,__pRT__,snd);
 _PPEndOfInputParser_Init(pass,__pRT__,snd);
 _PPExpressionParser_Init(pass,__pRT__,snd);
 _PPFlattenParser_Init(pass,__pRT__,snd);
--- a/mingwmake.bat	Mon Apr 13 14:19:55 2015 +0100
+++ b/mingwmake.bat	Mon Apr 13 22:00:44 2015 +0100
@@ -16,15 +16,15 @@
 @echo "***********************************"
 @echo "Buildung stx/goodies/petitparser/analyzer
 @echo "***********************************"
-@cd analyzer
-@call mingwmake %1 %2
-@cd ..
+@pushd analyzer
+@call mingwmake %1 %2 || exit /b "%errorlevel%"
+@popd
 
 @echo "***********************************"
 @echo "Buildung stx/goodies/petitparser/tests
 @echo "***********************************"
-@cd tests
-@call mingwmake %1 %2
-@cd ..
+@pushd tests
+@call mingwmake %1 %2 || exit /b "%errorlevel%"
+@popd
 
 
--- a/stx_goodies_petitparser.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/stx_goodies_petitparser.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser' }"
 
+"{ NameSpace: Smalltalk }"
+
 LibraryDefinition subclass:#stx_goodies_petitparser
 	instanceVariableNames:''
 	classVariableNames:''
@@ -7,12 +9,6 @@
 	category:'* Projects & Packages *'
 !
 
-!stx_goodies_petitparser class methodsFor:'documentation'!
-
-extensionsVersion_HG
-
-    ^ '$Changeset: <not expanded> $'
-! !
 
 !stx_goodies_petitparser class methodsFor:'accessing'!
 
@@ -86,7 +82,10 @@
 referencedPreRequisites
     "list packages which are a prerequisite, because they contain
      classes which are referenced by my classes.
-     We do not need these packages as a prerequisite for loading or compiling.
+     We do not need these packages as a prerequisite for compiling or loading,
+     however, a class from it may be referenced during execution and having it
+     unloaded then may lead to a runtime doesNotUnderstand error, unless the caller
+     includes explicit checks for the package being present.
      This method is generated automatically,
      by searching all classes (and their packages) which are referenced by my classes."
 
@@ -157,6 +156,7 @@
         PPToken
         #'stx_goodies_petitparser'
         PPDelegateParser
+        PPEndOfFileParser
         PPEndOfLineParser
         PPEpsilonParser
         PPFailingParser
@@ -166,11 +166,14 @@
         PPPredicateParser
         PPStartOfLine
         PPStartOfLineParser
+        PPStartOfLogicalLineParser
+        PPStartOfWordParser
         PPUnresolvedParser
         PPActionParser
         PPAndParser
         PPChoiceParser
         PPCompositeParser
+        PPConditionalParser
         PPEndOfInputParser
         PPExpressionParser
         PPFlattenParser
--- a/tests/Make.proto	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/Make.proto	Mon Apr 13 22:00:44 2015 +0100
@@ -136,6 +136,8 @@
 $(OUTDIR)stx_goodies_petitparser_tests.$(O) stx_goodies_petitparser_tests.$(H): stx_goodies_petitparser_tests.st $(INCLUDE_TOP)/stx/libbasic/LibraryDefinition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProjectDefinition.$(H) $(STCHDR)
 $(OUTDIR)PPComposedTest.$(O) PPComposedTest.$(H): PPComposedTest.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)PPCompositeParserTest.$(O) PPCompositeParserTest.$(H): PPCompositeParserTest.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)PPConditionalParserTest.$(O) PPConditionalParserTest.$(H): PPConditionalParserTest.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)PPConditionalParserTests.$(O) PPConditionalParserTests.$(H): PPConditionalParserTests.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)PPExtensionTest.$(O) PPExtensionTest.$(H): PPExtensionTest.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)PPMappingTest.$(O) PPMappingTest.$(H): PPMappingTest.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)PPObjectTest.$(O) PPObjectTest.$(H): PPObjectTest.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)
--- a/tests/Make.spec	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/Make.spec	Mon Apr 13 22:00:44 2015 +0100
@@ -60,6 +60,8 @@
 	stx_goodies_petitparser_tests \
 	PPComposedTest \
 	PPCompositeParserTest \
+	PPConditionalParserTest \
+	PPConditionalParserTests \
 	PPExtensionTest \
 	PPMappingTest \
 	PPObjectTest \
@@ -84,6 +86,8 @@
     $(OUTDIR_SLASH)stx_goodies_petitparser_tests.$(O) \
     $(OUTDIR_SLASH)PPComposedTest.$(O) \
     $(OUTDIR_SLASH)PPCompositeParserTest.$(O) \
+    $(OUTDIR_SLASH)PPConditionalParserTest.$(O) \
+    $(OUTDIR_SLASH)PPConditionalParserTests.$(O) \
     $(OUTDIR_SLASH)PPExtensionTest.$(O) \
     $(OUTDIR_SLASH)PPMappingTest.$(O) \
     $(OUTDIR_SLASH)PPObjectTest.$(O) \
--- a/tests/PPAbstractParserTest.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/PPAbstractParserTest.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
+"{ NameSpace: Smalltalk }"
+
 TestCase subclass:#PPAbstractParserTest
 	instanceVariableNames:''
 	classVariableNames:''
@@ -51,6 +53,12 @@
 	^ result
 !
 
+assert: string1 includesSubstring: string2
+	"Support portability by using ANSI search method"
+
+	self assert: (string1 notEmpty and: [string2 notEmpty and: [0 < (string1 indexOfSubCollection: string2 startingAt: 1)]])
+!
+
 assert: aParser parse: aCollection
 	^ self assert: aParser parse: aCollection to: nil end: aCollection size 
 !
--- a/tests/PPArithmeticParser.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/PPArithmeticParser.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
+"{ NameSpace: Smalltalk }"
+
 PPCompositeParser subclass:#PPArithmeticParser
 	instanceVariableNames:'terms addition factors multiplication power primary parentheses
 		number'
@@ -38,7 +40,7 @@
 
 parentheses
 	^ $( asParser trim , terms , $) asParser trim
-		==> [ :nodes | nodes second ]
+		==> [ :nodes | nodes at: 2 ]
 !
 
 power
--- a/tests/PPComposedTest.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/PPComposedTest.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
+"{ NameSpace: Smalltalk }"
+
 PPAbstractParserTest subclass:#PPComposedTest
 	instanceVariableNames:''
 	classVariableNames:''
@@ -114,7 +116,7 @@
 	number := #digit asParser plus flatten trim
 		==> [ :node | node asInteger ].
 	list := (number separatedBy: $, asParser token trim)
-		==> [ :node | node select: [ :each | each isInteger ] ].
+		==> [ :node | node select: [ :each | each isKindOf: Integer ] ].
 	parser := list end.
 
 	self assert: parser parse: '1' to: (1 to: 1) asArray.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPConditionalParserTest.st	Mon Apr 13 22:00:44 2015 +0100
@@ -0,0 +1,51 @@
+"{ Package: 'stx:goodies/petitparser/tests' }"
+
+"{ NameSpace: Smalltalk }"
+
+PPAbstractParserTest subclass:#PPConditionalParserTest
+	instanceVariableNames:'context'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+!PPConditionalParserTest methodsFor:'as yet unclassified'!
+
+context
+	^ context
+!
+
+setUp
+	super setUp.
+	context := PPContext new
+!
+
+testConditionCtxAccess
+	| parser |
+
+	parser := ('a' asParser if: [ :ctx | (ctx propertyAt: #foo) = #bar ]).
+	
+	context propertyAt: #foo put: #bar.
+	self assert: parser parse: 'a' .
+
+
+	context propertyAt: #foo put: #zorg.
+	self assert: parser fail: 'a' .
+!
+
+testConditionFalse
+	| parser |
+	parser := ('a' asParser if: [ :ctx | false ]).
+	
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'b'.
+!
+
+testConditionTrue
+	| parser |
+	parser := ('a' asParser if: [ :ctx | true ]).
+	
+	self assert: parser parse: 'a'.
+	self assert: parser fail: 'b'.
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPConditionalParserTests.st	Mon Apr 13 22:00:44 2015 +0100
@@ -0,0 +1,51 @@
+"{ Package: 'stx:goodies/petitparser/tests' }"
+
+"{ NameSpace: Smalltalk }"
+
+PPAbstractParserTest subclass:#PPConditionalParserTests
+	instanceVariableNames:'context'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+!PPConditionalParserTests methodsFor:'as yet unclassified'!
+
+context
+	^ context
+!
+
+setUp
+	super setUp.
+	context := PPContext new
+!
+
+testConditionCtxAccess
+	| parser |
+
+	parser := ('a' asParser if: [ :ctx | (ctx propertyAt: #foo) = #bar ]).
+	
+	context propertyAt: #foo put: #bar.
+	self assert: parser parse: 'a' .
+
+
+	context propertyAt: #foo put: #zorg.
+	self assert: parser fail: 'a' .
+!
+
+testConditionFalse
+	| parser |
+	parser := ('a' asParser if: [ :ctx | false ]).
+	
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'b'.
+!
+
+testConditionTrue
+	| parser |
+	parser := ('a' asParser if: [ :ctx | true ]).
+	
+	self assert: parser parse: 'a'.
+	self assert: parser fail: 'b'.
+! !
+
--- a/tests/PPContextMementoTest.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/PPContextMementoTest.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
+"{ NameSpace: Smalltalk }"
+
 TestCase subclass:#PPContextMementoTest
 	instanceVariableNames:'memento'
 	classVariableNames:''
@@ -17,6 +19,7 @@
 !PPContextMementoTest methodsFor:'running'!
 
 setUp
+	super setUp.
 	memento := self memento.
 ! !
 
--- a/tests/PPContextTest.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/PPContextTest.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
+"{ NameSpace: Smalltalk }"
+
 TestCase subclass:#PPContextTest
 	instanceVariableNames:'context'
 	classVariableNames:''
@@ -15,6 +17,7 @@
 !
 
 setUp
+	super setUp.
 	context := self context.
 ! !
 
--- a/tests/PPExtensionTest.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/PPExtensionTest.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
+"{ NameSpace: Smalltalk }"
+
 PPAbstractParserTest subclass:#PPExtensionTest
 	instanceVariableNames:''
 	classVariableNames:''
@@ -110,14 +112,15 @@
 !PPExtensionTest methodsFor:'testing-stream'!
 
 testStream
-	| stream |
+	| dot stream |
+	dot := (Character codePoint: 183) asString.
 	stream := 'abc' readStream asPetitStream.
 	self assert: stream class equals: PPStream.
-	self assert: stream printString equals: '·abc'.
+	self assert: stream printString equals: dot , 'abc'.
 	self assert: stream peek equals: $a.
 	self assert: stream uncheckedPeek equals: $a.
 	self assert: stream next equals: $a.
-	self assert: stream printString equals: 'a·bc'.
+	self assert: stream printString equals: 'a' , dot , 'bc'.
 	self assert: stream asPetitStream equals: stream
 !
 
--- a/tests/PPLambdaParser.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/PPLambdaParser.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
+"{ NameSpace: Smalltalk }"
+
 PPCompositeParser subclass:#PPLambdaParser
 	instanceVariableNames:'expression abstraction application variable'
 	classVariableNames:''
@@ -43,11 +45,13 @@
 !PPLambdaParser methodsFor:'productions'!
 
 abstraction
-	^ $\ asParser trim , variable , $. asParser trim , expression ==> [ :node | Array with: node second with: node fourth ]
+	^ $\ asParser trim , variable , $. asParser trim , expression 
+		==> [ :node | Array with: (node at: 2) with: (node at: 4) ]
 !
 
 application
-	^ $( asParser trim , expression , expression , $) asParser trim ==> [ :node | Array with: node second with: node third ]
+	^ $( asParser trim , expression , expression , $) asParser trim 
+			==> [ :node | Array with: (node at: 2) with: (node at: 3) ]
 !
 
 expression
--- a/tests/PPObjectTest.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/PPObjectTest.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
+"{ NameSpace: Smalltalk }"
+
 PPAbstractParserTest subclass:#PPObjectTest
 	instanceVariableNames:''
 	classVariableNames:''
@@ -12,13 +14,13 @@
 
 integer
 	^ PPPredicateObjectParser
-		on: [ :each | each isInteger ]
+		on: [ :each | each isKindOf: Integer ]
 		message: 'integer expected'
 !
 
 string
 	^ PPPredicateObjectParser
-		on: [ :each | each isString ]
+		on: [ :each | each isKindOf: String ]
 		message: 'string expected'
 ! !
 
@@ -88,6 +90,11 @@
     ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPObjectTest.st,v 1.4 2014-03-04 14:34:19 cg Exp $'
 !
 
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
 version_SVN
     ^ '$Id: PPObjectTest.st,v 1.4 2014-03-04 14:34:19 cg Exp $'
 ! !
--- a/tests/PPParserTest.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/PPParserTest.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
+"{ NameSpace: Smalltalk }"
+
 PPAbstractParserTest subclass:#PPParserTest
 	instanceVariableNames:''
 	classVariableNames:''
@@ -178,7 +180,7 @@
 !
 
 testMax
-	| parser |
+	| parser printString suffix |
 	parser := $a asParser max: 2.
 	self assert: parser min equals: 0.
 	self assert: parser max equals: 2.
@@ -195,7 +197,9 @@
 		parse: 'aaaa'
 		to: #($a $a)
 		end: 2.
-	self assert: (parser printString endsWith: '[0, 2]')
+	printString := parser printString.
+	suffix := printString copyFrom: printString size - 5 to: printString size.
+	self assert: suffix = '[0, 2]'
 !
 
 testMaxGreedy
@@ -261,7 +265,7 @@
 !
 
 testMin
-	| parser |
+	| parser printString suffix |
 	parser := $a asParser min: 2.
 	self assert: parser min equals: 2.
 	self assert: parser max > parser min.
@@ -270,7 +274,9 @@
 	self assert: parser parse: 'aa' to: #($a $a).
 	self assert: parser parse: 'aaa' to: #($a $a $a).
 	self assert: parser parse: 'aaaa' to: #($a $a $a $a).
-	self assert: (parser printString endsWith: '[2, *]')
+	printString := parser printString.
+	suffix := printString copyFrom: printString size - 5 to: printString size.
+	self assert: suffix = '[2, *]'
 !
 
 testMinGreedy
@@ -346,7 +352,7 @@
 !
 
 testMinMax
-	| parser |
+	| parser printString suffix |
 	parser := $a asParser min: 2 max: 4.
 	self assert: parser min equals: 2.
 	self assert: parser max equals: 4.
@@ -365,7 +371,9 @@
 		parse: 'aaaaaa'
 		to: #($a $a $a $a)
 		end: 4.
-	self assert: (parser printString endsWith: '[2, 4]')
+	printString := parser printString.
+	suffix := printString copyFrom: printString size - 5 to: printString size.
+	self assert: suffix = '[2, 4]'
 !
 
 testMinMaxGreedy
--- a/tests/PPPredicateTest.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/PPPredicateTest.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
+"{ NameSpace: Smalltalk }"
+
 PPAbstractParserTest subclass:#PPPredicateTest
 	instanceVariableNames:''
 	classVariableNames:''
@@ -75,29 +77,46 @@
 	self assert: parser fail: 'a'
 !
 
-testEndOfLine
+testEndOfFile
 	| parser |
-	parser := (#letter asParser / #blank asParser) star, #endOfLine asParser.
+	parser := (#letter asParser / #blank asParser) star, #eof asParser.
 	
 	self assert: parser parse: 'lorem ipsum'.
 	
-	parser := #any asParser, #endOfLine asParser, #any asParser star.
-	self assert: parser parse: 'a', String cr, 'b'.
-	self assert: parser fail: String crlf.
-	self assert: parser fail: 'lorem ipsum'.
-	
-	parser := #endOfLine asParser, #any asParser, #endOfLine asParser negate star, #endOfLine asParser.
-	self assert: parser parse: String cr, 'lorem ipsum'.
-	self assert: parser parse: String lf, 'lorem ipsum'.	
-	self assert: parser parse: String crlf, 'lorem ipsum'.	
-	
-	self assert: parser parse: String crlf.
-	self assert: parser parse: String cr.
-	self assert: parser parse: String lf.
-	
-	parser := #endOfLine asParser negate star, #endOfLine asParser, #any asParser star.
-	self assert: parser parse: String crlf, 'lorem ipsum'.
-	self assert: parser parse: String crlf.
+	parser := #any asParser, #eof asParser, #any asParser star.
+	self assert: parser fail: 'a', Character cr asString, 'b'.
+	self assert: parser fail: Character cr asString , Character lf asString.
+	self assert: parser parse: 'a'.
+!
+
+testEndOfLine
+        | cr crlf lf parser |
+        cr := (Character codePoint: 13) asString.
+        crlf := (Character codePoint: 13) , Character lf asString.
+        lf := Character lf asString.
+        parser := (#letter asParser / #blank asParser) star, #endOfLine asParser.
+        
+        self assert: parser parse: 'lorem ipsum'.
+        
+        parser := #any asParser, #endOfLine asParser, #any asParser star.
+        self assert: parser parse: 'a', cr, 'b'.
+        self assert: parser fail: crlf.
+        self assert: parser fail: 'lorem ipsum'.
+        
+        parser := #endOfLine asParser, #any asParser, #endOfLine asParser negate star, #endOfLine asParser.
+        self assert: parser parse: cr, 'lorem ipsum'.
+        self assert: parser parse: lf, 'lorem ipsum'.   
+        self assert: parser parse: crlf, 'lorem ipsum'. 
+        
+        self assert: parser parse: crlf.
+        self assert: parser parse: cr.
+        self assert: parser parse: lf.
+        
+        parser := #endOfLine asParser negate star, #endOfLine asParser, #any asParser star.
+        self assert: parser parse: crlf, 'lorem ipsum'.
+        self assert: parser parse: crlf.
+
+    "Modified: / 13-04-2015 / 21:55:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 testHex
@@ -176,26 +195,66 @@
 !
 
 testStartOfLine
+        | cr crlf lf parser |
+        cr := (Character codePoint: 13) asString.
+        crlf := (Character codePoint: 13) , Character lf asString.
+        lf := Character lf asString.
+        parser := #startOfLine asParser, #any asParser star.
+        
+        self assert: parser parse: 'lorem ipsum'.
+        
+        parser := #any asParser, #startOfLine asParser, #any asParser star.
+        self assert: parser fail: 'lorem ipsum'.
+        
+        parser := #startOfLine asParser, #any asParser, #startOfLine asParser, #any asParser star.
+        self assert: parser parse: cr, 'lorem ipsum'.
+        self assert: parser parse: lf, 'lorem ipsum'.   
+        self assert: parser fail: crlf, 'lorem ipsum'.  
+        
+        self assert: parser fail: crlf.
+        self assert: parser parse: cr.
+        self assert: parser parse: lf.
+        
+        parser := #startOfLine asParser, #any asParser, #any asParser, #startOfLine asParser, #any asParser star.
+        self assert: parser parse: crlf, 'lorem ipsum'.
+        self assert: parser parse: crlf.
+
+    "Modified: / 13-04-2015 / 21:56:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+testStartOfLogicalLine
 	| parser |
-	parser := #startOfLine asParser, #any asParser star.
-	
-	self assert: parser parse: 'lorem ipsum'.
-	
-	parser := #any asParser, #startOfLine asParser, #any asParser star.
-	self assert: parser fail: 'lorem ipsum'.
+	parser := #startOfLogicalLine asParser, #any asParser star.
 	
-	parser := #startOfLine asParser, #any asParser, #startOfLine asParser, #any asParser star.
-	self assert: parser parse: String cr, 'lorem ipsum'.
-	self assert: parser parse: String lf, 'lorem ipsum'.	
-	self assert: parser fail: String crlf, 'lorem ipsum'.	
+	self assert: parser parse: 'lorem'.
+	self assert: parser fail: ' lorem'.
+	
+	parser := #any asParser, #startOfLogicalLine asParser, #any asParser star.
+	self assert: parser fail: 'lorem'.
+	self assert: parser fail: '        lorem'.
+	self assert: parser parse: ' lorem'.
+	self assert: parser parse: '	lorem'.
+!
+
+testStartOfWord
+	| parser |
+	parser := #startOfWord asParser, #word asParser plus.
 	
-	self assert: parser fail: String crlf.
-	self assert: parser parse: String cr.
-	self assert: parser parse: String lf.
+	self assert: parser parse: 'lorem'.
+	
+	parser := #any asParser, #startOfWord asParser, #word asParser plus.
+	self assert: parser fail: 'lorem'.
+	self assert: parser fail: '1234'.
 	
-	parser := #startOfLine asParser, #any asParser, #any asParser, #startOfLine asParser, #any asParser star.
-	self assert: parser parse: String crlf, 'lorem ipsum'.
-	self assert: parser parse: String crlf.
+	self assert: parser parse: ' lorem'.	
+	self assert: parser parse: ' 123'.
+	self assert: parser parse: ')lorem'.
+	self assert: parser parse: ':lorem'.
+	
+	parser := #startOfWord asParser, #any asParser optional.
+	self assert: parser fail: ''.
+	self assert: parser parse: 'a'.
+	self assert: parser fail: '.'.
 !
 
 testTab
--- a/tests/PPTokenTest.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/PPTokenTest.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,7 @@
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
+"{ NameSpace: Smalltalk }"
+
 PPAbstractParserTest subclass:#PPTokenTest
 	instanceVariableNames:''
 	classVariableNames:''
@@ -36,7 +38,7 @@
 testPrinting
 	| result |
 	result := PPToken on: 'var'.
-	self assert: (result printString includesSubstring: 'PPToken[1,3]')
+	self assert: result printString includesSubstring: 'PPToken[1,3]'
 !
 
 testSize
--- a/tests/abbrev.stc	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/abbrev.stc	Mon Apr 13 22:00:44 2015 +0100
@@ -10,6 +10,8 @@
 stx_goodies_petitparser_tests stx_goodies_petitparser_tests stx:goodies/petitparser/tests '* Projects & Packages *' 3
 PPComposedTest PPComposedTest stx:goodies/petitparser/tests 'PetitTests-Tests' 1
 PPCompositeParserTest PPCompositeParserTest stx:goodies/petitparser/tests 'PetitTests-Core' 1
+PPConditionalParserTest PPConditionalParserTest stx:goodies/petitparser/tests 'PetitTests-Tests' 1
+PPConditionalParserTests PPConditionalParserTests stx:goodies/petitparser/tests 'PetitTests-Tests' 1
 PPExtensionTest PPExtensionTest stx:goodies/petitparser/tests 'PetitTests-Tests' 1
 PPMappingTest PPMappingTest stx:goodies/petitparser/tests 'PetitTests-Tests' 1
 PPObjectTest PPObjectTest stx:goodies/petitparser/tests 'PetitTests-Tests' 1
--- a/tests/bc.mak	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/bc.mak	Mon Apr 13 22:00:44 2015 +0100
@@ -83,6 +83,8 @@
 $(OUTDIR)stx_goodies_petitparser_tests.$(O) stx_goodies_petitparser_tests.$(H): stx_goodies_petitparser_tests.st $(INCLUDE_TOP)\stx\libbasic\LibraryDefinition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProjectDefinition.$(H) $(STCHDR)
 $(OUTDIR)PPComposedTest.$(O) PPComposedTest.$(H): PPComposedTest.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)PPCompositeParserTest.$(O) PPCompositeParserTest.$(H): PPCompositeParserTest.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)PPConditionalParserTest.$(O) PPConditionalParserTest.$(H): PPConditionalParserTest.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)PPConditionalParserTests.$(O) PPConditionalParserTests.$(H): PPConditionalParserTests.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)PPExtensionTest.$(O) PPExtensionTest.$(H): PPExtensionTest.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)PPMappingTest.$(O) PPMappingTest.$(H): PPMappingTest.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)PPObjectTest.$(O) PPObjectTest.$(H): PPObjectTest.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)
--- a/tests/libInit.cc	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/libInit.cc	Mon Apr 13 22:00:44 2015 +0100
@@ -36,6 +36,8 @@
 _stx_137goodies_137petitparser_137tests_Init(pass,__pRT__,snd);
 _PPComposedTest_Init(pass,__pRT__,snd);
 _PPCompositeParserTest_Init(pass,__pRT__,snd);
+_PPConditionalParserTest_Init(pass,__pRT__,snd);
+_PPConditionalParserTests_Init(pass,__pRT__,snd);
 _PPExtensionTest_Init(pass,__pRT__,snd);
 _PPMappingTest_Init(pass,__pRT__,snd);
 _PPObjectTest_Init(pass,__pRT__,snd);
--- a/tests/stx_goodies_petitparser_tests.st	Mon Apr 13 14:19:55 2015 +0100
+++ b/tests/stx_goodies_petitparser_tests.st	Mon Apr 13 22:00:44 2015 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
 "{ Package: 'stx:goodies/petitparser/tests' }"
 
 "{ NameSpace: Smalltalk }"
@@ -65,7 +63,10 @@
 referencedPreRequisites
     "list packages which are a prerequisite, because they contain
      classes which are referenced by my classes.
-     We do not need these packages as a prerequisite for loading or compiling.
+     We do not need these packages as a prerequisite for compiling or loading,
+     however, a class from it may be referenced during execution and having it
+     unloaded then may lead to a runtime doesNotUnderstand error, unless the caller
+     includes explicit checks for the package being present.
      This method is generated automatically,
      by searching all classes (and their packages) which are referenced by my classes."
 
@@ -110,6 +111,8 @@
         #'stx_goodies_petitparser_tests'
         PPComposedTest
         PPCompositeParserTest
+        PPConditionalParserTest
+        PPConditionalParserTests
         PPExtensionTest
         PPMappingTest
         PPObjectTest
--- a/vcmake.bat	Mon Apr 13 14:19:55 2015 +0100
+++ b/vcmake.bat	Mon Apr 13 22:00:44 2015 +0100
@@ -20,15 +20,15 @@
 @echo "***********************************"
 @echo "Buildung stx/goodies/petitparser/analyzer
 @echo "***********************************"
-@cd analyzer
-@call vcmake %1 %2
-@cd ..
+@pushd analyzer
+@call vcmake %1 %2 || exit /b "%errorlevel%"
+@popd
 
 @echo "***********************************"
 @echo "Buildung stx/goodies/petitparser/tests
 @echo "***********************************"
-@cd tests
-@call vcmake %1 %2
-@cd ..
+@pushd tests
+@call vcmake %1 %2 || exit /b "%errorlevel%"
+@popd