Struct ParseBuffer

Source
pub struct ParseBuffer<'a> { /* private fields */ }
Expand description

A cursor position within a token stream.

Implementations§

Source§

impl<'a> ParseBuffer<'a>

Source

pub fn parse<T: Parse>(&self) -> Result<T>

Attempts to parse self into the given syntax tree node, using T’s default parsing implementation.

§Errors

Returns an error if T’s Parse implementation fails.

Examples found in repository?
examples/calc.rs (line 45)
41    fn parse(input: ParseStream) -> Result<Self> {
42        let mut expr = factor(input)?;
43        loop {
44            if input.peek(Punct!["+"]) {
45                expr = Expr::Add(Box::new(expr), input.parse()?, Box::new(factor(input)?));
46            } else if input.peek(Punct!["-"]) {
47                expr = Expr::Sub(Box::new(expr), input.parse()?, Box::new(factor(input)?));
48            } else {
49                break;
50            }
51        }
52        Ok(expr)
53    }
54}
55
56fn factor(input: ParseStream) -> Result<Expr> {
57    let mut expr: Expr = unary(input)?;
58    loop {
59        if input.peek(Punct!["*"]) {
60            expr = Expr::Mul(Box::new(expr), input.parse()?, Box::new(unary(input)?));
61        } else if input.peek(Punct!["/"]) {
62            expr = Expr::Div(Box::new(expr), input.parse()?, Box::new(unary(input)?));
63        } else if input.peek(Punct!["%"]) {
64            expr = Expr::Mod(Box::new(expr), input.parse()?, Box::new(unary(input)?));
65        } else {
66            break;
67        }
68    }
69    Ok(expr)
70}
71
72fn unary(input: ParseStream) -> Result<Expr> {
73    if input.peek(Punct!["-"]) {
74        Ok(Expr::Neg(input.parse()?, Box::new(unary(input)?)))
75    } else {
76        primary(input)
77    }
78}
79
80#[allow(clippy::cast_precision_loss)]
81fn primary(input: ParseStream) -> Result<Expr> {
82    let lookahead = input.lookahead();
83    if lookahead.peek(token::LitFloat) {
84        Ok(Expr::Num(input.parse::<token::LitFloat>()?.value()))
85    } else if lookahead.peek(token::LitInt) {
86        Ok(Expr::Num(input.parse::<token::LitInt>()?.value() as f64))
87    } else if lookahead.peek(token::LeftParen) {
88        let group: Group<Parentheses> = input.parse()?;
89        parse(group.into_token_stream())
90    } else {
91        Err(lookahead.error())
92    }
93}
More examples
Hide additional examples
examples/lox/main.rs (line 196)
192    fn assignment(input: ParseStream) -> Result<Self> {
193        let expr = Expr::or(input)?;
194
195        if input.peek(Punct!["="]) {
196            let equals: Punct!["="] = input.parse()?;
197            let value = Box::new(Expr::assignment(input)?);
198
199            if let Expr::Variable { name, .. } = expr {
200                return Ok(Expr::Assign {
201                    name,
202                    value,
203                    distance: Cell::new(None),
204                });
205            } else if let Expr::Get { object, name } = expr {
206                return Ok(Expr::Set {
207                    object,
208                    name,
209                    value,
210                });
211            }
212
213            input.add_error(input.new_error(
214                "Invalid assignment target".to_string(),
215                &equals,
216                error_codes::INVALID_ASSIGN,
217            ));
218        }
219
220        Ok(expr)
221    }
222
223    fn or(input: ParseStream) -> Result<Self> {
224        let mut expr = Expr::and(input)?;
225
226        while input.peek(kw::or) {
227            expr = Expr::Logical(Box::new(Logical::Or(
228                expr,
229                input.parse()?,
230                Expr::and(input)?,
231            )));
232        }
233
234        Ok(expr)
235    }
236
237    fn and(input: ParseStream) -> Result<Self> {
238        let mut expr = Expr::equality(input)?;
239
240        while input.peek(kw::and) {
241            expr = Expr::Logical(Box::new(Logical::And(
242                expr,
243                input.parse()?,
244                Expr::equality(input)?,
245            )));
246        }
247
248        Ok(expr)
249    }
250
251    fn equality(input: ParseStream) -> Result<Self> {
252        let mut expr = Expr::comparison(input)?;
253
254        loop {
255            if input.peek(Punct!["=="]) {
256                expr = Expr::binary(Binary::Equal(
257                    expr,
258                    input.parse()?,
259                    Expr::comparison(input)?,
260                ));
261            } else if input.peek(Punct!["!="]) {
262                expr = Expr::binary(Binary::NotEqual(
263                    expr,
264                    input.parse()?,
265                    Expr::comparison(input)?,
266                ));
267            } else {
268                break Ok(expr);
269            }
270        }
271    }
272
273    fn comparison(input: ParseStream) -> Result<Self> {
274        let mut expr = Expr::term(input)?;
275
276        loop {
277            if input.peek(Punct![">"]) {
278                expr = Expr::binary(Binary::Greater(expr, input.parse()?, Expr::term(input)?));
279            } else if input.peek(Punct![">="]) {
280                expr = Expr::binary(Binary::GreaterEqual(
281                    expr,
282                    input.parse()?,
283                    Expr::term(input)?,
284                ));
285            } else if input.peek(Punct!["<"]) {
286                expr = Expr::binary(Binary::Less(expr, input.parse()?, Expr::term(input)?));
287            } else if input.peek(Punct!["<="]) {
288                expr = Expr::binary(Binary::LessEqual(expr, input.parse()?, Expr::term(input)?));
289            } else {
290                break Ok(expr);
291            }
292        }
293    }
294
295    fn term(input: ParseStream) -> Result<Self> {
296        let mut expr = Expr::factor(input)?;
297
298        loop {
299            if input.peek(Punct!["+"]) {
300                expr = Expr::binary(Binary::Add(expr, input.parse()?, Expr::factor(input)?));
301            } else if input.peek(Punct!["-"]) {
302                expr = Expr::binary(Binary::Sub(expr, input.parse()?, Expr::factor(input)?));
303            } else {
304                break Ok(expr);
305            }
306        }
307    }
308
309    fn factor(input: ParseStream) -> Result<Self> {
310        let mut expr = Expr::unary(input)?;
311
312        loop {
313            if input.peek(Punct!["*"]) {
314                expr = Expr::binary(Binary::Mul(expr, input.parse()?, Expr::unary(input)?));
315            } else if input.peek(Punct!["/"]) {
316                expr = Expr::binary(Binary::Div(expr, input.parse()?, Expr::unary(input)?));
317            } else {
318                break Ok(expr);
319            }
320        }
321    }
322
323    fn unary(input: ParseStream) -> Result<Self> {
324        if input.peek(Punct!["-"]) {
325            Ok(Expr::Unary(Box::new(Unary::Neg(
326                input.parse()?,
327                Expr::unary(input)?,
328            ))))
329        } else if input.peek(Punct!["!"]) {
330            Ok(Expr::Unary(Box::new(Unary::Not(
331                input.parse()?,
332                Expr::unary(input)?,
333            ))))
334        } else {
335            Expr::call(input)
336        }
337    }
338
339    fn call(input: ParseStream) -> Result<Self> {
340        let mut expr = Expr::primary(input)?;
341
342        loop {
343            if input.peek(Punct!["("]) {
344                expr = Expr::finish_call(input, expr)?;
345            } else if input.peek(Punct!["."]) {
346                let _: Punct!["."] = input.parse()?;
347                let name: Ident = input.parse()?;
348                expr = Expr::Get {
349                    object: Box::new(expr),
350                    name,
351                };
352            } else {
353                break Ok(expr);
354            }
355        }
356    }
357
358    fn finish_call(input: ParseStream<'_>, callee: Expr) -> Result<Self> {
359        let content;
360        let paren: Parentheses = group!(content in input);
361        let arguments: Punctuated<Expr, Punct![","]> =
362            Punctuated::parse_separated_trailing(&content)?;
363        let arguments: Vec<_> = arguments.into_iter().collect();
364        if arguments.len() >= 255 {
365            input.add_error(input.new_error(
366                "Can't have more than 254 arguments".to_string(),
367                paren.0.clone(),
368                error_codes::TOO_MANY_ARGS,
369            ));
370        }
371        Ok(Expr::Call {
372            callee: Box::new(callee),
373            paren,
374            arguments,
375        })
376    }
377
378    fn primary(input: ParseStream) -> Result<Self> {
379        let lookahead = input.lookahead();
380        if lookahead.peek(kw::kw_false) {
381            Ok(Expr::Literal(Literal::False(input.parse()?)))
382        } else if lookahead.peek(kw::kw_true) {
383            Ok(Expr::Literal(Literal::True(input.parse()?)))
384        } else if lookahead.peek(kw::nil) {
385            Ok(Expr::Literal(Literal::Nil(input.parse()?)))
386        } else if lookahead.peek(LitFloat) {
387            Ok(Expr::Literal(Literal::Float(input.parse()?)))
388        } else if lookahead.peek(LitInt) {
389            Ok(Expr::Literal(Literal::Int(input.parse()?)))
390        } else if lookahead.peek(LitStr) {
391            Ok(Expr::Literal(Literal::String(input.parse()?)))
392        } else if input.peek(kw::kw_super) {
393            Ok(Expr::Super {
394                keyword: input.parse()?,
395                distance: Cell::new(None),
396                dot: input.parse()?,
397                method: kw::ident(input)?,
398            })
399        } else if input.peek(kw::this) {
400            Ok(Expr::This {
401                keyword: input.parse()?,
402                distance: Cell::new(None),
403            })
404        } else if lookahead.peek(Ident) {
405            Ok(Expr::Variable {
406                name: kw::ident(input)?,
407                distance: Cell::new(None),
408            })
409        } else if lookahead.peek(Punct!["("]) {
410            let content;
411            let _: Parentheses = group!(content in input);
412            Ok(Expr::Group(Box::new(content.parse()?)))
413        } else {
414            Err(lookahead.error())
415        }
416    }
417}
418
419impl Parse for Expr {
420    fn parse(input: ParseStream) -> Result<Self> {
421        Expr::assignment(input)
422    }
423}
424
425#[derive(Debug, Clone, PartialEq)]
426struct Function {
427    name: Ident,
428    params: Vec<Ident>,
429    body: Vec<Stmt>,
430}
431
432impl Parse for Function {
433    fn parse(input: ParseStream) -> Result<Self> {
434        let name: Ident = input.parse()?;
435        let mut contents: Group<Parentheses> = input.parse()?;
436        contents.remove_whitespace();
437        let Parentheses(span) = contents.delimiters();
438        let tokens = contents.into_token_stream();
439        let params: Vec<Ident> = if tokens.is_empty() {
440            vec![]
441        } else {
442            let params: Punctuated<Ident, Punct![","]> =
443                Punctuated::parse_separated.parse(tokens)?;
444            params.into_iter().collect()
445        };
446        if params.len() >= 255 {
447            input.add_error(input.new_error(
448                "Can't have more than 254 parameters".to_string(),
449                span,
450                error_codes::TOO_MANY_ARGS,
451            ));
452        }
453        let mut contents: Group<Braces> = input.parse()?;
454        contents.remove_whitespace();
455        let body = block.parse(contents.into_token_stream())?;
456        Ok(Function { name, params, body })
457    }
458}
459
460#[derive(Debug, Clone, PartialEq)]
461enum Stmt {
462    Block(Vec<Stmt>),
463    Class {
464        name: Ident,
465        superclass: Option<Ident>,
466        superclass_distance: Cell<Option<usize>>,
467        methods: Vec<Function>,
468    },
469    Expr(Expr),
470    Function(Function),
471    If {
472        condition: Expr,
473        then_branch: Box<Stmt>,
474        else_branch: Option<Box<Stmt>>,
475    },
476    Print(Expr),
477    Return {
478        keyword: kw::kw_return,
479        value: Option<Expr>,
480    },
481    Variable {
482        name: Ident,
483        initialiser: Option<Expr>,
484    },
485    While {
486        condition: Expr,
487        body: Box<Stmt>,
488    },
489}
490
491fn block(input: ParseStream) -> Result<Vec<Stmt>> {
492    let mut statements = vec![];
493
494    while !input.is_empty() {
495        statements.push(Stmt::declaration(input)?);
496    }
497
498    Ok(statements)
499}
500
501impl Stmt {
502    fn declaration(input: ParseStream) -> Result<Self> {
503        if input.peek(kw::class) {
504            Stmt::class_declaration(input)
505        } else if input.peek(kw::fun) {
506            let _: kw::fun = input.parse()?;
507            Ok(Stmt::Function(Function::parse(input)?))
508        } else if input.peek(kw::var) {
509            Stmt::var_declaration(input)
510        } else {
511            Stmt::statement(input)
512        }
513    }
514
515    fn class_declaration(input: ParseStream) -> Result<Self> {
516        let _: kw::class = input.parse()?;
517        let name: Ident = input.parse()?;
518
519        let superclass = if input.peek(Punct!["<"]) {
520            let _: Punct!["<"] = input.parse()?;
521            Some(input.parse()?)
522        } else {
523            None
524        };
525
526        let content;
527        let _: Braces = group!(content in input);
528        let methods = parse_repeated(&content)?;
529
530        Ok(Stmt::Class {
531            name,
532            superclass,
533            superclass_distance: Cell::new(None),
534            methods,
535        })
536    }
537
538    fn var_declaration(input: ParseStream) -> Result<Self> {
539        let _: kw::var = input.parse()?;
540
541        let name = kw::ident(input)?;
542
543        let initialiser = if input.peek(Punct!["="]) {
544            let _: Punct!["="] = input.parse()?;
545            Some(input.parse()?)
546        } else {
547            None
548        };
549
550        let _: Punct![";"] = input.parse()?;
551        Ok(Stmt::Variable { name, initialiser })
552    }
553
554    fn statement(input: ParseStream) -> Result<Self> {
555        if input.peek(kw::kw_if) {
556            Stmt::if_statement(input)
557        } else if input.peek(kw::kw_for) {
558            Stmt::for_statement(input)
559        } else if input.peek(kw::print) {
560            Stmt::print_statement(input)
561        } else if input.peek(kw::kw_return) {
562            Stmt::return_statement(input)
563        } else if input.peek(kw::kw_while) {
564            Stmt::while_statement(input)
565        } else if input.peek(Punct!["{"]) {
566            let content;
567            let _: Braces = group!(content in input);
568            Ok(Stmt::Block(block(&content)?))
569        } else {
570            Stmt::expression_statement(input)
571        }
572    }
573
574    fn for_statement(input: ParseStream) -> Result<Self> {
575        let _: kw::kw_for = input.parse()?;
576
577        let content;
578        let _: Parentheses = group!(content in input);
579
580        let initialiser = if content.peek(Punct![";"]) {
581            let _: Punct![";"] = content.parse()?;
582            None
583        } else if content.peek(kw::var) {
584            Some(Stmt::var_declaration(&content)?)
585        } else {
586            Some(Stmt::expression_statement(&content)?)
587        };
588
589        let condition = if content.peek(Punct![";"]) {
590            Expr::Literal(Literal::True(kw::kw_true::new(&content)))
591        } else {
592            content.parse()?
593        };
594        let _: Punct![";"] = content.parse()?;
595
596        let increment = if content.is_empty() {
597            None
598        } else {
599            Some(content.parse()?)
600        };
601
602        let mut body = Stmt::statement(input)?;
603
604        if let Some(increment) = increment {
605            body = Stmt::Block(vec![body, Stmt::Expr(increment)]);
606        }
607
608        body = Stmt::While {
609            condition,
610            body: Box::new(body),
611        };
612
613        if let Some(initialiser) = initialiser {
614            body = Stmt::Block(vec![initialiser, body]);
615        }
616
617        Ok(body)
618    }
619
620    fn if_statement(input: ParseStream) -> Result<Self> {
621        let _: kw::kw_if = input.parse()?;
622        let content;
623        let _: Parentheses = group!(content in input);
624        let condition = content.parse()?;
625
626        let then_branch = Box::new(Stmt::statement(input)?);
627        let else_branch = if input.peek(kw::kw_else) {
628            Some(Box::new(Stmt::statement(input)?))
629        } else {
630            None
631        };
632
633        Ok(Stmt::If {
634            condition,
635            then_branch,
636            else_branch,
637        })
638    }
639
640    fn print_statement(input: ParseStream) -> Result<Self> {
641        let _: kw::print = input.parse()?;
642        let value = input.parse()?;
643        let _: Punct![";"] = input.parse()?;
644        Ok(Self::Print(value))
645    }
646
647    fn return_statement(input: ParseStream) -> Result<Self> {
648        let keyword: kw::kw_return = input.parse()?;
649        let value = if input.peek(Punct![";"]) {
650            None
651        } else {
652            Some(input.parse()?)
653        };
654        let _: Punct![";"] = input.parse()?;
655        Ok(Stmt::Return { keyword, value })
656    }
657
658    fn while_statement(input: ParseStream) -> Result<Self> {
659        let _: kw::kw_while = input.parse()?;
660        let content;
661        let _: Parentheses = group!(content in input);
662        let condition = content.parse()?;
663        let body = Box::new(Stmt::statement(input)?);
664
665        Ok(Stmt::While { condition, body })
666    }
667
668    fn expression_statement(input: ParseStream) -> Result<Self> {
669        let expr = input.parse()?;
670        let _: Punct![";"] = input.parse()?;
671        Ok(Self::Expr(expr))
672    }
673}
674
675impl Parse for Stmt {
676    fn parse(input: ParseStream) -> Result<Self> {
677        Stmt::declaration(input)
678    }
679}
680
681struct Ast(Vec<Stmt>);
682
683impl Ast {
684    #[allow(clippy::wildcard_imports)]
685    fn synchronise(input: ParseStream) {
686        input.synchronise(|input| {
687            use kw::*;
688            input.peek(Punct![";"]) && !input.peek2(Punct!["}"])
689                || peek2_any!(input, class, kw_for, fun, kw_if, print, kw_return, var, kw_while)
690        });
691    }
692}
693
694impl Parse for Ast {
695    fn parse(input: ParseStream) -> Result<Self> {
696        let mut stmts = vec![];
697
698        while !input.is_empty() {
699            match input.parse() {
700                Ok(stmt) => stmts.push(stmt),
701                Err(err) => {
702                    Ast::synchronise(input);
703                    input.add_error(err);
704                }
705            }
706        }
707
708        input.get_error().map_or(Ok(Ast(stmts)), Err)
709    }
Source

pub fn is_empty(&self) -> bool

Returns true if this stream has been exhausted.

Examples found in repository?
examples/lox/main.rs (line 494)
491fn block(input: ParseStream) -> Result<Vec<Stmt>> {
492    let mut statements = vec![];
493
494    while !input.is_empty() {
495        statements.push(Stmt::declaration(input)?);
496    }
497
498    Ok(statements)
499}
500
501impl Stmt {
502    fn declaration(input: ParseStream) -> Result<Self> {
503        if input.peek(kw::class) {
504            Stmt::class_declaration(input)
505        } else if input.peek(kw::fun) {
506            let _: kw::fun = input.parse()?;
507            Ok(Stmt::Function(Function::parse(input)?))
508        } else if input.peek(kw::var) {
509            Stmt::var_declaration(input)
510        } else {
511            Stmt::statement(input)
512        }
513    }
514
515    fn class_declaration(input: ParseStream) -> Result<Self> {
516        let _: kw::class = input.parse()?;
517        let name: Ident = input.parse()?;
518
519        let superclass = if input.peek(Punct!["<"]) {
520            let _: Punct!["<"] = input.parse()?;
521            Some(input.parse()?)
522        } else {
523            None
524        };
525
526        let content;
527        let _: Braces = group!(content in input);
528        let methods = parse_repeated(&content)?;
529
530        Ok(Stmt::Class {
531            name,
532            superclass,
533            superclass_distance: Cell::new(None),
534            methods,
535        })
536    }
537
538    fn var_declaration(input: ParseStream) -> Result<Self> {
539        let _: kw::var = input.parse()?;
540
541        let name = kw::ident(input)?;
542
543        let initialiser = if input.peek(Punct!["="]) {
544            let _: Punct!["="] = input.parse()?;
545            Some(input.parse()?)
546        } else {
547            None
548        };
549
550        let _: Punct![";"] = input.parse()?;
551        Ok(Stmt::Variable { name, initialiser })
552    }
553
554    fn statement(input: ParseStream) -> Result<Self> {
555        if input.peek(kw::kw_if) {
556            Stmt::if_statement(input)
557        } else if input.peek(kw::kw_for) {
558            Stmt::for_statement(input)
559        } else if input.peek(kw::print) {
560            Stmt::print_statement(input)
561        } else if input.peek(kw::kw_return) {
562            Stmt::return_statement(input)
563        } else if input.peek(kw::kw_while) {
564            Stmt::while_statement(input)
565        } else if input.peek(Punct!["{"]) {
566            let content;
567            let _: Braces = group!(content in input);
568            Ok(Stmt::Block(block(&content)?))
569        } else {
570            Stmt::expression_statement(input)
571        }
572    }
573
574    fn for_statement(input: ParseStream) -> Result<Self> {
575        let _: kw::kw_for = input.parse()?;
576
577        let content;
578        let _: Parentheses = group!(content in input);
579
580        let initialiser = if content.peek(Punct![";"]) {
581            let _: Punct![";"] = content.parse()?;
582            None
583        } else if content.peek(kw::var) {
584            Some(Stmt::var_declaration(&content)?)
585        } else {
586            Some(Stmt::expression_statement(&content)?)
587        };
588
589        let condition = if content.peek(Punct![";"]) {
590            Expr::Literal(Literal::True(kw::kw_true::new(&content)))
591        } else {
592            content.parse()?
593        };
594        let _: Punct![";"] = content.parse()?;
595
596        let increment = if content.is_empty() {
597            None
598        } else {
599            Some(content.parse()?)
600        };
601
602        let mut body = Stmt::statement(input)?;
603
604        if let Some(increment) = increment {
605            body = Stmt::Block(vec![body, Stmt::Expr(increment)]);
606        }
607
608        body = Stmt::While {
609            condition,
610            body: Box::new(body),
611        };
612
613        if let Some(initialiser) = initialiser {
614            body = Stmt::Block(vec![initialiser, body]);
615        }
616
617        Ok(body)
618    }
619
620    fn if_statement(input: ParseStream) -> Result<Self> {
621        let _: kw::kw_if = input.parse()?;
622        let content;
623        let _: Parentheses = group!(content in input);
624        let condition = content.parse()?;
625
626        let then_branch = Box::new(Stmt::statement(input)?);
627        let else_branch = if input.peek(kw::kw_else) {
628            Some(Box::new(Stmt::statement(input)?))
629        } else {
630            None
631        };
632
633        Ok(Stmt::If {
634            condition,
635            then_branch,
636            else_branch,
637        })
638    }
639
640    fn print_statement(input: ParseStream) -> Result<Self> {
641        let _: kw::print = input.parse()?;
642        let value = input.parse()?;
643        let _: Punct![";"] = input.parse()?;
644        Ok(Self::Print(value))
645    }
646
647    fn return_statement(input: ParseStream) -> Result<Self> {
648        let keyword: kw::kw_return = input.parse()?;
649        let value = if input.peek(Punct![";"]) {
650            None
651        } else {
652            Some(input.parse()?)
653        };
654        let _: Punct![";"] = input.parse()?;
655        Ok(Stmt::Return { keyword, value })
656    }
657
658    fn while_statement(input: ParseStream) -> Result<Self> {
659        let _: kw::kw_while = input.parse()?;
660        let content;
661        let _: Parentheses = group!(content in input);
662        let condition = content.parse()?;
663        let body = Box::new(Stmt::statement(input)?);
664
665        Ok(Stmt::While { condition, body })
666    }
667
668    fn expression_statement(input: ParseStream) -> Result<Self> {
669        let expr = input.parse()?;
670        let _: Punct![";"] = input.parse()?;
671        Ok(Self::Expr(expr))
672    }
673}
674
675impl Parse for Stmt {
676    fn parse(input: ParseStream) -> Result<Self> {
677        Stmt::declaration(input)
678    }
679}
680
681struct Ast(Vec<Stmt>);
682
683impl Ast {
684    #[allow(clippy::wildcard_imports)]
685    fn synchronise(input: ParseStream) {
686        input.synchronise(|input| {
687            use kw::*;
688            input.peek(Punct![";"]) && !input.peek2(Punct!["}"])
689                || peek2_any!(input, class, kw_for, fun, kw_if, print, kw_return, var, kw_while)
690        });
691    }
692}
693
694impl Parse for Ast {
695    fn parse(input: ParseStream) -> Result<Self> {
696        let mut stmts = vec![];
697
698        while !input.is_empty() {
699            match input.parse() {
700                Ok(stmt) => stmts.push(stmt),
701                Err(err) => {
702                    Ast::synchronise(input);
703                    input.add_error(err);
704                }
705            }
706        }
707
708        input.get_error().map_or(Ok(Ast(stmts)), Err)
709    }
Source

pub fn new_error<T: Into<Span>>( &self, message: String, location: T, code: u16, ) -> Error

Creates a new error at the given location with the given message and code.

Examples found in repository?
examples/lox/main.rs (lines 213-217)
192    fn assignment(input: ParseStream) -> Result<Self> {
193        let expr = Expr::or(input)?;
194
195        if input.peek(Punct!["="]) {
196            let equals: Punct!["="] = input.parse()?;
197            let value = Box::new(Expr::assignment(input)?);
198
199            if let Expr::Variable { name, .. } = expr {
200                return Ok(Expr::Assign {
201                    name,
202                    value,
203                    distance: Cell::new(None),
204                });
205            } else if let Expr::Get { object, name } = expr {
206                return Ok(Expr::Set {
207                    object,
208                    name,
209                    value,
210                });
211            }
212
213            input.add_error(input.new_error(
214                "Invalid assignment target".to_string(),
215                &equals,
216                error_codes::INVALID_ASSIGN,
217            ));
218        }
219
220        Ok(expr)
221    }
222
223    fn or(input: ParseStream) -> Result<Self> {
224        let mut expr = Expr::and(input)?;
225
226        while input.peek(kw::or) {
227            expr = Expr::Logical(Box::new(Logical::Or(
228                expr,
229                input.parse()?,
230                Expr::and(input)?,
231            )));
232        }
233
234        Ok(expr)
235    }
236
237    fn and(input: ParseStream) -> Result<Self> {
238        let mut expr = Expr::equality(input)?;
239
240        while input.peek(kw::and) {
241            expr = Expr::Logical(Box::new(Logical::And(
242                expr,
243                input.parse()?,
244                Expr::equality(input)?,
245            )));
246        }
247
248        Ok(expr)
249    }
250
251    fn equality(input: ParseStream) -> Result<Self> {
252        let mut expr = Expr::comparison(input)?;
253
254        loop {
255            if input.peek(Punct!["=="]) {
256                expr = Expr::binary(Binary::Equal(
257                    expr,
258                    input.parse()?,
259                    Expr::comparison(input)?,
260                ));
261            } else if input.peek(Punct!["!="]) {
262                expr = Expr::binary(Binary::NotEqual(
263                    expr,
264                    input.parse()?,
265                    Expr::comparison(input)?,
266                ));
267            } else {
268                break Ok(expr);
269            }
270        }
271    }
272
273    fn comparison(input: ParseStream) -> Result<Self> {
274        let mut expr = Expr::term(input)?;
275
276        loop {
277            if input.peek(Punct![">"]) {
278                expr = Expr::binary(Binary::Greater(expr, input.parse()?, Expr::term(input)?));
279            } else if input.peek(Punct![">="]) {
280                expr = Expr::binary(Binary::GreaterEqual(
281                    expr,
282                    input.parse()?,
283                    Expr::term(input)?,
284                ));
285            } else if input.peek(Punct!["<"]) {
286                expr = Expr::binary(Binary::Less(expr, input.parse()?, Expr::term(input)?));
287            } else if input.peek(Punct!["<="]) {
288                expr = Expr::binary(Binary::LessEqual(expr, input.parse()?, Expr::term(input)?));
289            } else {
290                break Ok(expr);
291            }
292        }
293    }
294
295    fn term(input: ParseStream) -> Result<Self> {
296        let mut expr = Expr::factor(input)?;
297
298        loop {
299            if input.peek(Punct!["+"]) {
300                expr = Expr::binary(Binary::Add(expr, input.parse()?, Expr::factor(input)?));
301            } else if input.peek(Punct!["-"]) {
302                expr = Expr::binary(Binary::Sub(expr, input.parse()?, Expr::factor(input)?));
303            } else {
304                break Ok(expr);
305            }
306        }
307    }
308
309    fn factor(input: ParseStream) -> Result<Self> {
310        let mut expr = Expr::unary(input)?;
311
312        loop {
313            if input.peek(Punct!["*"]) {
314                expr = Expr::binary(Binary::Mul(expr, input.parse()?, Expr::unary(input)?));
315            } else if input.peek(Punct!["/"]) {
316                expr = Expr::binary(Binary::Div(expr, input.parse()?, Expr::unary(input)?));
317            } else {
318                break Ok(expr);
319            }
320        }
321    }
322
323    fn unary(input: ParseStream) -> Result<Self> {
324        if input.peek(Punct!["-"]) {
325            Ok(Expr::Unary(Box::new(Unary::Neg(
326                input.parse()?,
327                Expr::unary(input)?,
328            ))))
329        } else if input.peek(Punct!["!"]) {
330            Ok(Expr::Unary(Box::new(Unary::Not(
331                input.parse()?,
332                Expr::unary(input)?,
333            ))))
334        } else {
335            Expr::call(input)
336        }
337    }
338
339    fn call(input: ParseStream) -> Result<Self> {
340        let mut expr = Expr::primary(input)?;
341
342        loop {
343            if input.peek(Punct!["("]) {
344                expr = Expr::finish_call(input, expr)?;
345            } else if input.peek(Punct!["."]) {
346                let _: Punct!["."] = input.parse()?;
347                let name: Ident = input.parse()?;
348                expr = Expr::Get {
349                    object: Box::new(expr),
350                    name,
351                };
352            } else {
353                break Ok(expr);
354            }
355        }
356    }
357
358    fn finish_call(input: ParseStream<'_>, callee: Expr) -> Result<Self> {
359        let content;
360        let paren: Parentheses = group!(content in input);
361        let arguments: Punctuated<Expr, Punct![","]> =
362            Punctuated::parse_separated_trailing(&content)?;
363        let arguments: Vec<_> = arguments.into_iter().collect();
364        if arguments.len() >= 255 {
365            input.add_error(input.new_error(
366                "Can't have more than 254 arguments".to_string(),
367                paren.0.clone(),
368                error_codes::TOO_MANY_ARGS,
369            ));
370        }
371        Ok(Expr::Call {
372            callee: Box::new(callee),
373            paren,
374            arguments,
375        })
376    }
377
378    fn primary(input: ParseStream) -> Result<Self> {
379        let lookahead = input.lookahead();
380        if lookahead.peek(kw::kw_false) {
381            Ok(Expr::Literal(Literal::False(input.parse()?)))
382        } else if lookahead.peek(kw::kw_true) {
383            Ok(Expr::Literal(Literal::True(input.parse()?)))
384        } else if lookahead.peek(kw::nil) {
385            Ok(Expr::Literal(Literal::Nil(input.parse()?)))
386        } else if lookahead.peek(LitFloat) {
387            Ok(Expr::Literal(Literal::Float(input.parse()?)))
388        } else if lookahead.peek(LitInt) {
389            Ok(Expr::Literal(Literal::Int(input.parse()?)))
390        } else if lookahead.peek(LitStr) {
391            Ok(Expr::Literal(Literal::String(input.parse()?)))
392        } else if input.peek(kw::kw_super) {
393            Ok(Expr::Super {
394                keyword: input.parse()?,
395                distance: Cell::new(None),
396                dot: input.parse()?,
397                method: kw::ident(input)?,
398            })
399        } else if input.peek(kw::this) {
400            Ok(Expr::This {
401                keyword: input.parse()?,
402                distance: Cell::new(None),
403            })
404        } else if lookahead.peek(Ident) {
405            Ok(Expr::Variable {
406                name: kw::ident(input)?,
407                distance: Cell::new(None),
408            })
409        } else if lookahead.peek(Punct!["("]) {
410            let content;
411            let _: Parentheses = group!(content in input);
412            Ok(Expr::Group(Box::new(content.parse()?)))
413        } else {
414            Err(lookahead.error())
415        }
416    }
417}
418
419impl Parse for Expr {
420    fn parse(input: ParseStream) -> Result<Self> {
421        Expr::assignment(input)
422    }
423}
424
425#[derive(Debug, Clone, PartialEq)]
426struct Function {
427    name: Ident,
428    params: Vec<Ident>,
429    body: Vec<Stmt>,
430}
431
432impl Parse for Function {
433    fn parse(input: ParseStream) -> Result<Self> {
434        let name: Ident = input.parse()?;
435        let mut contents: Group<Parentheses> = input.parse()?;
436        contents.remove_whitespace();
437        let Parentheses(span) = contents.delimiters();
438        let tokens = contents.into_token_stream();
439        let params: Vec<Ident> = if tokens.is_empty() {
440            vec![]
441        } else {
442            let params: Punctuated<Ident, Punct![","]> =
443                Punctuated::parse_separated.parse(tokens)?;
444            params.into_iter().collect()
445        };
446        if params.len() >= 255 {
447            input.add_error(input.new_error(
448                "Can't have more than 254 parameters".to_string(),
449                span,
450                error_codes::TOO_MANY_ARGS,
451            ));
452        }
453        let mut contents: Group<Braces> = input.parse()?;
454        contents.remove_whitespace();
455        let body = block.parse(contents.into_token_stream())?;
456        Ok(Function { name, params, body })
457    }
Source

pub fn add_error(&self, error: Error)

Adds a new error to this buffer’s storage.

Examples found in repository?
examples/lox/main.rs (lines 213-217)
192    fn assignment(input: ParseStream) -> Result<Self> {
193        let expr = Expr::or(input)?;
194
195        if input.peek(Punct!["="]) {
196            let equals: Punct!["="] = input.parse()?;
197            let value = Box::new(Expr::assignment(input)?);
198
199            if let Expr::Variable { name, .. } = expr {
200                return Ok(Expr::Assign {
201                    name,
202                    value,
203                    distance: Cell::new(None),
204                });
205            } else if let Expr::Get { object, name } = expr {
206                return Ok(Expr::Set {
207                    object,
208                    name,
209                    value,
210                });
211            }
212
213            input.add_error(input.new_error(
214                "Invalid assignment target".to_string(),
215                &equals,
216                error_codes::INVALID_ASSIGN,
217            ));
218        }
219
220        Ok(expr)
221    }
222
223    fn or(input: ParseStream) -> Result<Self> {
224        let mut expr = Expr::and(input)?;
225
226        while input.peek(kw::or) {
227            expr = Expr::Logical(Box::new(Logical::Or(
228                expr,
229                input.parse()?,
230                Expr::and(input)?,
231            )));
232        }
233
234        Ok(expr)
235    }
236
237    fn and(input: ParseStream) -> Result<Self> {
238        let mut expr = Expr::equality(input)?;
239
240        while input.peek(kw::and) {
241            expr = Expr::Logical(Box::new(Logical::And(
242                expr,
243                input.parse()?,
244                Expr::equality(input)?,
245            )));
246        }
247
248        Ok(expr)
249    }
250
251    fn equality(input: ParseStream) -> Result<Self> {
252        let mut expr = Expr::comparison(input)?;
253
254        loop {
255            if input.peek(Punct!["=="]) {
256                expr = Expr::binary(Binary::Equal(
257                    expr,
258                    input.parse()?,
259                    Expr::comparison(input)?,
260                ));
261            } else if input.peek(Punct!["!="]) {
262                expr = Expr::binary(Binary::NotEqual(
263                    expr,
264                    input.parse()?,
265                    Expr::comparison(input)?,
266                ));
267            } else {
268                break Ok(expr);
269            }
270        }
271    }
272
273    fn comparison(input: ParseStream) -> Result<Self> {
274        let mut expr = Expr::term(input)?;
275
276        loop {
277            if input.peek(Punct![">"]) {
278                expr = Expr::binary(Binary::Greater(expr, input.parse()?, Expr::term(input)?));
279            } else if input.peek(Punct![">="]) {
280                expr = Expr::binary(Binary::GreaterEqual(
281                    expr,
282                    input.parse()?,
283                    Expr::term(input)?,
284                ));
285            } else if input.peek(Punct!["<"]) {
286                expr = Expr::binary(Binary::Less(expr, input.parse()?, Expr::term(input)?));
287            } else if input.peek(Punct!["<="]) {
288                expr = Expr::binary(Binary::LessEqual(expr, input.parse()?, Expr::term(input)?));
289            } else {
290                break Ok(expr);
291            }
292        }
293    }
294
295    fn term(input: ParseStream) -> Result<Self> {
296        let mut expr = Expr::factor(input)?;
297
298        loop {
299            if input.peek(Punct!["+"]) {
300                expr = Expr::binary(Binary::Add(expr, input.parse()?, Expr::factor(input)?));
301            } else if input.peek(Punct!["-"]) {
302                expr = Expr::binary(Binary::Sub(expr, input.parse()?, Expr::factor(input)?));
303            } else {
304                break Ok(expr);
305            }
306        }
307    }
308
309    fn factor(input: ParseStream) -> Result<Self> {
310        let mut expr = Expr::unary(input)?;
311
312        loop {
313            if input.peek(Punct!["*"]) {
314                expr = Expr::binary(Binary::Mul(expr, input.parse()?, Expr::unary(input)?));
315            } else if input.peek(Punct!["/"]) {
316                expr = Expr::binary(Binary::Div(expr, input.parse()?, Expr::unary(input)?));
317            } else {
318                break Ok(expr);
319            }
320        }
321    }
322
323    fn unary(input: ParseStream) -> Result<Self> {
324        if input.peek(Punct!["-"]) {
325            Ok(Expr::Unary(Box::new(Unary::Neg(
326                input.parse()?,
327                Expr::unary(input)?,
328            ))))
329        } else if input.peek(Punct!["!"]) {
330            Ok(Expr::Unary(Box::new(Unary::Not(
331                input.parse()?,
332                Expr::unary(input)?,
333            ))))
334        } else {
335            Expr::call(input)
336        }
337    }
338
339    fn call(input: ParseStream) -> Result<Self> {
340        let mut expr = Expr::primary(input)?;
341
342        loop {
343            if input.peek(Punct!["("]) {
344                expr = Expr::finish_call(input, expr)?;
345            } else if input.peek(Punct!["."]) {
346                let _: Punct!["."] = input.parse()?;
347                let name: Ident = input.parse()?;
348                expr = Expr::Get {
349                    object: Box::new(expr),
350                    name,
351                };
352            } else {
353                break Ok(expr);
354            }
355        }
356    }
357
358    fn finish_call(input: ParseStream<'_>, callee: Expr) -> Result<Self> {
359        let content;
360        let paren: Parentheses = group!(content in input);
361        let arguments: Punctuated<Expr, Punct![","]> =
362            Punctuated::parse_separated_trailing(&content)?;
363        let arguments: Vec<_> = arguments.into_iter().collect();
364        if arguments.len() >= 255 {
365            input.add_error(input.new_error(
366                "Can't have more than 254 arguments".to_string(),
367                paren.0.clone(),
368                error_codes::TOO_MANY_ARGS,
369            ));
370        }
371        Ok(Expr::Call {
372            callee: Box::new(callee),
373            paren,
374            arguments,
375        })
376    }
377
378    fn primary(input: ParseStream) -> Result<Self> {
379        let lookahead = input.lookahead();
380        if lookahead.peek(kw::kw_false) {
381            Ok(Expr::Literal(Literal::False(input.parse()?)))
382        } else if lookahead.peek(kw::kw_true) {
383            Ok(Expr::Literal(Literal::True(input.parse()?)))
384        } else if lookahead.peek(kw::nil) {
385            Ok(Expr::Literal(Literal::Nil(input.parse()?)))
386        } else if lookahead.peek(LitFloat) {
387            Ok(Expr::Literal(Literal::Float(input.parse()?)))
388        } else if lookahead.peek(LitInt) {
389            Ok(Expr::Literal(Literal::Int(input.parse()?)))
390        } else if lookahead.peek(LitStr) {
391            Ok(Expr::Literal(Literal::String(input.parse()?)))
392        } else if input.peek(kw::kw_super) {
393            Ok(Expr::Super {
394                keyword: input.parse()?,
395                distance: Cell::new(None),
396                dot: input.parse()?,
397                method: kw::ident(input)?,
398            })
399        } else if input.peek(kw::this) {
400            Ok(Expr::This {
401                keyword: input.parse()?,
402                distance: Cell::new(None),
403            })
404        } else if lookahead.peek(Ident) {
405            Ok(Expr::Variable {
406                name: kw::ident(input)?,
407                distance: Cell::new(None),
408            })
409        } else if lookahead.peek(Punct!["("]) {
410            let content;
411            let _: Parentheses = group!(content in input);
412            Ok(Expr::Group(Box::new(content.parse()?)))
413        } else {
414            Err(lookahead.error())
415        }
416    }
417}
418
419impl Parse for Expr {
420    fn parse(input: ParseStream) -> Result<Self> {
421        Expr::assignment(input)
422    }
423}
424
425#[derive(Debug, Clone, PartialEq)]
426struct Function {
427    name: Ident,
428    params: Vec<Ident>,
429    body: Vec<Stmt>,
430}
431
432impl Parse for Function {
433    fn parse(input: ParseStream) -> Result<Self> {
434        let name: Ident = input.parse()?;
435        let mut contents: Group<Parentheses> = input.parse()?;
436        contents.remove_whitespace();
437        let Parentheses(span) = contents.delimiters();
438        let tokens = contents.into_token_stream();
439        let params: Vec<Ident> = if tokens.is_empty() {
440            vec![]
441        } else {
442            let params: Punctuated<Ident, Punct![","]> =
443                Punctuated::parse_separated.parse(tokens)?;
444            params.into_iter().collect()
445        };
446        if params.len() >= 255 {
447            input.add_error(input.new_error(
448                "Can't have more than 254 parameters".to_string(),
449                span,
450                error_codes::TOO_MANY_ARGS,
451            ));
452        }
453        let mut contents: Group<Braces> = input.parse()?;
454        contents.remove_whitespace();
455        let body = block.parse(contents.into_token_stream())?;
456        Ok(Function { name, params, body })
457    }
458}
459
460#[derive(Debug, Clone, PartialEq)]
461enum Stmt {
462    Block(Vec<Stmt>),
463    Class {
464        name: Ident,
465        superclass: Option<Ident>,
466        superclass_distance: Cell<Option<usize>>,
467        methods: Vec<Function>,
468    },
469    Expr(Expr),
470    Function(Function),
471    If {
472        condition: Expr,
473        then_branch: Box<Stmt>,
474        else_branch: Option<Box<Stmt>>,
475    },
476    Print(Expr),
477    Return {
478        keyword: kw::kw_return,
479        value: Option<Expr>,
480    },
481    Variable {
482        name: Ident,
483        initialiser: Option<Expr>,
484    },
485    While {
486        condition: Expr,
487        body: Box<Stmt>,
488    },
489}
490
491fn block(input: ParseStream) -> Result<Vec<Stmt>> {
492    let mut statements = vec![];
493
494    while !input.is_empty() {
495        statements.push(Stmt::declaration(input)?);
496    }
497
498    Ok(statements)
499}
500
501impl Stmt {
502    fn declaration(input: ParseStream) -> Result<Self> {
503        if input.peek(kw::class) {
504            Stmt::class_declaration(input)
505        } else if input.peek(kw::fun) {
506            let _: kw::fun = input.parse()?;
507            Ok(Stmt::Function(Function::parse(input)?))
508        } else if input.peek(kw::var) {
509            Stmt::var_declaration(input)
510        } else {
511            Stmt::statement(input)
512        }
513    }
514
515    fn class_declaration(input: ParseStream) -> Result<Self> {
516        let _: kw::class = input.parse()?;
517        let name: Ident = input.parse()?;
518
519        let superclass = if input.peek(Punct!["<"]) {
520            let _: Punct!["<"] = input.parse()?;
521            Some(input.parse()?)
522        } else {
523            None
524        };
525
526        let content;
527        let _: Braces = group!(content in input);
528        let methods = parse_repeated(&content)?;
529
530        Ok(Stmt::Class {
531            name,
532            superclass,
533            superclass_distance: Cell::new(None),
534            methods,
535        })
536    }
537
538    fn var_declaration(input: ParseStream) -> Result<Self> {
539        let _: kw::var = input.parse()?;
540
541        let name = kw::ident(input)?;
542
543        let initialiser = if input.peek(Punct!["="]) {
544            let _: Punct!["="] = input.parse()?;
545            Some(input.parse()?)
546        } else {
547            None
548        };
549
550        let _: Punct![";"] = input.parse()?;
551        Ok(Stmt::Variable { name, initialiser })
552    }
553
554    fn statement(input: ParseStream) -> Result<Self> {
555        if input.peek(kw::kw_if) {
556            Stmt::if_statement(input)
557        } else if input.peek(kw::kw_for) {
558            Stmt::for_statement(input)
559        } else if input.peek(kw::print) {
560            Stmt::print_statement(input)
561        } else if input.peek(kw::kw_return) {
562            Stmt::return_statement(input)
563        } else if input.peek(kw::kw_while) {
564            Stmt::while_statement(input)
565        } else if input.peek(Punct!["{"]) {
566            let content;
567            let _: Braces = group!(content in input);
568            Ok(Stmt::Block(block(&content)?))
569        } else {
570            Stmt::expression_statement(input)
571        }
572    }
573
574    fn for_statement(input: ParseStream) -> Result<Self> {
575        let _: kw::kw_for = input.parse()?;
576
577        let content;
578        let _: Parentheses = group!(content in input);
579
580        let initialiser = if content.peek(Punct![";"]) {
581            let _: Punct![";"] = content.parse()?;
582            None
583        } else if content.peek(kw::var) {
584            Some(Stmt::var_declaration(&content)?)
585        } else {
586            Some(Stmt::expression_statement(&content)?)
587        };
588
589        let condition = if content.peek(Punct![";"]) {
590            Expr::Literal(Literal::True(kw::kw_true::new(&content)))
591        } else {
592            content.parse()?
593        };
594        let _: Punct![";"] = content.parse()?;
595
596        let increment = if content.is_empty() {
597            None
598        } else {
599            Some(content.parse()?)
600        };
601
602        let mut body = Stmt::statement(input)?;
603
604        if let Some(increment) = increment {
605            body = Stmt::Block(vec![body, Stmt::Expr(increment)]);
606        }
607
608        body = Stmt::While {
609            condition,
610            body: Box::new(body),
611        };
612
613        if let Some(initialiser) = initialiser {
614            body = Stmt::Block(vec![initialiser, body]);
615        }
616
617        Ok(body)
618    }
619
620    fn if_statement(input: ParseStream) -> Result<Self> {
621        let _: kw::kw_if = input.parse()?;
622        let content;
623        let _: Parentheses = group!(content in input);
624        let condition = content.parse()?;
625
626        let then_branch = Box::new(Stmt::statement(input)?);
627        let else_branch = if input.peek(kw::kw_else) {
628            Some(Box::new(Stmt::statement(input)?))
629        } else {
630            None
631        };
632
633        Ok(Stmt::If {
634            condition,
635            then_branch,
636            else_branch,
637        })
638    }
639
640    fn print_statement(input: ParseStream) -> Result<Self> {
641        let _: kw::print = input.parse()?;
642        let value = input.parse()?;
643        let _: Punct![";"] = input.parse()?;
644        Ok(Self::Print(value))
645    }
646
647    fn return_statement(input: ParseStream) -> Result<Self> {
648        let keyword: kw::kw_return = input.parse()?;
649        let value = if input.peek(Punct![";"]) {
650            None
651        } else {
652            Some(input.parse()?)
653        };
654        let _: Punct![";"] = input.parse()?;
655        Ok(Stmt::Return { keyword, value })
656    }
657
658    fn while_statement(input: ParseStream) -> Result<Self> {
659        let _: kw::kw_while = input.parse()?;
660        let content;
661        let _: Parentheses = group!(content in input);
662        let condition = content.parse()?;
663        let body = Box::new(Stmt::statement(input)?);
664
665        Ok(Stmt::While { condition, body })
666    }
667
668    fn expression_statement(input: ParseStream) -> Result<Self> {
669        let expr = input.parse()?;
670        let _: Punct![";"] = input.parse()?;
671        Ok(Self::Expr(expr))
672    }
673}
674
675impl Parse for Stmt {
676    fn parse(input: ParseStream) -> Result<Self> {
677        Stmt::declaration(input)
678    }
679}
680
681struct Ast(Vec<Stmt>);
682
683impl Ast {
684    #[allow(clippy::wildcard_imports)]
685    fn synchronise(input: ParseStream) {
686        input.synchronise(|input| {
687            use kw::*;
688            input.peek(Punct![";"]) && !input.peek2(Punct!["}"])
689                || peek2_any!(input, class, kw_for, fun, kw_if, print, kw_return, var, kw_while)
690        });
691    }
692}
693
694impl Parse for Ast {
695    fn parse(input: ParseStream) -> Result<Self> {
696        let mut stmts = vec![];
697
698        while !input.is_empty() {
699            match input.parse() {
700                Ok(stmt) => stmts.push(stmt),
701                Err(err) => {
702                    Ast::synchronise(input);
703                    input.add_error(err);
704                }
705            }
706        }
707
708        input.get_error().map_or(Ok(Ast(stmts)), Err)
709    }
Source

pub fn get_error(&self) -> Option<Error>

Returns an error consisting of all errors from ParseBuffer::add_error, if it has been called.

Examples found in repository?
examples/lox/main.rs (line 708)
695    fn parse(input: ParseStream) -> Result<Self> {
696        let mut stmts = vec![];
697
698        while !input.is_empty() {
699            match input.parse() {
700                Ok(stmt) => stmts.push(stmt),
701                Err(err) => {
702                    Ast::synchronise(input);
703                    input.add_error(err);
704                }
705            }
706        }
707
708        input.get_error().map_or(Ok(Ast(stmts)), Err)
709    }
Source

pub fn synchronise<F: FnMut(ParseStream<'_>) -> bool>(&self, function: F)

Repeatedly skips tokens until function returns true or self is empty.

Examples found in repository?
examples/lox/main.rs (lines 686-690)
685    fn synchronise(input: ParseStream) {
686        input.synchronise(|input| {
687            use kw::*;
688            input.peek(Punct![";"]) && !input.peek2(Punct!["}"])
689                || peek2_any!(input, class, kw_for, fun, kw_if, print, kw_return, var, kw_while)
690        });
691    }
Source

pub fn parse_joint<T1: Token, T2: Token>(&self) -> Result<(T1, T2)>

Parses T1 and T2, with no whitespace allowed between them.

§Errors

Returns an error if self does not start with the required tokens.

Source

pub fn parse_repeated<T: Parse>(&self) -> Result<Vec<T>>

Attempts to parse self into Vec<T>, with no separating punctuation, fully consuming self.

To parse separated instances of T, see Punctuated.

§Errors

Returns an error if self is not a valid sequence of T.

Source

pub fn peek<T: Peek>(&self, token: T) -> bool

Returns true if the next token is an instance of T.

Examples found in repository?
examples/calc.rs (line 44)
41    fn parse(input: ParseStream) -> Result<Self> {
42        let mut expr = factor(input)?;
43        loop {
44            if input.peek(Punct!["+"]) {
45                expr = Expr::Add(Box::new(expr), input.parse()?, Box::new(factor(input)?));
46            } else if input.peek(Punct!["-"]) {
47                expr = Expr::Sub(Box::new(expr), input.parse()?, Box::new(factor(input)?));
48            } else {
49                break;
50            }
51        }
52        Ok(expr)
53    }
54}
55
56fn factor(input: ParseStream) -> Result<Expr> {
57    let mut expr: Expr = unary(input)?;
58    loop {
59        if input.peek(Punct!["*"]) {
60            expr = Expr::Mul(Box::new(expr), input.parse()?, Box::new(unary(input)?));
61        } else if input.peek(Punct!["/"]) {
62            expr = Expr::Div(Box::new(expr), input.parse()?, Box::new(unary(input)?));
63        } else if input.peek(Punct!["%"]) {
64            expr = Expr::Mod(Box::new(expr), input.parse()?, Box::new(unary(input)?));
65        } else {
66            break;
67        }
68    }
69    Ok(expr)
70}
71
72fn unary(input: ParseStream) -> Result<Expr> {
73    if input.peek(Punct!["-"]) {
74        Ok(Expr::Neg(input.parse()?, Box::new(unary(input)?)))
75    } else {
76        primary(input)
77    }
78}
More examples
Hide additional examples
examples/lox/main.rs (line 195)
192    fn assignment(input: ParseStream) -> Result<Self> {
193        let expr = Expr::or(input)?;
194
195        if input.peek(Punct!["="]) {
196            let equals: Punct!["="] = input.parse()?;
197            let value = Box::new(Expr::assignment(input)?);
198
199            if let Expr::Variable { name, .. } = expr {
200                return Ok(Expr::Assign {
201                    name,
202                    value,
203                    distance: Cell::new(None),
204                });
205            } else if let Expr::Get { object, name } = expr {
206                return Ok(Expr::Set {
207                    object,
208                    name,
209                    value,
210                });
211            }
212
213            input.add_error(input.new_error(
214                "Invalid assignment target".to_string(),
215                &equals,
216                error_codes::INVALID_ASSIGN,
217            ));
218        }
219
220        Ok(expr)
221    }
222
223    fn or(input: ParseStream) -> Result<Self> {
224        let mut expr = Expr::and(input)?;
225
226        while input.peek(kw::or) {
227            expr = Expr::Logical(Box::new(Logical::Or(
228                expr,
229                input.parse()?,
230                Expr::and(input)?,
231            )));
232        }
233
234        Ok(expr)
235    }
236
237    fn and(input: ParseStream) -> Result<Self> {
238        let mut expr = Expr::equality(input)?;
239
240        while input.peek(kw::and) {
241            expr = Expr::Logical(Box::new(Logical::And(
242                expr,
243                input.parse()?,
244                Expr::equality(input)?,
245            )));
246        }
247
248        Ok(expr)
249    }
250
251    fn equality(input: ParseStream) -> Result<Self> {
252        let mut expr = Expr::comparison(input)?;
253
254        loop {
255            if input.peek(Punct!["=="]) {
256                expr = Expr::binary(Binary::Equal(
257                    expr,
258                    input.parse()?,
259                    Expr::comparison(input)?,
260                ));
261            } else if input.peek(Punct!["!="]) {
262                expr = Expr::binary(Binary::NotEqual(
263                    expr,
264                    input.parse()?,
265                    Expr::comparison(input)?,
266                ));
267            } else {
268                break Ok(expr);
269            }
270        }
271    }
272
273    fn comparison(input: ParseStream) -> Result<Self> {
274        let mut expr = Expr::term(input)?;
275
276        loop {
277            if input.peek(Punct![">"]) {
278                expr = Expr::binary(Binary::Greater(expr, input.parse()?, Expr::term(input)?));
279            } else if input.peek(Punct![">="]) {
280                expr = Expr::binary(Binary::GreaterEqual(
281                    expr,
282                    input.parse()?,
283                    Expr::term(input)?,
284                ));
285            } else if input.peek(Punct!["<"]) {
286                expr = Expr::binary(Binary::Less(expr, input.parse()?, Expr::term(input)?));
287            } else if input.peek(Punct!["<="]) {
288                expr = Expr::binary(Binary::LessEqual(expr, input.parse()?, Expr::term(input)?));
289            } else {
290                break Ok(expr);
291            }
292        }
293    }
294
295    fn term(input: ParseStream) -> Result<Self> {
296        let mut expr = Expr::factor(input)?;
297
298        loop {
299            if input.peek(Punct!["+"]) {
300                expr = Expr::binary(Binary::Add(expr, input.parse()?, Expr::factor(input)?));
301            } else if input.peek(Punct!["-"]) {
302                expr = Expr::binary(Binary::Sub(expr, input.parse()?, Expr::factor(input)?));
303            } else {
304                break Ok(expr);
305            }
306        }
307    }
308
309    fn factor(input: ParseStream) -> Result<Self> {
310        let mut expr = Expr::unary(input)?;
311
312        loop {
313            if input.peek(Punct!["*"]) {
314                expr = Expr::binary(Binary::Mul(expr, input.parse()?, Expr::unary(input)?));
315            } else if input.peek(Punct!["/"]) {
316                expr = Expr::binary(Binary::Div(expr, input.parse()?, Expr::unary(input)?));
317            } else {
318                break Ok(expr);
319            }
320        }
321    }
322
323    fn unary(input: ParseStream) -> Result<Self> {
324        if input.peek(Punct!["-"]) {
325            Ok(Expr::Unary(Box::new(Unary::Neg(
326                input.parse()?,
327                Expr::unary(input)?,
328            ))))
329        } else if input.peek(Punct!["!"]) {
330            Ok(Expr::Unary(Box::new(Unary::Not(
331                input.parse()?,
332                Expr::unary(input)?,
333            ))))
334        } else {
335            Expr::call(input)
336        }
337    }
338
339    fn call(input: ParseStream) -> Result<Self> {
340        let mut expr = Expr::primary(input)?;
341
342        loop {
343            if input.peek(Punct!["("]) {
344                expr = Expr::finish_call(input, expr)?;
345            } else if input.peek(Punct!["."]) {
346                let _: Punct!["."] = input.parse()?;
347                let name: Ident = input.parse()?;
348                expr = Expr::Get {
349                    object: Box::new(expr),
350                    name,
351                };
352            } else {
353                break Ok(expr);
354            }
355        }
356    }
357
358    fn finish_call(input: ParseStream<'_>, callee: Expr) -> Result<Self> {
359        let content;
360        let paren: Parentheses = group!(content in input);
361        let arguments: Punctuated<Expr, Punct![","]> =
362            Punctuated::parse_separated_trailing(&content)?;
363        let arguments: Vec<_> = arguments.into_iter().collect();
364        if arguments.len() >= 255 {
365            input.add_error(input.new_error(
366                "Can't have more than 254 arguments".to_string(),
367                paren.0.clone(),
368                error_codes::TOO_MANY_ARGS,
369            ));
370        }
371        Ok(Expr::Call {
372            callee: Box::new(callee),
373            paren,
374            arguments,
375        })
376    }
377
378    fn primary(input: ParseStream) -> Result<Self> {
379        let lookahead = input.lookahead();
380        if lookahead.peek(kw::kw_false) {
381            Ok(Expr::Literal(Literal::False(input.parse()?)))
382        } else if lookahead.peek(kw::kw_true) {
383            Ok(Expr::Literal(Literal::True(input.parse()?)))
384        } else if lookahead.peek(kw::nil) {
385            Ok(Expr::Literal(Literal::Nil(input.parse()?)))
386        } else if lookahead.peek(LitFloat) {
387            Ok(Expr::Literal(Literal::Float(input.parse()?)))
388        } else if lookahead.peek(LitInt) {
389            Ok(Expr::Literal(Literal::Int(input.parse()?)))
390        } else if lookahead.peek(LitStr) {
391            Ok(Expr::Literal(Literal::String(input.parse()?)))
392        } else if input.peek(kw::kw_super) {
393            Ok(Expr::Super {
394                keyword: input.parse()?,
395                distance: Cell::new(None),
396                dot: input.parse()?,
397                method: kw::ident(input)?,
398            })
399        } else if input.peek(kw::this) {
400            Ok(Expr::This {
401                keyword: input.parse()?,
402                distance: Cell::new(None),
403            })
404        } else if lookahead.peek(Ident) {
405            Ok(Expr::Variable {
406                name: kw::ident(input)?,
407                distance: Cell::new(None),
408            })
409        } else if lookahead.peek(Punct!["("]) {
410            let content;
411            let _: Parentheses = group!(content in input);
412            Ok(Expr::Group(Box::new(content.parse()?)))
413        } else {
414            Err(lookahead.error())
415        }
416    }
417}
418
419impl Parse for Expr {
420    fn parse(input: ParseStream) -> Result<Self> {
421        Expr::assignment(input)
422    }
423}
424
425#[derive(Debug, Clone, PartialEq)]
426struct Function {
427    name: Ident,
428    params: Vec<Ident>,
429    body: Vec<Stmt>,
430}
431
432impl Parse for Function {
433    fn parse(input: ParseStream) -> Result<Self> {
434        let name: Ident = input.parse()?;
435        let mut contents: Group<Parentheses> = input.parse()?;
436        contents.remove_whitespace();
437        let Parentheses(span) = contents.delimiters();
438        let tokens = contents.into_token_stream();
439        let params: Vec<Ident> = if tokens.is_empty() {
440            vec![]
441        } else {
442            let params: Punctuated<Ident, Punct![","]> =
443                Punctuated::parse_separated.parse(tokens)?;
444            params.into_iter().collect()
445        };
446        if params.len() >= 255 {
447            input.add_error(input.new_error(
448                "Can't have more than 254 parameters".to_string(),
449                span,
450                error_codes::TOO_MANY_ARGS,
451            ));
452        }
453        let mut contents: Group<Braces> = input.parse()?;
454        contents.remove_whitespace();
455        let body = block.parse(contents.into_token_stream())?;
456        Ok(Function { name, params, body })
457    }
458}
459
460#[derive(Debug, Clone, PartialEq)]
461enum Stmt {
462    Block(Vec<Stmt>),
463    Class {
464        name: Ident,
465        superclass: Option<Ident>,
466        superclass_distance: Cell<Option<usize>>,
467        methods: Vec<Function>,
468    },
469    Expr(Expr),
470    Function(Function),
471    If {
472        condition: Expr,
473        then_branch: Box<Stmt>,
474        else_branch: Option<Box<Stmt>>,
475    },
476    Print(Expr),
477    Return {
478        keyword: kw::kw_return,
479        value: Option<Expr>,
480    },
481    Variable {
482        name: Ident,
483        initialiser: Option<Expr>,
484    },
485    While {
486        condition: Expr,
487        body: Box<Stmt>,
488    },
489}
490
491fn block(input: ParseStream) -> Result<Vec<Stmt>> {
492    let mut statements = vec![];
493
494    while !input.is_empty() {
495        statements.push(Stmt::declaration(input)?);
496    }
497
498    Ok(statements)
499}
500
501impl Stmt {
502    fn declaration(input: ParseStream) -> Result<Self> {
503        if input.peek(kw::class) {
504            Stmt::class_declaration(input)
505        } else if input.peek(kw::fun) {
506            let _: kw::fun = input.parse()?;
507            Ok(Stmt::Function(Function::parse(input)?))
508        } else if input.peek(kw::var) {
509            Stmt::var_declaration(input)
510        } else {
511            Stmt::statement(input)
512        }
513    }
514
515    fn class_declaration(input: ParseStream) -> Result<Self> {
516        let _: kw::class = input.parse()?;
517        let name: Ident = input.parse()?;
518
519        let superclass = if input.peek(Punct!["<"]) {
520            let _: Punct!["<"] = input.parse()?;
521            Some(input.parse()?)
522        } else {
523            None
524        };
525
526        let content;
527        let _: Braces = group!(content in input);
528        let methods = parse_repeated(&content)?;
529
530        Ok(Stmt::Class {
531            name,
532            superclass,
533            superclass_distance: Cell::new(None),
534            methods,
535        })
536    }
537
538    fn var_declaration(input: ParseStream) -> Result<Self> {
539        let _: kw::var = input.parse()?;
540
541        let name = kw::ident(input)?;
542
543        let initialiser = if input.peek(Punct!["="]) {
544            let _: Punct!["="] = input.parse()?;
545            Some(input.parse()?)
546        } else {
547            None
548        };
549
550        let _: Punct![";"] = input.parse()?;
551        Ok(Stmt::Variable { name, initialiser })
552    }
553
554    fn statement(input: ParseStream) -> Result<Self> {
555        if input.peek(kw::kw_if) {
556            Stmt::if_statement(input)
557        } else if input.peek(kw::kw_for) {
558            Stmt::for_statement(input)
559        } else if input.peek(kw::print) {
560            Stmt::print_statement(input)
561        } else if input.peek(kw::kw_return) {
562            Stmt::return_statement(input)
563        } else if input.peek(kw::kw_while) {
564            Stmt::while_statement(input)
565        } else if input.peek(Punct!["{"]) {
566            let content;
567            let _: Braces = group!(content in input);
568            Ok(Stmt::Block(block(&content)?))
569        } else {
570            Stmt::expression_statement(input)
571        }
572    }
573
574    fn for_statement(input: ParseStream) -> Result<Self> {
575        let _: kw::kw_for = input.parse()?;
576
577        let content;
578        let _: Parentheses = group!(content in input);
579
580        let initialiser = if content.peek(Punct![";"]) {
581            let _: Punct![";"] = content.parse()?;
582            None
583        } else if content.peek(kw::var) {
584            Some(Stmt::var_declaration(&content)?)
585        } else {
586            Some(Stmt::expression_statement(&content)?)
587        };
588
589        let condition = if content.peek(Punct![";"]) {
590            Expr::Literal(Literal::True(kw::kw_true::new(&content)))
591        } else {
592            content.parse()?
593        };
594        let _: Punct![";"] = content.parse()?;
595
596        let increment = if content.is_empty() {
597            None
598        } else {
599            Some(content.parse()?)
600        };
601
602        let mut body = Stmt::statement(input)?;
603
604        if let Some(increment) = increment {
605            body = Stmt::Block(vec![body, Stmt::Expr(increment)]);
606        }
607
608        body = Stmt::While {
609            condition,
610            body: Box::new(body),
611        };
612
613        if let Some(initialiser) = initialiser {
614            body = Stmt::Block(vec![initialiser, body]);
615        }
616
617        Ok(body)
618    }
619
620    fn if_statement(input: ParseStream) -> Result<Self> {
621        let _: kw::kw_if = input.parse()?;
622        let content;
623        let _: Parentheses = group!(content in input);
624        let condition = content.parse()?;
625
626        let then_branch = Box::new(Stmt::statement(input)?);
627        let else_branch = if input.peek(kw::kw_else) {
628            Some(Box::new(Stmt::statement(input)?))
629        } else {
630            None
631        };
632
633        Ok(Stmt::If {
634            condition,
635            then_branch,
636            else_branch,
637        })
638    }
639
640    fn print_statement(input: ParseStream) -> Result<Self> {
641        let _: kw::print = input.parse()?;
642        let value = input.parse()?;
643        let _: Punct![";"] = input.parse()?;
644        Ok(Self::Print(value))
645    }
646
647    fn return_statement(input: ParseStream) -> Result<Self> {
648        let keyword: kw::kw_return = input.parse()?;
649        let value = if input.peek(Punct![";"]) {
650            None
651        } else {
652            Some(input.parse()?)
653        };
654        let _: Punct![";"] = input.parse()?;
655        Ok(Stmt::Return { keyword, value })
656    }
657
658    fn while_statement(input: ParseStream) -> Result<Self> {
659        let _: kw::kw_while = input.parse()?;
660        let content;
661        let _: Parentheses = group!(content in input);
662        let condition = content.parse()?;
663        let body = Box::new(Stmt::statement(input)?);
664
665        Ok(Stmt::While { condition, body })
666    }
667
668    fn expression_statement(input: ParseStream) -> Result<Self> {
669        let expr = input.parse()?;
670        let _: Punct![";"] = input.parse()?;
671        Ok(Self::Expr(expr))
672    }
673}
674
675impl Parse for Stmt {
676    fn parse(input: ParseStream) -> Result<Self> {
677        Stmt::declaration(input)
678    }
679}
680
681struct Ast(Vec<Stmt>);
682
683impl Ast {
684    #[allow(clippy::wildcard_imports)]
685    fn synchronise(input: ParseStream) {
686        input.synchronise(|input| {
687            use kw::*;
688            input.peek(Punct![";"]) && !input.peek2(Punct!["}"])
689                || peek2_any!(input, class, kw_for, fun, kw_if, print, kw_return, var, kw_while)
690        });
691    }
Source

pub fn peek2<T: Peek>(&self, token: T) -> bool

Returns true if the next token is an instance of T.

Note that for the purposes of this function, multi-character punctuation like += is considered to be two tokens, and float literals are considered to be three tokens (start, ., end).

Examples found in repository?
examples/lox/main.rs (line 688)
685    fn synchronise(input: ParseStream) {
686        input.synchronise(|input| {
687            use kw::*;
688            input.peek(Punct![";"]) && !input.peek2(Punct!["}"])
689                || peek2_any!(input, class, kw_for, fun, kw_if, print, kw_return, var, kw_while)
690        });
691    }
Source

pub fn current_span(&self) -> Result<Span>

Gets the span of the current token.

§Errors

Returns an error if self is empty.

Source

pub fn fork(&self) -> ParseBuffer<'a>

Creates a new ParseBuffer at the same position as self.

Changes to self will not affect the fork, and vice versa.

Source

pub fn commit(&self, fork: &Self)

Commits a forked buffer into self, updating self to reflect fork.

§Panics

This function will panic if fork wasn’t forked from self or if self is further ahead than fork.

Source

pub fn unexpected_token(&self, expected: HashSet<String>) -> Error

Creates an error with the message Unexpected token and the given expected tokens.

Use of this function is generally discouraged in favour of Lookahead::error.

Source

pub fn lookahead(&self) -> Lookahead<'a>

Creates a helper struct for peeking at the next token.

Examples found in repository?
examples/calc.rs (line 82)
81fn primary(input: ParseStream) -> Result<Expr> {
82    let lookahead = input.lookahead();
83    if lookahead.peek(token::LitFloat) {
84        Ok(Expr::Num(input.parse::<token::LitFloat>()?.value()))
85    } else if lookahead.peek(token::LitInt) {
86        Ok(Expr::Num(input.parse::<token::LitInt>()?.value() as f64))
87    } else if lookahead.peek(token::LeftParen) {
88        let group: Group<Parentheses> = input.parse()?;
89        parse(group.into_token_stream())
90    } else {
91        Err(lookahead.error())
92    }
93}
More examples
Hide additional examples
examples/lox/main.rs (line 379)
378    fn primary(input: ParseStream) -> Result<Self> {
379        let lookahead = input.lookahead();
380        if lookahead.peek(kw::kw_false) {
381            Ok(Expr::Literal(Literal::False(input.parse()?)))
382        } else if lookahead.peek(kw::kw_true) {
383            Ok(Expr::Literal(Literal::True(input.parse()?)))
384        } else if lookahead.peek(kw::nil) {
385            Ok(Expr::Literal(Literal::Nil(input.parse()?)))
386        } else if lookahead.peek(LitFloat) {
387            Ok(Expr::Literal(Literal::Float(input.parse()?)))
388        } else if lookahead.peek(LitInt) {
389            Ok(Expr::Literal(Literal::Int(input.parse()?)))
390        } else if lookahead.peek(LitStr) {
391            Ok(Expr::Literal(Literal::String(input.parse()?)))
392        } else if input.peek(kw::kw_super) {
393            Ok(Expr::Super {
394                keyword: input.parse()?,
395                distance: Cell::new(None),
396                dot: input.parse()?,
397                method: kw::ident(input)?,
398            })
399        } else if input.peek(kw::this) {
400            Ok(Expr::This {
401                keyword: input.parse()?,
402                distance: Cell::new(None),
403            })
404        } else if lookahead.peek(Ident) {
405            Ok(Expr::Variable {
406                name: kw::ident(input)?,
407                distance: Cell::new(None),
408            })
409        } else if lookahead.peek(Punct!["("]) {
410            let content;
411            let _: Parentheses = group!(content in input);
412            Ok(Expr::Group(Box::new(content.parse()?)))
413        } else {
414            Err(lookahead.error())
415        }
416    }
Source

pub fn skip_whitespace(&self)

Skips over all whitespace tokens before the next non-whitespace token.

This method will not skip newlines.

Source

pub fn empty_span(&self) -> Span

Creates a new empty Span with this stream’s source file.

Trait Implementations§

Source§

impl Debug for ParseBuffer<'_>

Source§

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

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

impl<'a> From<&'a TokenStream> for ParseBuffer<'a>

Source§

fn from(value: &'a TokenStream) -> Self

Converts to this type from the input type.
Source§

impl<'a> From<TokenStream> for ParseBuffer<'a>

Source§

fn from(value: TokenStream) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<'a> !Freeze for ParseBuffer<'a>

§

impl<'a> RefUnwindSafe for ParseBuffer<'a>

§

impl<'a> Send for ParseBuffer<'a>

§

impl<'a> Sync for ParseBuffer<'a>

§

impl<'a> Unpin for ParseBuffer<'a>

§

impl<'a> UnwindSafe for ParseBuffer<'a>

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.