[−][src]Trait arithmetic_parser::grammars::ParseLiteral
Encapsulates parsing literals in a grammar.
Examples
If your grammar does not need to support type annotations, you can define a ParseLiteral
impl
and wrap it into Untyped
to get a Grammar
/ Parse
:
use arithmetic_parser::{ grammars::{Features, ParseLiteral, Parse, Untyped}, ErrorKind, InputSpan, NomResult, }; /// Grammar that parses `u64` numbers. #[derive(Debug)] struct IntegerGrammar; impl ParseLiteral for IntegerGrammar { type Lit = u64; // We use the `nom` crate to construct necessary parsers. fn parse_literal(input: InputSpan<'_>) -> NomResult<'_, Self::Lit> { use nom::{character::complete::digit1, combinator::map_res}; let parser = |s: InputSpan<'_>| { s.fragment().parse().map_err(ErrorKind::literal) }; map_res(digit1, parser)(input) } } // Here's how a grammar can be used. let program = r#" x = 1 + 2 * 3 + sin(a^3 / b^2); some_function = |a, b| (a + b, a - b); other_function = |x| { r = min(rand(), 0); r * x }; (y, z) = some_function({ x = x - 1; x }, x); other_function(y - z) "#; let parsed = Untyped::<IntegerGrammar>::parse_statements(program)?; println!("{:#?}", parsed);
Associated Types
Loading content...Required methods
pub fn parse_literal(input: InputSpan<'_>) -> NomResult<'_, Self::Lit>
[src]
Attempts to parse a literal.
Literals should follow these rules:
- A literal must be distinguished from other constructs, in particular, variable identifiers.
- If a literal may end with
.
and methods are enabled inParse::FEATURES
, care should be taken for cases when.
is a part of a call, rather than a part of a literal. For example, a parser for real-valued literals should interpret1.abs()
as a call of theabs
method on receiver1
, rather than1.
followed by ineligibleabs()
.
If a literal may start with -
or !
(in general, unary ops), these ops will be
consumed as a part of the literal, rather than Expr::Unary
, unless the literal
is followed by an eligible higher-priority operation (i.e., a method call) and
the literal without a preceding unary op is still eligible. That is, if -1
and 1
are both valid literals, then -1.abs()
will be parsed as negation applied to 1.abs()
.
On the other hand, if !foo!
is a valid literal, but foo!
isn't, !foo!.bar()
will
be parsed as method bar()
called on !foo!
.
Return value
The output should follow nom
conventions on errors / failures.