Public API
Interface
ExprParsers.EP — ModuleEP = ExprParsersShort 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 = 3Adapted from Base.@assert
ExprParsers.ParseError — TypeEP.ParseErrorSpecial Exception Type to indicate that some parsing failed.
Types
ExprParsers.ExprParser — TypeEP.ExprParserAll parsers in the ExprParsers package inherit from this type.
ExprParsers.ExprParserWithParsed — TypeEP.ExprParserWithParsedThis 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_ParsedExprParsers.@exprparser — MacroEP.@exprparser struct MySymbol
symbol = EP.anything = :default_parsed_value
endis 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_ParsedIt 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
ExprParserto 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
endCore 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)
:whateverExprParsers.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)
endAs 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)
endExamples
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 = rightExamples
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.fExamples
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
namefield might stay empty argscan 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) = dExamples
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 dExamples
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 <: UpperBoundExamples
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
::BExamples
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.