rslua/
parser.rs

1use crate::ast::*;
2use crate::tokens::{Token, TokenType, TokenValue};
3use rslua_derive::Traceable;
4use rslua_traits::Error;
5
6#[derive(Traceable, Default)]
7pub struct Parser {
8    tokens: Vec<Token>,
9    current: usize,
10}
11
12#[derive(Debug)]
13pub struct SyntaxError(String);
14
15impl Error for SyntaxError {
16    fn what(&self) -> &str {
17        &self.0
18    }
19}
20
21type ParseResult<T> = Result<T, SyntaxError>;
22
23impl Parser {
24
25    pub fn run(&mut self, tokens: Vec<Token>) -> ParseResult<Block> {
26        self.reset();
27        self.tokens = tokens;
28        self.block()
29    }
30
31    // block -> { stat [';'] }
32    fn block(&mut self) -> ParseResult<Block> {
33        let mut stats: Vec<Stat> = Vec::new();
34        while !self.is_block_end() {
35            let stat = self.stat()?;
36            if let Some(stat) = stat {
37                let should_break = matches!(stat, Stat::RetStat(_));
38                stats.push(stat);
39                if should_break {
40                    break;
41                }
42            }
43        }
44        Ok(Block { stats })
45    }
46
47    fn stat(&mut self) -> ParseResult<Option<Stat>> {
48        let stat = match self.current_token_type() {
49            // stat -> ';' (empty stat)
50            TokenType::Semi | TokenType::SComment | TokenType::MComment => {
51                self.next();
52                return Ok(None);
53            }
54            // stat -> if stat
55            TokenType::If => Stat::IfStat(self.ifstat()?),
56            // stat -> while stat
57            TokenType::While => Stat::WhileStat(self.whilestat()?),
58            // stat -> DO block END
59            TokenType::Do => Stat::DoBlock(self.doblock()?),
60            // stat -> forstat
61            TokenType::For => Stat::ForStat(self.forstat()?),
62            // stat -> repeatstat
63            TokenType::Repeat => Stat::RepeatStat(self.repeatstat()?),
64            // stat -> funcstat
65            TokenType::Function => Stat::FuncStat(self.funcstat()?),
66            // stat -> localstat | localfunc
67            TokenType::Local => {
68                let local = self.next_and_skip_comment();
69                if self.test(TokenType::Function) {
70                    Stat::FuncStat(self.localfunc(local)?)
71                } else {
72                    Stat::LocalStat(self.localstat(local)?)
73                }
74            }
75            // stat -> label
76            TokenType::DbColon => Stat::LabelStat(self.labelstat()?),
77            // stat -> retstat
78            TokenType::Return => Stat::RetStat(self.retstat()?),
79            // stat -> breakstat
80            TokenType::Break => Stat::BreakStat(self.breakstat()?),
81            // stat -> gotostat
82            TokenType::Goto => Stat::GotoStat(self.gotostat()?),
83            // stat -> func | assignment
84            _ => self.exprstat()?,
85        };
86        Ok(Some(stat))
87    }
88
89    fn doblock(&mut self) -> ParseResult<DoBlock> {
90        let line = self.current_line();
91        let do_ = self.next();
92        let block = self.block()?;
93        let end = self.check_match(TokenType::End, TokenType::Do, line)?;
94        Ok(DoBlock { do_, block, end })
95    }
96
97    // ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END
98    fn ifstat(&mut self) -> ParseResult<IfStat> {
99        let line = self.current_line();
100        let mut cond_blocks: Vec<CondBlock> = Vec::new();
101        cond_blocks.push(self.test_then_block()?);
102        while self.current_token_type() == TokenType::ElseIf {
103            cond_blocks.push(self.test_then_block()?);
104        }
105        let mut else_ = None;
106        let mut else_block = None;
107        if let Some(else_token) = self.test_next(TokenType::Else) {
108            else_ = Some(else_token);
109            else_block = Some(self.block()?);
110        }
111        let end = self.check_match(TokenType::End, TokenType::If, line)?;
112        Ok(IfStat {
113            cond_blocks,
114            else_,
115            else_block,
116            end,
117        })
118    }
119
120    //  [IF | ELSEIF] cond THEN block
121    fn test_then_block(&mut self) -> ParseResult<CondBlock> {
122        let if_ = self.next_and_skip_comment();
123        let cond = self.cond()?;
124        let then = self.check_next(TokenType::Then)?;
125        let block = self.block()?;
126        Ok(CondBlock {
127            if_,
128            cond,
129            then,
130            block,
131        })
132    }
133
134    // whilestat -> WHILE cond DO block END
135    fn whilestat(&mut self) -> ParseResult<WhileStat> {
136        let line = self.current_line();
137        let while_ = self.next_and_skip_comment();
138        let cond = self.cond()?;
139        let do_ = self.check_next(TokenType::Do)?;
140        let block = self.block()?;
141        let end = self.check_match(TokenType::End, TokenType::While, line)?;
142        Ok(WhileStat {
143            while_,
144            cond,
145            do_,
146            block,
147            end,
148        })
149    }
150
151    fn cond(&mut self) -> ParseResult<Expr> {
152        self.expr()
153    }
154
155    // forstat -> FOR (fornum | forlist) END
156    fn forstat(&mut self) -> ParseResult<ForStat> {
157        let line = self.current_line();
158        let for_ = self.next_and_skip_comment();
159        let var = self.check_name()?;
160        match self.current_token_type() {
161            TokenType::Assign => self.forenum(line, for_, var),
162            TokenType::Comma | TokenType::In => self.forlist(line, for_, var),
163            _ => self.syntax_error("'=' or 'in' expected"),
164        }
165    }
166
167    // fornum -> NAME = exp1,exp1[,exp1] forbody
168    fn forenum(&mut self, line: usize, for_: Token, var: StringExpr) -> ParseResult<ForStat> {
169        let equal = self.next_and_skip_comment();
170        let init = self.expr()?;
171        let init_commas = self.check_next(TokenType::Comma)?;
172        self.skip_comment();
173        let limit = self.expr()?;
174        let limit_commas = self.test_next(TokenType::Comma);
175        let step = match limit_commas {
176            Some(_) => Some(self.expr()?),
177            None => None,
178        };
179        let do_ = self.check_next(TokenType::Do)?;
180        let body = self.block()?;
181        let end = self.check_match(TokenType::End, TokenType::For, line)?;
182        Ok(ForStat::ForNum(ForNum {
183            for_,
184            var,
185            equal,
186            init,
187            init_comma: init_commas,
188            limit,
189            limit_comma: limit_commas,
190            step,
191            do_,
192            body,
193            end,
194        }))
195    }
196
197    // forlist -> NAME {,NAME} IN explist forbody
198    fn forlist(&mut self, line: usize, for_: Token, var: StringExpr) -> ParseResult<ForStat> {
199        let vars = self.varlist(TokenType::Comma, Some(var))?;
200        let in_ = self.check_next(TokenType::In)?;
201        self.skip_comment();
202        let exprs = self.exprlist()?;
203        let do_ = self.check_next(TokenType::Do)?;
204        let body = self.block()?;
205        let end = self.check_match(TokenType::End, TokenType::For, line)?;
206        Ok(ForStat::ForList(ForList {
207            for_,
208            vars,
209            in_,
210            exprs,
211            do_,
212            body,
213            end,
214        }))
215    }
216
217    fn varlist(
218        &mut self,
219        delimiter: TokenType,
220        first_var: Option<StringExpr>,
221    ) -> ParseResult<VarList> {
222        let mut vars = VarList {
223            vars: Vec::new(),
224            delimiters: Vec::new(),
225        };
226        let var = match first_var {
227            Some(var) => var,
228            None => self.check_name()?,
229        };
230        vars.vars.push(var);
231        while let Some(comma) = self.test_next(delimiter) {
232            vars.delimiters.push(comma);
233            vars.vars.push(self.check_name()?);
234        }
235        Ok(vars)
236    }
237
238    // repeatstat -> REPEAT block UNTIL cond
239    fn repeatstat(&mut self) -> ParseResult<RepeatStat> {
240        let line = self.current_line();
241        let repeat = self.next();
242        let block = self.block()?;
243        let until = self.check_match(TokenType::Until, TokenType::Repeat, line)?;
244        let cond = self.cond()?;
245        Ok(RepeatStat {
246            repeat,
247            block,
248            until,
249            cond,
250        })
251    }
252
253    // funcstat -> FUNCTION funcname body
254    fn funcstat(&mut self) -> ParseResult<FuncStat> {
255        let function = self.next_and_skip_comment();
256        let func_name = self.funcname()?;
257        let body = self.funcbody()?;
258        Ok(FuncStat {
259            function,
260            func_type: FuncType::Global,
261            func_name,
262            body,
263        })
264    }
265
266    // funcname -> NAME {'.' NAME} [':' NAME]
267    fn funcname(&mut self) -> ParseResult<FuncName> {
268        let fields = self.varlist(TokenType::Attr, None)?;
269        let mut method = None;
270        if let Some(colon) = self.test_next(TokenType::Colon) {
271            method = Some((colon, self.check_name()?));
272        }
273        Ok(FuncName { fields, method })
274    }
275
276    // body ->  '(' parlist ')' block END
277    fn funcbody(&mut self) -> ParseResult<FuncBody> {
278        let line = self.current_line();
279        let lp = self.check_next(TokenType::Lp)?;
280        self.skip_comment();
281        let mut params = ParamList {
282            params: Vec::new(),
283            commas: Vec::new(),
284        };
285        loop {
286            if self.test(TokenType::Rp) {
287                break;
288            }
289            match self.current_token_type() {
290                TokenType::Dots => {
291                    params.params.push(Param::VarArg(self.current_token()));
292                    self.next_and_skip_comment();
293                }
294                TokenType::Name => params.params.push(Param::Name(self.check_name()?)),
295                _ => self.syntax_error("<name> or '...' expected")?,
296            };
297            self.skip_comment();
298            if let Some(commas) = self.test_next(TokenType::Comma) {
299                params.commas.push(commas);
300                self.skip_comment();
301            } else {
302                break;
303            }
304        }
305        let rp = self.check_next(TokenType::Rp)?;
306        let block = self.block()?;
307        let end = self.check_match(TokenType::End, TokenType::Function, line)?;
308        Ok(FuncBody {
309            lp,
310            params,
311            rp,
312            block,
313            end,
314        })
315    }
316
317    // funcstat -> local FUNCTION funcname body
318    fn localfunc(&mut self, token: Token) -> ParseResult<FuncStat> {
319        let function = self.current_token();
320        self.next_and_skip_comment();
321        let func_name = self.funcname()?;
322        let body = self.funcbody()?;
323        Ok(FuncStat {
324            func_type: FuncType::Local(token),
325            function,
326            func_name,
327            body,
328        })
329    }
330
331    // stat -> LOCAL NAME {',' NAME} ['=' explist]
332    fn localstat(&mut self, local: Token) -> ParseResult<LocalStat> {
333        let names = self.varlist(TokenType::Comma, None)?;
334        let equal = self.test_next(TokenType::Assign);
335        let exprs = if equal.is_some() {
336            Some(self.exprlist()?)
337        } else {
338            None
339        };
340        Ok(LocalStat {
341            local,
342            names,
343            equal,
344            exprs,
345        })
346    }
347
348    // label -> '::' NAME '::'
349    fn labelstat(&mut self) -> ParseResult<LabelStat> {
350        let ldc = self.next();
351        self.skip_comment();
352        let label = self.check_name()?;
353        let rdc = self.check_next(TokenType::DbColon)?;
354        self.skip_comment();
355        Ok(LabelStat { ldc, label, rdc })
356    }
357
358    // stat -> RETURN [explist] [';']
359    fn retstat(&mut self) -> ParseResult<RetStat> {
360        let return_ = self.next_and_skip_comment();
361        let exprs = if !self.is_block_end() && self.current_token_type() != TokenType::Semi {
362            Some(self.exprlist()?)
363        } else {
364            None
365        };
366        let semi = self.test_next(TokenType::Semi);
367        Ok(RetStat {
368            return_,
369            exprs,
370            semi,
371        })
372    }
373
374    fn breakstat(&mut self) -> ParseResult<BreakStat> {
375        let token = self.next_and_skip_comment();
376        Ok(BreakStat { token })
377    }
378
379    fn gotostat(&mut self) -> ParseResult<GotoStat> {
380        let goto = self.next_and_skip_comment();
381        let label = self.check_name()?;
382        Ok(GotoStat { goto, label })
383    }
384
385    // stat -> func call | assignment
386    fn exprstat(&mut self) -> ParseResult<Stat> {
387        let expr = self.suffixedexpr()?;
388        if self.test(TokenType::Assign) || self.test(TokenType::Comma) {
389            Ok(Stat::AssignStat(self.assignment(expr.to_assignable())?))
390        } else {
391            Ok(Stat::CallStat(CallStat {
392                call: expr.to_assignable(),
393            }))
394        }
395    }
396
397    // assignment -> ',' suffixedexp assignment
398    // assignment -> '=' explist
399    fn assignment(&mut self, first: Assignable) -> ParseResult<AssignStat> {
400        let mut left = AssignableList {
401            assignables: Vec::new(),
402            commas: Vec::new(),
403        };
404        left.assignables.push(first);
405        while let Some(comma) = self.test_next(TokenType::Comma) {
406            left.commas.push(comma);
407            left.assignables.push(self.suffixedexpr()?.to_assignable())
408        }
409        let equal = self.check_next(TokenType::Assign)?;
410        self.skip_comment();
411        let right = self.exprlist()?;
412        Ok(AssignStat { left, equal, right })
413    }
414
415    // exprlist -> expr { ',' expr }
416    fn exprlist(&mut self) -> ParseResult<ExprList> {
417        let mut exprs  = ExprList::default();
418        self.skip_comment();
419        exprs.exprs.push(self.expr()?);
420        while let Some(comma) = self.test_next(TokenType::Comma) {
421            exprs.commas.push(comma);
422            self.skip_comment();
423            exprs.exprs.push(self.expr()?)
424        }
425        self.skip_comment();
426        Ok(exprs)
427    }
428
429    fn expr(&mut self) -> ParseResult<Expr> {
430        self.subexpr(0)
431    }
432
433    fn get_unop(&self) -> UnOp {
434        UnOp::from_token(self.current_token())
435    }
436
437    fn get_binop(&self) -> BinOp {
438        BinOp::from_token(self.current_token())
439    }
440
441    // subexpr -> (simpleexpr | unop subexpr) { binop subexpr }
442    // where 'binop' is any binary operator with a priority higher than 'limit'
443    fn subexpr(&mut self, limit: u8) -> ParseResult<Expr> {
444        let mut left;
445        let unop = self.get_unop();
446        if unop != UnOp::None {
447            self.next_and_skip_comment();
448            let expr = Box::new(self.subexpr(unop.priority())?);
449            left = Expr::UnExpr(UnExpr {
450                op: unop.clone(),
451                expr,
452            });
453        } else {
454            left = self.simpleexpr()?;
455        }
456        let mut binop = self.get_binop();
457        while binop != BinOp::None && binop.priority().left > limit {
458            self.next_and_skip_comment();
459            let right = self.subexpr(binop.priority().right)?;
460            left = Expr::BinExpr(BinExpr {
461                left: Box::new(left),
462                right: Box::new(right),
463                op: binop,
464            });
465            binop = self.get_binop();
466        }
467        Ok(left)
468    }
469
470    // simpleexpr -> FLT | INT | STRING | NIL | TRUE | FALSE | ... | constructor | FUNCTION body | suffixedexp
471    fn simpleexpr(&mut self) -> ParseResult<Expr> {
472        let token = self.current_token();
473        let expr = match token.t {
474            TokenType::Flt => Expr::Float(FloatExpr { token }),
475            TokenType::Int => Expr::Int(IntExpr { token }),
476            TokenType::String => Expr::String(StringExpr { token }),
477            TokenType::Nil => Expr::Nil(token),
478            TokenType::True => Expr::True(token),
479            TokenType::False => Expr::False(token),
480            TokenType::Dots => Expr::VarArg(token),
481            TokenType::Lb => return Ok(Expr::Table(self.table()?)),
482            TokenType::Function => {
483                self.next_and_skip_comment();
484                return Ok(Expr::FuncBody(self.funcbody()?));
485            }
486            _ => return self.suffixedexpr(),
487        };
488        self.next_and_skip_comment();
489        Ok(expr)
490    }
491
492    // suffixedexpr -> primaryexpr { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs }
493    fn suffixedexpr(&mut self) -> ParseResult<Expr> {
494        let primary = self.primaryexpr()?;
495        let mut suffixes: Vec<Suffix> = Vec::new();
496        loop {
497            match self.current_token_type() {
498                TokenType::Attr => {
499                    let attr = self.next_and_skip_comment();
500                    suffixes.push(Suffix::Attr(attr, self.check_name()?));
501                }
502                TokenType::Ls => {
503                    let line = self.current_line();
504                    let ls = self.next_and_skip_comment();
505                    suffixes.push(Suffix::Index(
506                        ls,
507                        self.expr()?,
508                        self.check_match(TokenType::Rs, TokenType::Ls, line)?,
509                    ));
510                }
511                TokenType::Colon => {
512                    let colon = self.next_and_skip_comment();
513                    let name = self.check_name()?;
514                    suffixes.push(Suffix::Method(colon, name));
515                }
516                TokenType::Lp | TokenType::Lb | TokenType::String => {
517                    suffixes.push(Suffix::FuncArgs(self.funcargs()?));
518                }
519                _ => break,
520            }
521        }
522
523        if suffixes.is_empty() {
524            Ok(primary)
525        } else {
526            Ok(Expr::SuffixedExpr(SuffixedExpr {
527                primary: Box::new(primary),
528                suffixes,
529            }))
530        }
531    }
532
533    // primaryexp -> NAME | '(' expr ')'
534    fn primaryexpr(&mut self) -> ParseResult<Expr> {
535        let expr = match self.current_token_type() {
536            TokenType::Name => Expr::Name(self.check_name()?),
537            TokenType::Lp => {
538                let line = self.current_line();
539                self.next_and_skip_comment();
540                let expr = self.expr()?;
541                self.check_match(TokenType::Rp, TokenType::Lp, line)?;
542                Expr::ParenExpr(Box::new(expr))
543            }
544            _ => {
545                return self.syntax_error(&format!(
546                    "unexpected symbol '{:?}'",
547                    self.current_token_type()
548                ))
549            }
550        };
551        Ok(expr)
552    }
553
554    // table constructor -> '{' [ field { sep field } [sep] ] '}'
555    // sep -> ',' | ';'
556    fn table(&mut self) -> ParseResult<Table> {
557        let line = self.current_line();
558        let lb = self.check_next(TokenType::Lb)?;
559        self.skip_comment();
560        let mut fields: Vec<Field> = Vec::new();
561        while !self.test(TokenType::Rb) {
562            fields.push(self.field()?);
563        }
564        let rb = self.check_match(TokenType::Rb, TokenType::Lb, line)?;
565        Ok(Table { lb, fields, rb })
566    }
567
568    // field -> listfield | recfield
569    fn field(&mut self) -> ParseResult<Field> {
570        let field = match self.current_token_type() {
571            TokenType::Name => {
572                if self.next_token_type() == TokenType::Assign {
573                    self.recfield()?
574                } else {
575                    self.listfield()?
576                }
577            }
578            TokenType::Ls => self.recfield()?,
579            _ => self.listfield()?,
580        };
581        self.skip_comment();
582        Ok(field)
583    }
584
585    // recfield -> (NAME | '['exp1']') = exp1 ','
586    fn recfield(&mut self) -> ParseResult<Field> {
587        let key = match self.current_token_type() {
588            TokenType::Name => FieldKey::Name(self.check_name()?),
589            TokenType::Ls => {
590                let line = self.current_line();
591                let ls = self.next_and_skip_comment();
592                let expr = self.expr()?;
593                let rs = self.check_match(TokenType::Rs, TokenType::Ls, line)?;
594                FieldKey::Expr(ls, expr, rs)
595            }
596            _ => unreachable!(),
597        };
598        let equal = self.check_next(TokenType::Assign)?;
599        self.skip_comment();
600        let value = self.expr()?;
601        self.skip_comment();
602        let sep = self
603            .test_next(TokenType::Comma)
604            .or_else(|| self.test_next(TokenType::Semi));
605        Ok(Field::RecField(RecField {
606            key,
607            equal,
608            value,
609            sep,
610        }))
611    }
612
613    // listfield -> expr
614    fn listfield(&mut self) -> ParseResult<Field> {
615        let expr = self.expr()?;
616        let sep = self
617            .test_next(TokenType::Comma)
618            .or_else(|| self.test_next(TokenType::Semi));
619        Ok(Field::ListField(ListField { value: expr, sep }))
620    }
621
622    // funcargs -> '(' [ explist ] ') | table constructor | STRING
623    fn funcargs(&mut self) -> ParseResult<FuncArgs> {
624        let func_args = match self.current_token_type() {
625            TokenType::Lp => {
626                let line = self.current_line();
627                let lp = self.next_and_skip_comment();
628
629                // empty arg list
630                if let Some(rp) = self.test_next(TokenType::Rp) {
631                    return Ok(FuncArgs::Exprs(lp, ExprList::default(), rp));
632                }
633
634                let exprs = self.exprlist()?;
635                let rp = self.check_match(TokenType::Rp, TokenType::Lp, line)?;
636                FuncArgs::Exprs(lp, exprs, rp)
637            }
638            TokenType::Lb => FuncArgs::Table(self.table()?),
639            TokenType::String => FuncArgs::String(StringExpr {
640                token: self.next_and_skip_comment(),
641            }),
642            _ => return self.syntax_error("function arguments expected"),
643        };
644        Ok(func_args)
645    }
646
647    fn reset(&mut self) {
648        self.current = 0;
649    }
650
651    fn current_token(&self) -> Token {
652        self.tokens[self.current].clone()
653    }
654
655    fn next_token(&self) -> &Token {
656        let mut current = self.current + 1;
657        while self.tokens[current].is_comment() {
658            current += 1;
659        }
660        &self.tokens[current]
661    }
662
663    fn current_token_type(&self) -> TokenType {
664        let token = self.current_token();
665        token.t
666    }
667
668    fn current_line(&self) -> usize {
669        let token = self.current_token();
670        token.source.line
671    }
672
673    fn next_token_type(&self) -> TokenType {
674        let token = self.next_token();
675        token.t
676    }
677
678    fn next_and_skip_comment(&mut self) -> Token {
679        let token = self.current_token();
680        self.current += 1;
681        self.skip_comment();
682        token
683    }
684
685    fn next(&mut self) -> Token {
686        let token = self.current_token();
687        self.current += 1;
688        token
689    }
690
691    fn skip_comment(&mut self) -> usize {
692        let old = self.current;
693        while self.current_token().is_comment() {
694            self.current += 1;
695        }
696        old
697    }
698
699    // if reach a block end
700    fn is_block_end(&self) -> bool {
701        let token = self.current_token();
702        matches!(token.t, TokenType::Else
703            | TokenType::ElseIf
704            | TokenType::End
705            | TokenType::Until
706            | TokenType::Eos)
707    }
708
709    fn check_match(&mut self, end: TokenType, start: TokenType, line: usize) -> ParseResult<Token> {
710        self.skip_comment();
711        if self.current_token_type() != end {
712            if line == self.current_line() {
713                self.error_expected(end)?;
714            } else {
715                self.syntax_error(&format!(
716                    "{:?} expected (to close {:?} at line {})",
717                    end, start, line
718                ))?;
719            }
720        }
721        Ok(self.next())
722    }
723
724    fn test(&self, expected: TokenType) -> bool {
725        self.current_token_type() == expected
726    }
727
728    fn test_next(&mut self, expected: TokenType) -> Option<Token> {
729        let origin = self.skip_comment();
730        if self.test(expected) {
731            Some(self.next())
732        } else {
733            self.current = origin;
734            None
735        }
736    }
737
738    fn check(&self, expected: TokenType) -> ParseResult<Token> {
739        if self.current_token_type() != expected {
740            self.error_expected(expected)
741        } else {
742            Ok(self.current_token())
743        }
744    }
745
746    fn check_next(&mut self, expected: TokenType) -> ParseResult<Token> {
747        self.skip_comment();
748        self.check(expected)?;
749        Ok(self.next())
750    }
751
752    fn check_name(&mut self) -> ParseResult<StringExpr> {
753        self.skip_comment();
754        self.check(TokenType::Name)?;
755        Ok(StringExpr { token: self.next() })
756    }
757
758    fn syntax_error<T>(&self, msg: &str) -> ParseResult<T> {
759        let token = self.current_token();
760        let ident = match token.value {
761            TokenValue::None => format!("{:?}", token.t),
762            _ => format!("{:?}", token.value),
763        };
764        let error_msg = format!(
765            "[syntax error] {} at line [{}:{}] near [{}]",
766            msg, token.source.line, token.source.col, ident
767        );
768        Parser::trace_error(SyntaxError(error_msg))
769    }
770
771    fn error_expected<T>(&self, expected: TokenType) -> ParseResult<T> {
772        self.syntax_error(&format!("{:?} expected", expected))
773    }
774}