Parser Submodule
SmartGameFormat.Parser
— Module.The Parser
sub-module is concerned with converting a sequence of Lexer.Token
into a collection (i.e. a vector) of SGFGameTree
.
To that end it provides the following functionality:
Types
ParseContext()
Context information used during parsing. It stores temporary data such as the encountered game type and file format version.
Functions
SmartGameFormat.Parser.parse
— Function.parse(ts::Lexer.TokenStream) -> Vector{SGFGameTree}
Read all the lexical Lexer.Token
from the Lexer.TokenStream
ts
, and attempt to parse the sequence of token as an SGF collection. To accomplish this it uses the function tryparse
. If successful, the SGF collection is returned as a Vector
of SGFGameTree
.
Depending on the content, any of the following exceptions may be thrown to signal that it is not a legal SGF specification.
Base.EOFError
: Premature end-of-file encountered during tokenisation.Lexer.LexicalError
: Illegal characters used outside property values. For example lower case letters for identifier.Parser.ParseError
: Content is not a valid SGF specification (while considering the given the FF version).
parse(::Type{T}, ts::Lexer.TokenStream, ctx::ParseContext) -> T
Same as the corresponding tryparse
method, but instead of returning a Nullable
it throws a ParseError
if it is unable to parse the next N
token in ts
to type T
.
SmartGameFormat.Parser.tryparse
— Function.tryparse(::Type{Vector{SGFGameTree}}, ts::Lexer.TokenStream, ctx::ParseContext) -> Nullable{Vector{SGFGameTree}}
Try to parse the next N
token in ts
as a Vector
of SGFGameTree
. Such a vector is called a "collection". For a collection to occur there must be at least one parse-able SGFGameTree
in ts
.
tryparse(::Type{SGFGameTree}, ts::Lexer.TokenStream, ctx::ParseContext) -> Nullable{SGFGameTree}
Try to parse the next N
token in ts
into a SGFGameTree
.
A game tree must start with a Token('(')
, followed by one or more SGFNode
, followed by zero or more sub-SGFGameTree
, and finally end with a Token(')')
.
tryparse(::Type{SGFNode}, ts::Lexer.TokenStream, ctx::ParseContext) -> Nullable{SGFNode}
Try to parse the next N
token in ts
into a SGFNode
, which means that the immediate next element in ts
is expected to be Token(';')
followed by zero or more properties. Each property must have a unique identifier, or a ParseError
will be thrown.
tryparse(::Type{Pair}, ts::Lexer.TokenStream, ctx::ParseContext) -> Nullable{Pair{Symbol,Vector{Any}}}
Try to parse the next N
token in ts
into a Pair
denoting a single property of a SGFNode
. Note that individual properties are parsed as Pair
, because each SGFNode
stores all its properties as a single Dict
.
For a property to occur in ts
, the immediate next element in ts
must be a Token('I', "<ID>")
, where <ID>
is some sequence of uppercase letters denoting the identifier of the token. After the identifier there can be one or more property values. There must be at least one property value.
Each property value must be delimited by a Token('[')
at the beginning and a Token(']')
at the end. The value itself is contained within those two delimiter token as a single Token('S', "<val>")
where <val>
denotes the value. Note that this "S" token is optional and its absence means that the property value is the empty value.
Exceptions
ParseError(msg)
The expression passed to Parser.parse
could not be interpreted as a valid SGF specification (in accordance with the specified FF version).