PetitCompiler contains several limitations, i.e., it cannot (efficiently) compile any working parser. This due to the fact that PetitParser allows any arbitrary code.
Limitations on action blocks
By action blocks we mean blocks that are executed when child parser
consumes input. They're created by
map: messages, i.e.,
#letter asParser / (#letterOrDigit asParser) ==> [:chars | String withAll: chars ]
#letter asParser / (#digit asParser) map: [:letter :digit | String with: letter with: digit ]
Generally speaking, action blocks are required to be purely functional. In practice this means they may not access any state nor they may do a super-send. This requirement is transitive, i.e., all self-sent methods must be purely functional.
Strictly speaking, from within an action block defined in class C, you may not:
- read or assign any instance variable of class C
- read or assign any class variable of class C
- do a super-send
- do a self-send to non-existing method
If actions blocks are not functional, an error (instance of
PPCCompilationError) is raised with a message like code not functional: ... where ... gives
more detail on what's wrong.
Accessing properties from within action blocks
Strictly speaking, accessing
PPParser's properties leads to accessing
and instance variable and therefore is forbidden. However, is storing some
sort of state during parsing is absolutely unavoidable, PetitCompiler
provides an option to get around this limitation.
If the parser is compiled with option #allowProperties set to
parser compiler allows accessing properties via properties API (see class PPParser protocol accessing-properties).
However, the values of all properties MUST be lazy initialized - never use
#propertyAt:, always use
For example. following is allowed
semiSeen ^self propertyAt: #semiSeen isAbsent:[ false ] semiSeen: aBoolean ^self propertyAt: #semiSeen put: aBoolean semi ^$; asParser ==> [:semi | self semiSeen: true. semi ]
given that parser is compiled with #allowProperties like:
SomeParser compileWithOptions: #( allowProperties: true )
If properties are not lazy-initialized, the behaviour is undefined.