Public API
Interface
ExprParsers.EP
— ModuleEP = ExprParsers
Short alias for the ExprParsers
package.
ExprParsers.parse_expr
— Functionparse_expr(parser, value)
Match parser against a value, will throw ParseError if the parser does not match.
Defaults to comparing with ==
, if matches, will return the value. Parsers will be called instead and return their parsed value.
Examples
julia> using ExprParsers
julia> parse_expr(:a, :a)
:a
julia> parse_expr([1,2,3], [1,2,3])
3-element Array{Int64,1}:
1
2
3
julia> parse_expr([1,2,3], [1,2,35])
ERROR: ParseError: Using default `==` comparison, but parser `3` ≠ value `35`.
julia> parse_expr(:(a = 4), :(a = 5))
ERROR: ParseError: Using default `==` comparison, but parser `4` ≠ value `5`.
julia> parse_expr([1,2,3,4], [1,2])
ERROR: ParseError: length(parser) == length(values) = false
length(parser) = 4
parser = [1, 2, 3, 4]
length(values) = 2
values = [1, 2]
All ExprParserWithParsed have a common parse_expr method, namely that all struct fields are given directly as keyword arguments.
ExprParsers.to_expr
— Functionto_expr(parsed)
Converts parsed information back to Expr.
Defaults to returning same value, however if something knows about how it can be translated back, just overload the function.
ExprParsers.@passert
— Macro@passert cond [text]
Throw an ParseError
if cond
is false
. Preferred syntax for writing assertions. Message text
is optionally displayed upon assertion failure.
If no text is given a default rich text description is constructed, evaluating all found subexpressions for easier debugging.
Examples
julia> using ExprParsers
julia> @passert iseven(3) "3 is an odd number!"
ERROR: ParseError: 3 is an odd number!
julia> @passert isodd(3) "What even are numbers?"
julia> a = 3;
julia> @passert a+2 == 4
ERROR: ParseError: a + 2 == 4 = false
a + 2 = 5
a = 3
Adapted from Base.@assert
ExprParsers.ParseError
— TypeEP.ParseError
Special Exception Type to indicate that some parsing failed.
Types
ExprParsers.ExprParser
— TypeEP.ExprParser
All parsers in the ExprParsers
package inherit from this type.
ExprParsers.ExprParserWithParsed
— TypeEP.ExprParserWithParsed
This Type is mainly for internal usage. Please use @exprparser
instead for the public interface.
It is a subtype of ExprParser
which indicates that this parser actually constructs a ExprParsed
object when calling parse_expr(parser, expr)
.
The resulting ExprParsed
object is a struct with identical fields like the parser, where then the parsed values will be stored.
ExprParsed(parser::ExprParserWithParsed)
will return the corresponding ExprParsed
type.
ExprParsers.ExprParsed
— TypeEP.ExprParsed(ParserType::Type{<:ExprParserWithParsed}) -> Type{<:ExprParsed}
Maps Parser Type to respective Parsed Type, and is also abstract super type of all Parsed types.
Example
EP.ExprParsed(EP.Assignment) == EP.Assignment_Parsed
ExprParsers.@exprparser
— MacroEP.@exprparser struct MySymbol
symbol = EP.anything = :default_parsed_value
end
is transformed to
Base.@kwdef struct MySymbol <: EP.ExprParserWithParsed
symbol = anything
end
Base.@kwdef mutable struct MySymbol_Parsed{T} <: EP.ExprParsed
symbol = :default_parsed_value
end
EP.ExprParsed(::Base.Type{MySymbol}) = MySymbol_Parsed
It defines the basics for an usual ExprParser, namely
- the Parser type itself like specified in the original struct. It is always immutable - if you feel the need of mutating a parser, try to construct a new parser instead.
- a corresponding Parsed type which will be used to hold parsed values. This is intentionally mutable as a usual workflow consists of adapting the parsed values to the needs of your macro, and if everything is changed, transform it back to an Expr using
to_expr(parsed)
. - a mapping from the
ExprParser
to theExprParsed
Additionally, the created MySymbol Parser supports the following default parse_expr
functionality
parser = MySymbol()
parse_expr(parser, symbol = :hi)
which translates to
parser = MySymbol()
MySymbol_Parsed(symbol = parse_expr(parser.symbol, :hi))
This is generic, and works similar if you have multiple fields.
Finally, in order to finish your custom ExprParser definition, you just need to specialize the two main functions
parse_expr(mysymbolparser::MySymbol, expr)
to_expr(mysymbolparsed::MySymbol_Parsed)
function EP.parse_expr(mysymbolparser::MySymbol, expr)
# do your custom parsing
# use @passert for checking parse assertions (it will have a nice and detailed default error message)
# construct your parsed result
MySymbol_Parsed(symbol = ...)
end
function EP.to_expr(parsed::MySymbol_Parsed)
# create a proper `Base.Expr` from your parsed result
# in this case it is simple
parsed.symbol
end
Core ExprParser
ExprParsers.Utils.Iterator
— TypeEP.Iterator(some_iterable)
Mark an iterable explicitly as an Iterator to add support for elementwise parse_expr
.
Examples
julia> using ExprParsers; using Base.Iterators
julia> parser = EP.Iterator(repeated(4));
julia> parse_expr(parser, [4, 4])
2-element Array{Int64,1}:
4
4
julia> parse_expr(parser, [4, 4, 4, 4])
4-element Array{Int64,1}:
4
4
4
4
julia> parse_expr(parser, [3, 4])
ERROR: ParseError: Using default `==` comparison, but parser `4` ≠ value `3`.
ExprParsers.SatisfiesPredicate
— TypeEP.SatisfiesPredicate(predicate_func[, errormessage])
Construct an ExprParser which checks whether the given predicate_func
returns true. If so, the to-be-parsed value is returned as such, otherwise an ParseError
is thrown as usual. If errormessage
is given, it will be appended to the default error message.
Example
julia> using ExprParsers;
julia> parser = EP.SatisfiesPredicate(isodd);
julia> parse_expr(parser, 3)
3
julia> parse_expr(parser, 4)
ERROR: ParseError: Predicate `isodd` returned false on expr `4`.
julia> is44(x) = x==44;
julia> parser2 = EP.SatisfiesPredicate(is44, "It should be 44.");
julia> parse_expr(parser2, 44)
44
julia> parse_expr(parser2, 4)
ERROR: ParseError: Predicate `is44` returned false on expr `4`. It should be 44.
ExprParsers.Isa
— TypeEP.Isa(T::Type)
Constructs an ExprParser which checks whether a value is of the given type.
Example
julia> using ExprParsers
julia> parser = EP.Isa(Symbol);
julia> parse_expr(parser, :thisisasymbol)
:thisisasymbol
julia> parse_expr(parser, 42)
ERROR: ParseError: Expected type `Symbol`, got `42` of type `Int64`.
EP.Isa(Symbol)
is so common that there is a special constant for it anysymbol
.
ExprParsers.anything
— ConstantEP.anything = Isa(Any)
Special constant ExprParser which matches literally anything.
Examples
julia> using ExprParsers
julia> parse_expr(EP.anything, 42)
42
julia> parse_expr(EP.anything, :whatever)
:whatever
ExprParsers.anysymbol
— ConstantEP.anysymbol = Isa(Symbol)
Special constant ExprParser which matches Symbols, and only Symbols.
Examples
julia> using ExprParsers
julia> parse_expr(EP.anysymbol, :asymbol)
:asymbol
julia> parse_expr(EP.anysymbol, 42)
ERROR: ParseError: Expected type `Symbol`, got `42` of type `Int64`.
ExprParsers.AnyOf
— TypeEP.AnyOf(parser1, parser2, parser3, ...; errormessage = "")
Constructs an ExprParser from multiple given parsers. When given a value it first tries to match parser1
, and if that fails with a ParseError, then parser2
, and so forth. The result from the first parser which matches will be returned. If no parser matches, a dedicated ParseError is raised.
If errormessage
is given, it will be appended to the default error message in case of ParseError.
Examples
julia> using ExprParsers
julia> parser = EP.AnyOf(EP.anysymbol, EP.Isa(String), EP.SatisfiesPredicate(isodd),
errormessage="My error message.");
julia> parse_expr(parser, :hi)
:hi
julia> parse_expr(parser, 3)
3
julia> parse_expr(parser, "something")
"something"
julia> parse_expr(parser, 4)
ERROR: ParseError: AnyOf could not parse expr `4` with any of the parsers `(ExprParsers.Isa{Symbol}(), ExprParsers.Isa{String}(), ExprParsers.SatisfiesPredicate{typeof(isodd)}(isodd, ""))`. My error message.
ExprParsers.AllOf
— TypeEP.AllOf(parser1, parser2, parser3, ...)
Constructs an ExprParser from multiple given parsers. When to match a value, all parsers actually need to parse correctly, otherwise the ParseError
from the first non-matching parser is rethrown. If all parsers match, then the return value from the last parser is returned.
Examples
julia> using ExprParsers
julia> parser = EP.AllOf(EP.Isa(Number), EP.SatisfiesPredicate(isodd), 3);
julia> parse_expr(parser, 3)
3
julia> parse_expr(parser, "something")
ERROR: ParseError: Expected type `Number`, got `something` of type `String`.
julia> parse_expr(parser, 4)
ERROR: ParseError: Predicate `isodd` returned false on expr `4`.
julia> parse_expr(parser, 5)
ERROR: ParseError: Using default `==` comparison, but parser `3` ≠ value `5`.
Meta ExprParser
ExprParsers.Named
— TypeEP.Named{:MyTag}(parser)
Construct an ExprParser with a type identified by MyTag
. This is helpful if you have multiple versions of a similar parser and would like to easily distinguish them during dispatch.
The Named{:MyTag}
wrapper is also passed on to the parsed value.
Works with any ExprParser, also custom defined ones.
Examples
julia> using ExprParsers
julia> parser1 = EP.Named{:simple}(EP.Assignment(left = EP.anysymbol));
julia> parser2 = EP.Named{:any}(EP.Assignment());
julia> parse_expr(parser1, :(a = 4))
ExprParsers.Named{:simple,ExprParsers.Assignment_Parsed}(EP.Assignment_Parsed(left=:a, right=4))
julia> parse_expr(parser1, :(a.b = 4))
ERROR: ParseError: Expected type `Symbol`, got `a.b` of type `Expr`.
julia> parse_expr(parser2, :(a = 4))
ExprParsers.Named{:any,ExprParsers.Assignment_Parsed}(EP.Assignment_Parsed(left=:a, right=4))
julia> parse_expr(parser2, :(a.b = 4))
ExprParsers.Named{:any,ExprParsers.Assignment_Parsed}(EP.Assignment_Parsed(left=:(a.b), right=4))
ExprParsers.Indexed
— TypeEP.Indexed(func_expecting_dict_as_only_argument)
Constructs an ExprParser where you can access dedicated subexpressions/subparsers via Dictionary lookup. Most importantly, the shortcuts are preserved during parse_expr()
.
Works with any ExprParser, also custom defined ones.
Concretely, here a toy example
EP.Indexed() do dict
EP.Expr(quote
a = $(dict[:a] = EP.Isa(Int))
b = $(dict[:b] = EP.anysymbol)
end)
end
As you can see, EP.Indexed
is expecting a function which takes a dict
as the only argument. It best used with do-notation. The function then needs to return an ExprParser
, but can do whatever it wants in principle. Shortcuts are now assigned by just using interpolation syntax $(...)
and storing references to subparser into the given dict
. For example you see that EP.Isa(Int)
is captured as dict[:a]
before being used as a subparser.
Examples
julia> using ExprParsers
julia> parser = EP.Indexed() do dict
EP.Expr(quote
a = $(dict[:a] = EP.Isa(Int))
b = $(dict[:b] = EP.anysymbol)
end)
end;
julia> parser[:a]
ExprParsers.Isa{Int64}()
julia> parsed = parse_expr(parser, quote
a = 42
b = a
end);
julia> parsed[:a], parsed[:b]
(42, :a)
julia> parse_expr(parser, quote
a = 42
b = :notasymbol
end);
ERROR: ParseError: Expected type `Symbol`, got `:notasymbol` of type `QuoteNode`.
ExprParserWithParsed
All these ExprParsers have a corresponding ..._Parsed
object which captures the parsed information. I.e. there is EP.Function
and when it is parsed with parse_expr
it will return an EP.Function_Parsed
.
ExprParsers.Expr
— TypeEP.Expr(head = EP.anything, args = EP.anything)
EP.Expr(expr; [ignore_linenumbernodes=true])
It is the most flexible parser, but hence also the least plug-and-play.
Parses the following
Base.Expr(head, args...)
Examples
julia> using ExprParsers
julia> parser = EP.Expr(head = :vect);
julia> parse_expr(parser, :([1,2,3]))
EP.Expr_Parsed(
head = :vect
args = Any[1, 2, 3]
)
julia> parse_expr(parser, :(f(a) = a))
ERROR: ParseError: Using default `==` comparison, but parser `:vect` ≠ value `:(=)`.
Also see Indexed
for an example to combine EP.Indexed
with EP.Expr
.
ExprParsers.Block
— TypeEP.Block(block_expr; [ignore_linenumbernodes = true])
EP.Block(expr1, expr2, ...; [ignore_linenumbernodes = true])
EP.Block()
Helper to parse blocks of code (i.e. expr.head == :block
) or a given list of expr respectively.
The main purpose is to handle linenumbernodes, otherwise it behaves similar to plain Vector of Expr.
Parses the following
quote
any
4
end
[:(a = 4), 42, :anyvector]
(:(a = 4), 42, :or_tuple_of_expr)
end
Examples
julia> using ExprParsers
julia> parser = EP.Block(quote
$(EP.anything)
$(EP.anysymbol)
13
end);
julia> parse_expr(parser, [:(a = 4), :hi, 13])
EP.Block_Parsed(
exprs = Any[:(a = 4), :hi, 13]
)
julia> parse_expr(parser, quote
whatever(a) = a
asymbol
14
end)
ERROR: ParseError: Using default `==` comparison, but parser `13` ≠ value `14`.
Used within EP.Expr
.
ExprParsers.Macro
— TypeEP.Macro(name = EP.anything, args = EP.anything, linenumber = EP.Isa(LineNumberNode))
Parses the following
@macroname arg1 arg2 ...
Examples
julia> using ExprParsers
julia> parser = EP.Macro(name = :mymacro);
julia> parse_expr(parser, :(@mymacro 1 two))
EP.Macro_Parsed(
name = :mymacro
args = Any[1, :two]
linenumber = :(#= none:1 =#)
)
julia> parse_expr(parser, :(@anothermacro))
ERROR: ParseError: Using default `==` comparison, but parser `:mymacro` ≠ value `:anothermacro`.
ExprParsers.Assignment
— TypeEP.Assignment(left = EP.anything, right = EP.anything)
Parses the following
left = right
Examples
julia> using ExprParsers
julia> parser = EP.Assignment(left = EP.anysymbol)
EP.Assignment(
left = ExprParsers.Isa{Symbol}()
right = ExprParsers.Isa{Any}()
)
julia> parse_expr(parser, :(a = [1,2,3,4]))
EP.Assignment_Parsed(
left = :a
right = :([1, 2, 3, 4])
)
julia> parse_expr(parser, :(f(a) = a))
ERROR: ParseError: Expected type `Symbol`, got `f(a)` of type `Expr`.
ExprParsers.NestedDot
— TypeEP.NestedDot(base = EP.anything, properties = EP.anything)
Parses the following
a.b
fun(T{:hi}).b.c.d.e.f
Examples
julia> using ExprParsers; using Base.Iterators
julia> parser = EP.NestedDot(
properties = EP.Iterator(repeated(
EP.SatisfiesPredicate("It should start with 'a'.") do x
startswith(string(x), "a")
end
))
);
julia> parse_expr(parser, :(fun(T{:hi}).aone.atwo.athree))
EP.NestedDot_Parsed(
base = :(fun(T{:hi}))
properties = [:aone, :atwo, :athree]
)
julia> parse_expr(parser, :(fun(T{:hi}).aone.btwo.athree))
ERROR: ParseError: Predicate `#1` returned false on expr `btwo`. It should start with 'a'.
ExprParsers.Reference
— TypeEP.Reference(name = EP.anything, curlies = EP.anything)
Parses the following
a
a{b, c}
Examples
julia> using ExprParsers
julia> parser = EP.Reference(curlies = [:A, EP.anysymbol])
EP.Reference(
name = ExprParsers.Isa{Any}()
curlies = Any[:A, ExprParsers.Isa{Symbol}()]
)
julia> parse_expr(parser, :(SomeType{A, B}))
EP.Reference_Parsed(
name = :SomeType
curlies = [:A, :B]
)
julia> parse_expr(parser, :(SomeType{A}))
ERROR: ParseError: length(parser) == length(values) = false
length(parser) = 2
parser = Any[:A, ExprParsers.Isa{Symbol}()]
length(values) = 1
values = Any[:A]
julia> parse_expr(parser, :(SomeType{B, C}))
ERROR: ParseError: Using default `==` comparison, but parser `:A` ≠ value `:B`.
julia> parse_expr(parser, :(SomeType{A, 1}))
ERROR: ParseError: Expected type `Symbol`, got `1` of type `Int64`.
ExprParsers.Call
— TypeEP.Call(
name = EP.anything,
curlies = EP.anything,
args = EP.anything,
kwargs = EP.anything)
Parses the following
a()
a(b, c)
a{b, c}(d, e)
a{b, c}(d, e, f = 1; g = :two)
Note that all keyword arguments are collected into the kwargs
field, also those before ;
, corresponding to standard julia call semantics.
Note that keyword arguments are represented using the default Expr representation Expr(:kw, :key, "value")
.
Examples
julia> using ExprParsers
julia> parser = EP.Call(name = :myfunc)
EP.Call(
name = :myfunc
curlies = ExprParsers.Isa{Any}()
args = ExprParsers.Isa{Any}()
kwargs = ExprParsers.Isa{Any}()
)
julia> parse_expr(parser, :(myfunc(a, b, c = 1; d = :hi)))
EP.Call_Parsed(
name = :myfunc
curlies = Any[]
args = Any[:a, :b]
kwargs = Any[:($(Expr(:kw, :c, 1))), :($(Expr(:kw, :d, :(:hi))))]
)
julia> parse_expr(parser, :(anotherfunc(a, b, c = 1; d = :hi)))
ERROR: ParseError: Using default `==` comparison, but parser `:myfunc` ≠ value `:anotherfunc`.
ExprParsers.Signature
— TypeEP.Signature(
name = EP.anything,
curlies = EP.anything,
args = EP.anything,
kwargs = EP.anything,
wheres = EP.anything)
Similar to EP.Call
but with a couple of differences
- extra
wheres
- the
name
field might stay empty args
can also containExpr(:kw, key, value)
values (corresponds to default value syntax, which is only available in signatures)
Parses the following:
a(b, c::Any)
a(b::B, c) where B
(::Any, c::C) where {C <: Number}
f(::Any, c::C, d::Int=1; e=true) where {C <: Number}
Examples
julia> using ExprParsers
julia> parser = EP.Signature()
EP.Signature(
name = ExprParsers.Isa{Any}()
curlies = ExprParsers.Isa{Any}()
args = ExprParsers.Isa{Any}()
kwargs = ExprParsers.Isa{Any}()
wheres = ExprParsers.Isa{Any}()
)
julia> parse_expr(parser, :(f{T}(a::T) where T))
EP.Signature_Parsed(
name = :f
curlies = Any[:T]
args = Any[:(a::T)]
kwargs = Any[]
wheres = Any[:T]
)
julia> parse_expr(parser, :((a, b::T) where T))
EP.Signature_Parsed(
name = nothing
curlies = Any[]
args = Any[:a, :(b::T)]
kwargs = Any[]
wheres = Any[:T]
)
julia> parse_expr(parser, :(f(a, b::T, c::Any=3; d=true) where T))
EP.Signature_Parsed(
name = :f
curlies = Any[]
args = Any[:a, :(b::T), :($(Expr(:kw, :(c::Any), 3)))]
kwargs = Any[:($(Expr(:kw, :d, true)))]
wheres = Any[:T]
)
julia> parse_expr(parser, :(f(a) = a))
ERROR: ParseError: expr.head in (:where, :call, :tuple) = false
expr.head = :(=)
expr = :(f(a) = begin
#= none:1 =#
a
end)
(:where, :call, :tuple) = (:where, :call, :tuple)
ExprParsers.Function
— TypeEP.Function(
name = EP.anything,
curlies = EP.anything,
args = EP.anything,
kwargs = EP.anything,
wheres = EP.anything,
body = EP.anything)
Parses full functions. For instance
function a(b, c) where B
d
end
a(b, c) = d
Examples
julia> using ExprParsers
julia> parser = EP.Function(
args = [EP.anything for i in 1:3],
)
EP.Function(
name = ExprParsers.Isa{Any}()
curlies = ExprParsers.Isa{Any}()
args = [ExprParsers.Isa{Any}(), ExprParsers.Isa{Any}(), ExprParsers.Isa{Any}()]
kwargs = ExprParsers.Isa{Any}()
wheres = ExprParsers.Isa{Any}()
body = ExprParsers.Isa{Any}()
)
julia> parse_expr(parser, :(f(a, b, c) = a + b + c))
EP.Function_Parsed(
name = :f
curlies = Any[]
args = [:a, :b, :c]
kwargs = Any[]
wheres = Any[]
body = quote
#= none:1 =#
a + b + c
end
)
julia> parse_expr(parser, :(
function g(a)
a
end
))
ERROR: ParseError: length(parser) == length(values) = false
length(parser) = 3
parser = [ExprParsers.Isa{Any}(), ExprParsers.Isa{Any}(), ExprParsers.Isa{Any}()]
length(values) = 1
values = Any[:a]
julia> parse_expr(parser, :a)
ERROR: ParseError: ExprParsers.Function has no `parse_expr` method defined to capture Type `Symbol`. Got: `a`.
ExprParsers.Type
— TypeEP.Type(name = EP.anything, curlies = EP.anything, wheres = EP.anything)
Parses the following:
a
a{b, c}
a{d} where d
Examples
julia> using ExprParsers
julia> parser = EP.Type()
EP.Type(
name = ExprParsers.Isa{Any}()
curlies = ExprParsers.Isa{Any}()
wheres = ExprParsers.Isa{Any}()
)
julia> parse_expr(parser, :(Array{T, 2} where T))
EP.Type_Parsed(
name = :Array
curlies = Any[:T, 2]
wheres = Any[:T]
)
julia> parse_expr(parser, :(f(1,2)))
ERROR: ParseError: Cannot parse expr `f(1, 2)` as reference: expr.head `call` not in `[:curly, :.]`.
ExprParsers.TypeRange
— TypeEP.TypeRange(lb = EP.anything, name = EP.anything, ub = EP.anything)
Note: Construct with typevar = EP.anysymbol
to guarantee that only plain symbols can be used as type variable.
Parses the following.
TypeVar >: LowerBound
TypeVar <: UpperBound
LowerBound <: TypeVar <: UpperBound
Examples
julia> using ExprParsers
julia> parser = EP.TypeRange(name = EP.anysymbol)
EP.TypeRange(
lb = ExprParsers.Isa{Any}()
name = ExprParsers.Isa{Symbol}()
ub = ExprParsers.Isa{Any}()
)
julia> parse_expr(parser, :(Int <: T <: Number))
EP.TypeRange_Parsed(
lb = :Int
name = :T
ub = :Number
)
julia> parse_expr(parser, :(T <: Number))
EP.TypeRange_Parsed(
lb = Union{}
name = :T
ub = :Number
)
julia> parse_expr(parser, :(Int <: 4)) # CAUTION: when using single `<:`, the order is decisive!
EP.TypeRange_Parsed(
lb = Union{}
name = :Int
ub = 4
)
julia> parse_expr(parser, :(4 >: Int))
ERROR: ParseError: Expected type `Symbol`, got `4` of type `Int64`.
julia> parse_expr(parser, :(4 <: Int))
ERROR: ParseError: Expected type `Symbol`, got `4` of type `Int64`.
ExprParsers.TypeAnnotation
— TypeEP.TypeAnnotation(name = EP.anything, type = EP.anything)
Parses the following
a
a::B
::B
Examples
julia> using ExprParsers
julia> parser = EP.TypeAnnotation(type = :Int)
EP.TypeAnnotation(
name = ExprParsers.Isa{Any}()
type = :Int
)
julia> parse_expr(parser, :(::Int))
EP.TypeAnnotation_Parsed(
name = nothing
type = :Int
)
julia> parse_expr(parser, :(a::Int))
EP.TypeAnnotation_Parsed(
name = :a
type = :Int
)
julia> parse_expr(parser, :(a::String))
ERROR: ParseError: Using default `==` comparison, but parser `:Int` ≠ value `:String`.
ExprParsers.Arg
— TypeEP.Arg(name = EP.anything, type = EP.anything, default = EP.anything)
A missing default value is indicated by the special variable EP.nodefault
which is the unique instance of the singleton type EP.NoDefault
.
Parses the following
a
a::B
::B
a = c # only :($(Expr(:kw, :a, :c))), not plain :(a = c)
a::B = c # only :($(Expr(:kw, :(a::B), :c))), not plain :(a::B = c)
Examples
julia> using ExprParsers
julia> parser = EP.Arg()
EP.Arg(
name = ExprParsers.Isa{Any}()
type = ExprParsers.Isa{Any}()
default = ExprParsers.Isa{Any}()
)
julia> parse_expr(parser, :(a::B))
EP.Arg_Parsed(
name = :a
type = :B
default = ExprParsers.NoDefault()
)
julia> parse_expr(parser, Expr(:kw, :a, 3))
EP.Arg_Parsed(
name = :a
type = Any
default = 3
)
julia> parse_expr(parser, :(a = 3))
ERROR: ParseError: AnyOf could not parse expr `a = 3` with any of the parsers `(ExprParsers.Isa{Symbol}(), EP.TypeAnnotation(name=ExprParsers.Isa{Any}(), type=ExprParsers.Isa{Any}()))`. Arg should either be a Symbol or a TypeAnnotation.
julia> parse_expr(parser, :(f(a)))
ERROR: ParseError: AnyOf could not parse expr `f(a)` with any of the parsers `(ExprParsers.Isa{Symbol}(), EP.TypeAnnotation(name=ExprParsers.Isa{Any}(), type=ExprParsers.Isa{Any}()))`. Arg should either be a Symbol or a TypeAnnotation.