Rule
public protocol Rule : CustomStringConvertible
Behavioural rule is both an extension to and ultimately a replacement for current
Rule
. It bakes in the logic for repeating, negation, lookahead, as well as
transient and void rules both flattening the evaluation hierarchy and making it
easier to extend (previously implementations would have to add any of this logic
themselves, and it’s easy to get wrong.
-
The behaviour for the rule controlling things like cardinality and lookahead
Declaration
Swift
var behaviour: Behaviour { get }
-
The annotations on the rule
Declaration
Swift
var annotations: RuleAnnotations { get }
-
This function implements the actual test. It is responsible soley for performing the test. The scanner head will be managed correctly based on success (it will be left in the position at the end of the test), or returned to its pre-test position on failure.
Declaration
Swift
func test(with lexer: LexicalAnalyzer, for ir: IntermediateRepresentation) throws
Parameters
lexer
The lexer controlling the scanner
ir
The intermediate representation
-
Creates a rule with the specified behaviour and annotations.
Declaration
Swift
func rule(with behaviour: Behaviour?, annotations: RuleAnnotations?) -> Rule
Parameters
behaviour
The behaviour for the new instance, if nil the rule should use the default behaviour for the producer.
annotations
The annotations for the new rule, if nil the rule should use the default behaviour for the producer.
Return Value
A new instance with the specified behaviour and annotations.
-
An abrieviated description of the rule that should reflect behaviour, but not annotations and should not expand references
Declaration
Swift
var shortDescription: String { get }
-
match(with:for:)
Default implementationShould perform the actual check and manage the communicaion with the supplied
IntermedidateRepresentation
. If the match fails, and that failure cannot be ignored anError
should be thrown. It is the responsiblity of the implementer to ensure the following basic pattern is followedir.willEvaluate()
is called to inform their
that evaluation is beginning. If their
returns an existing match result that should be used (proceed to step XXX)lexer.mark()
should be called so that an accurateLexicalContext
can be generated.- Perform apply your rule using
lexer
. - Depending on the outcome, and the to-be-generated token:
- If the rule was satisfied, return a
MatchResult.success
together with a generatedlexer.proceed()
generated context - If the rule was satisfied, but the result should be consumed (no node/token created, but scanning should proceed after the match) return
MatchResult.consume
with a generatedlexer.proceed()
context - If the rule was not satisfied but the failure can be ignored return
MatchResult.ignoreFailure
. Depending on your grammar you may want to leave the scanner in the same position in which case issue alexer.proceed()
but discard the result. Otherwise issue alexer.rewind()
. - If the rule was not satisfied but the failure should not be ignored. Call
lexer.rewind()
and return aMatchResult.failure
- If the rule was not satisifed and parsing of this branch of the grammar should stop immediately throw an
Error
For standard implementations of rules that should satisfy almost every grammar see
ParserRule
andScannerRule
.ParserRule
has a custom case which provides all of the logic above with the exception of actual matching which is a lot simpler, and it is recommended that you use that if you wish to provide your own rules.Default Implementation
Standard implementation that uses the evaluate function to apply the behaviour of the rule.
Declaration
Swift
func match(with lexer: LexicalAnalyzer, for ir: IntermediateRepresentation) throws
Parameters
with
The
LexicalAnalyzer
providing the scanning functionsfor
The
IntermediateRepresentation
that wil be building any data structures required for subsequent interpretation of the parsing results
-
parse(as:)
Extension methodChanges the behaviour (or creates a rule with the behaviour) to create a token.
Declaration
Swift
public func parse(as token: TokenType) -> Rule
Parameters
rule
The rule (or thing that can become a rule)
Return Value
A rule
-
annotatedWith(_:)
Extension methodCreates a new instance of the rule annotated with the specified annotations. If you supply annotations that impact scanning (token, void, transient), they will be filtered out, but applied to the resultant behaviour.
Declaration
Swift
public func annotatedWith(_ annotations: RuleAnnotations) -> Rule
Parameters
annotations
The desired annotations
Return Value
A new instance of the rule with the specified annotations
-
require(_:)
Extension methodCreates a new instance of the rule that requires matches of the specified cardinality
Declaration
Swift
public func require(_ cardinality: Cardinality) -> Rule
Parameters
cardinality
The desired cardinalitiy
Return Value
The new rule instance
-
lookahead()
Extension methodCreates a new instance of the rule set to have lookahead behaviour
// Creates a lookahead version of of the rule let lookahead = -CharacterSet.letters.lookahead()
Declaration
Swift
public func lookahead() -> Rule
Return Value
A new version of the rule
-
negate()
Extension methodCreates a new instance of the rule which negates its match. Note that negate does not
toggle
, that is !!rule != rule.// Creates a negated version of of the rule let notLetter = CharacterSet.letters.negate()
Declaration
Swift
public func negate() -> Rule
Return Value
A new version of the rule
-
skip()
Extension methodCreates a new instance of the rule which skips.
// Creates a skipping version of of the rule let skipLetters = CharacterSet.letters.skip()
Declaration
Swift
public func skip() -> Rule
Return Value
A new version of the rule
-
scan()
Extension methodCreates a new instance of the rule which scans.
// Creates a scanning version of of the rule let scanLetters = CharacterSet.letters.scan()
Declaration
Swift
public func scan() -> Rule
Return Value
A new version of the rule
-
reference(_:annotations:)
Extension methodUndocumented
Declaration
Swift
public func reference(_ kind:Behaviour.Kind, annotations: RuleAnnotations? = nil)->Rule
-
error
Extension methodThe user specified (in an annotation) error associated with the rule
Declaration
Swift
public var error: String? { get }
-
subscript(_:)
Extension methodReturns the value of the specific
RuleAnnotationValue
identified byannotation
if presentDeclaration
Swift
public subscript(annotation: RuleAnnotation) -> RuleAnnotationValue? { get }
-
structural
Extension methodtrue
if the rule creates ndoes, false otherwiseDeclaration
Swift
public var structural: Bool { get }
-
skipping
Extension methodtrue
if the rule creates ndoes, false otherwiseDeclaration
Swift
public var skipping: Bool { get }
-
scanning
Extension methodtrue
if the rule creates ndoes, false otherwiseDeclaration
Swift
public var scanning: Bool { get }
-
evaluate(_:using:and:)
Extension methodStandard implementation that applies the behaviour of the rule.
Declaration
Swift
public func evaluate(_ matcher:@escaping Test, using lexer:LexicalAnalyzer, and ir:IntermediateRepresentation) throws
Parameters
matcher
The test to use, wrap, in the specified behaviour.
lexer
The lexer controlling the scanning head
ir
The intermediate representation to use
Return Value
The match result