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;
use combine_language::LanguageDef;
use combine_language::Identifier;
use combine::char::letter;
use combine::char::alpha_num;
use combine::satisfy;
use combine::char::string;
use crate::mma::data::Expr;
use combine::parser::combinator::Recognize;
use combine::parser::combinator::AndThen;
mod read;
fn main() {
let mut parser = recognize((
skip_many1(digit()),
optional((item('.'), skip_many(digit())))))
.and_then( str_to_bignum);
let result = parser.parse("123");
// println!("result: {:?}", result);
}
pub fn str_to_bignum(s: &str) -> Result<Expr, combine::error::StringStreamError> {
let v: Vec<&str> = s.split('.').collect();
let start = v[0];
let bint = BInt::new_from_u8(start.as_bytes())
.ok_or(combine::error::StringStreamError::UnexpectedParse)?;
if v.len() == 1 { return Ok(Expr::BInt(bint)); }
let dec = v[1];
if dec.len() == 0 { return Ok(Expr::BInt(bint)); }
return Ok(Expr::BFloat(bint.attach_real(dec.as_bytes()).unwrap()))
}
Now, if we comment out the "let result = parser.parse("123")` line, then we get the following error:
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;
use combine_language::LanguageDef;
use combine_language::Identifier;
use combine::char::letter;
use combine::char::alpha_num;
use combine::satisfy;
use combine::char::string;
use crate::mma::data::Expr;
use combine::parser::combinator::Recognize;
use combine::parser::combinator::AndThen;
mod read;
fn main() {
let mut parser = recognize((
skip_many1(digit()),
optional((item('.'), skip_many(digit())))))
.and_then( str_to_bignum);
// let result = parser.parse("123");
// println!("result: {:?}", result);
}
pub fn str_to_bignum(s: &str) -> Result<Expr, combine::error::StringStreamError> {
let v: Vec<&str> = s.split('.').collect();
let start = v[0];
let bint = BInt::new_from_u8(start.as_bytes())
.ok_or(combine::error::StringStreamError::UnexpectedParse)?;
if v.len() == 1 { return Ok(Expr::BInt(bint)); }
let dec = v[1];
if dec.len() == 0 { return Ok(Expr::BInt(bint)); }
return Ok(Expr::BFloat(bint.attach_real(dec.as_bytes()).unwrap()))
}
Error:
error[E0284]: type annotations required: cannot resolve `<_ as combine::StreamOnce>::Error == _`
|
25 | let mut parser = recognize((
| ^^^^^^^^^
error: aborting due to previous error
My question: so I need to add a type signature to "parser" .. what type signature do I add?
Well, it was most likely not done by hand, as this is just an error surrounding a generic issue and type inferences. Therefore, there was no need to derive the entire type, just the fact that there is a missing generic type, which is clearly related to the parameter of the parse method.
Actually I misread the question and a post above; but my point still holds; there was a missing signature somewhere
The ugly long type was copied from vscode variable popup. (deliberate errors are another good way, as you demonstrate.)
I don't know the library but the docs are there on docs.rs so can read the functions.
The parse call hints the type is &str
Looking at the other functions in the docs gives insight into there types.
Could also use turbofish on skip_many1 or recognize, but generally easier to place the type on inside function.
I deduced enough for important trait. Filling in let _: &dyn Parser was also just reading the error and filling in the missing but could have read from docs too.