- This is the code I have so far:
use super::*;
use combine::error::UnexpectedParse;
use combine::parser::char::digit;
use combine::parser::choice::optional;
use combine::parser::item::item;
use combine::parser::range::recognize;
use combine::parser::repeat::{skip_many, skip_many1};
use combine::Parser;
use combine_language::{LanguageEnv, LanguageDef, Identifier};
use combine::char::{letter, alpha_num, string};
use combine::satisfy;
use crate::mma::data::Expr;
use combine::parser::combinator::{Recognize, AndThen};
mod read;
fn main() {
let mut parser = recognize((
skip_many1(digit::<&str>()),
optional((item('.'), skip_many(digit())))))
.and_then( str_to_bignum);
let t : Parser<Input = &str, Output = Expr> = parser;
}
pub fn str_to_bignum(s: &str) -> Result<Expr, combine::error::StringStreamError> {
unimplemented!()
}
-
I am trying to shove the variable parser
into the trait Parser
-
I'm guessing the values for Input = &str
and Output = Expr
. I have no idea what to specify ro PartialState. I am getting error of:
|
24 | let t : Parser<Input = &str, Output = Expr> = parser;
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn combine::Parser<Output=mma::data::Expr, Input=&str>`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
You're trying to own a trait object without it being behind reference/pointer of some sort. This is not allowed in local scopes. This has nothing to do with the type parameters of Parser
as this is about the unsizedness of t
. I recommend using a box:
let t: Box<dn Parser<Input = &str, Output = Expr> = Box::new(parser);
And then you can sort out the proper type parameters. Unravel your errors one at a time. If the compiler doesn't mention it, then that means that it hasn't gotten to that stage in compilation yet.
So now we have:
use super::*;
use combine::error::UnexpectedParse;
use combine::parser::char::digit;
use combine::parser::choice::optional;
use combine::parser::item::item;
use combine::parser::range::recognize;
use combine::parser::repeat::{skip_many, skip_many1};
use combine::Parser;
use combine_language::{LanguageEnv, LanguageDef, Identifier};
use combine::char::{letter, alpha_num, string};
use combine::satisfy;
use crate::mma::data::Expr;
use combine::parser::combinator::{Recognize, AndThen};
mod read;
fn main() {
let mut parser = recognize((
skip_many1(digit::<&str>()),
optional((item('.'), skip_many(digit())))))
.and_then( str_to_bignum);
let t : Box<Parser<Input = &str, Output = Expr, PartialState = ()>> = Box::new(parser);
}
pub fn str_to_bignum(s: &str) -> Result<Expr, combine::error::StringStreamError> {
unimplemented!()
}
This gives error:
|
24 | let t : Box<Parser<Input = &str, Output = Expr, PartialState = ()>> = Box::new(parser);
| ^^^^^^^^^^^^^^^^ expected tuple, found ()
|
= note: expected type `(usize, combine::combinator::PartialState2<combine::combinator::SequenceState<(), (bool, bool, combine::combinator::Sink, ())>, combine::combinator::SequenceState<std::option::Option<(char, ())>, combine::combinator::PartialState2<combine::combinator::SequenceState<char, ()>, combine::combinator::SequenceState<(), (combine::combinator::Sink, ())>>>>)`
found type `()`
= note: required for the cast to the object type `dyn combine::Parser<Output=mma::data::Expr, Input=&str, PartialState=()>`
What is going on here? why is it expecting a tuple?
Okay, I've delved into the docs for you:
recognize<T>(T)
returns a Recognize<T>
, who is a Parser
, and its PartialState
is based off of RecognizeWithValue
's PartialState
which is not ()
.
1 Like