Struct LexerOfString

Source
pub struct LexerOfString<P, T, E>{ /* private fields */ }
Expand description

This provides a type that wraps an allocated String, and which tracks the lines within the string. It then provides a method to create a LexerOfStr that borrows the text, and which can the be used as a crate::Lexer.

This type also implements the FmtContext trait, which allows for pretty-printing the text between certain lines, to highlight certain characters or regions of the text.

Should the LexerOfStr return an error while parsing then the FmtContext implementation can be used to generate a very useful error message with the context of the error.

This also applies should the LexerOfStr output be used in a further grammar - the methods to pretty-print the text require just start and end positions of the position type, which must support PosnInCharStream.

The LexerOfString may be used more than once, replacing its text if necessary before a new parse is initiated. The String can also be retrieved, which is useful for droppign the LexerOfString but retaining the text for future parse or compilation stages

Implementations§

Source§

impl<P, T, E> LexerOfString<P, T, E>
where P: PosnInCharStream, T: Debug + Clone, E: LexerError<P>,

Source

pub fn set_text<S: Into<String>>(self, text: S) -> Self

Set the text

Examples found in repository?
examples/calc.rs (line 158)
151fn main() -> Result<(), String> {
152    let args: Vec<String> = env::args().collect();
153    if args.len() < 2 {
154        return Err(format!("Usage: {} <expression>", args[0]));
155    }
156    let args_as_string = args[1..].join(" ");
157    let c = CalcTokenParser::new();
158    let l = LexerOfString::default().set_text(args_as_string);
159    let ts = l.lexer();
160
161    // let ts = TextStream::new(&args_as_string);
162
163    println!("Parsing");
164    let tokens = c.iter(&ts);
165    for t in tokens {
166        let t = {
167            match t {
168                Err(e) => {
169                    println!();
170                    let mut s = String::new();
171                    l.fmt_context(&mut s, &e.pos, &e.pos).unwrap();
172                    eprintln!("{}", s);
173                    return Err(format!("{}", e));
174                }
175                Ok(t) => t,
176            }
177        };
178        print!("{}", t);
179    }
180    println!();
181    println!("Text parsed okay");
182    Ok(())
183}
More examples
Hide additional examples
examples/simple.rs (line 214)
201fn main() -> Result<(), String> {
202    let args: Vec<String> = env::args().collect();
203    if args.len() < 2 {
204        return Err(format!("Usage: {} <expression>", args[0]));
205    }
206    let args_as_string = args[1..].join(" ");
207
208    let mut parsers = ParserVec::new();
209    parsers.add_parser(|a, b, c| LexToken::parse_whitespace(a, b, c));
210    parsers.add_parser(|a, b, c| LexToken::parse_comment_line(a, b, c));
211    parsers.add_parser(|a, b, c| LexToken::parse_digits(a, b, c));
212    parsers.add_parser(|a, b, c| LexToken::parse_char(a, b, c));
213
214    let l = LexerOfString::default().set_text(args_as_string);
215    let ts = l.lexer();
216    let tokens = ts.iter(&parsers.parsers);
217
218    println!("Parsing");
219    for t in tokens {
220        let t = {
221            match t {
222                Err(e) => {
223                    println!();
224                    let mut s = String::new();
225                    l.fmt_context(&mut s, &e.pos, &e.pos).unwrap();
226                    eprintln!("{}", s);
227                    return Err(format!("{}", e));
228                }
229                Ok(t) => t,
230            }
231        };
232        println!("{:?}", t);
233    }
234    println!();
235    println!("Text parsed okay");
236    Ok(())
237}
Source

pub fn take_text(&mut self) -> String

Take the text as a String out of the LexerOfString

Source

pub fn text(&self) -> &str

Get a str reference to the text content

Source

pub fn lexer(&self) -> LexerOfStr<'_, P, T, E>

Create a LexerOfStr that will parse the text

Examples found in repository?
examples/calc.rs (line 159)
151fn main() -> Result<(), String> {
152    let args: Vec<String> = env::args().collect();
153    if args.len() < 2 {
154        return Err(format!("Usage: {} <expression>", args[0]));
155    }
156    let args_as_string = args[1..].join(" ");
157    let c = CalcTokenParser::new();
158    let l = LexerOfString::default().set_text(args_as_string);
159    let ts = l.lexer();
160
161    // let ts = TextStream::new(&args_as_string);
162
163    println!("Parsing");
164    let tokens = c.iter(&ts);
165    for t in tokens {
166        let t = {
167            match t {
168                Err(e) => {
169                    println!();
170                    let mut s = String::new();
171                    l.fmt_context(&mut s, &e.pos, &e.pos).unwrap();
172                    eprintln!("{}", s);
173                    return Err(format!("{}", e));
174                }
175                Ok(t) => t,
176            }
177        };
178        print!("{}", t);
179    }
180    println!();
181    println!("Text parsed okay");
182    Ok(())
183}
More examples
Hide additional examples
examples/simple.rs (line 215)
201fn main() -> Result<(), String> {
202    let args: Vec<String> = env::args().collect();
203    if args.len() < 2 {
204        return Err(format!("Usage: {} <expression>", args[0]));
205    }
206    let args_as_string = args[1..].join(" ");
207
208    let mut parsers = ParserVec::new();
209    parsers.add_parser(|a, b, c| LexToken::parse_whitespace(a, b, c));
210    parsers.add_parser(|a, b, c| LexToken::parse_comment_line(a, b, c));
211    parsers.add_parser(|a, b, c| LexToken::parse_digits(a, b, c));
212    parsers.add_parser(|a, b, c| LexToken::parse_char(a, b, c));
213
214    let l = LexerOfString::default().set_text(args_as_string);
215    let ts = l.lexer();
216    let tokens = ts.iter(&parsers.parsers);
217
218    println!("Parsing");
219    for t in tokens {
220        let t = {
221            match t {
222                Err(e) => {
223                    println!();
224                    let mut s = String::new();
225                    l.fmt_context(&mut s, &e.pos, &e.pos).unwrap();
226                    eprintln!("{}", s);
227                    return Err(format!("{}", e));
228                }
229                Ok(t) => t,
230            }
231        };
232        println!("{:?}", t);
233    }
234    println!();
235    println!("Text parsed okay");
236    Ok(())
237}

Trait Implementations§

Source§

impl<P, T: Debug, E: Debug> Debug for LexerOfString<P, T, E>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<P, T, E> Default for LexerOfString<P, T, E>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<P, T, E> FmtContext<P> for LexerOfString<P, T, E>
where P: PosnInCharStream, E: LexerError<P>,

Source§

fn line_length(&self, line: usize) -> usize

Return the length of the specified line
Source§

fn fmt_line(&self, f: &mut dyn Write, line: usize) -> Result

Format the line of text (potentially with coloring and so on). Read more
Source§

fn fmt_context_single_line( &self, f: &mut dyn Write, start: &P, num_cols: usize, ) -> Result
where P: UserPosn,

Format a line of text with highlight on certain columns
Source§

fn fmt_context_multiple_lines( &self, f: &mut dyn Write, start: &P, end: &P, ) -> Result
where P: UserPosn,

Format multiple lines of text, highlighting certain lines
Source§

fn fmt_context(&self, fmt: &mut dyn Write, start: &P, end: &P) -> Result
where P: UserPosn,

Format text with highlighting between start and end Read more

Auto Trait Implementations§

§

impl<P, T, E> Freeze for LexerOfString<P, T, E>

§

impl<P, T, E> RefUnwindSafe for LexerOfString<P, T, E>

§

impl<P, T, E> Send for LexerOfString<P, T, E>
where T: Send, E: Send, P: Send,

§

impl<P, T, E> Sync for LexerOfString<P, T, E>
where T: Sync, E: Sync, P: Sync,

§

impl<P, T, E> Unpin for LexerOfString<P, T, E>
where T: Unpin, E: Unpin, P: Unpin,

§

impl<P, T, E> UnwindSafe for LexerOfString<P, T, E>
where T: UnwindSafe, E: UnwindSafe, P: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.