error_recovery/
error_recovery.rs1use sipha_core::{span::Span, token::Token as TokenStruct, traits::TokenKind};
10use sipha_parse::{helpers, parser::Parser, state::ParserState};
11use sipha_tree::{NodeArena, RawNodeId};
12
13#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
14enum Token {
15 Ident,
16 Plus,
17 Semicolon,
18 Invalid,
19}
20
21impl TokenKind for Token {
22 fn is_trivia(&self) -> bool {
23 false
24 }
25}
26
27#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
28enum Rule {
29 Statement,
30}
31
32fn main() {
33 let mut parser = Parser::create();
34
35 parser.register_rule(
37 Rule::Statement,
38 helpers::seq(vec![
39 helpers::token(Token::Ident),
40 helpers::token(Token::Plus),
41 helpers::token(Token::Ident),
42 helpers::token(Token::Semicolon),
43 ]),
44 );
45
46 parser.set_sync_tokens(vec![Token::Semicolon]);
48
49 let tokens = vec![
52 TokenStruct::create(Token::Ident, Span::new(0..1), "a", Vec::new(), Vec::new()),
53 TokenStruct::create(Token::Plus, Span::new(2..3), "+", Vec::new(), Vec::new()),
54 TokenStruct::create(
55 Token::Invalid,
56 Span::new(4..10),
57 "invalid",
58 Vec::new(),
59 Vec::new(),
60 ),
61 TokenStruct::create(
62 Token::Semicolon,
63 Span::new(11..12),
64 ";",
65 Vec::new(),
66 Vec::new(),
67 ),
68 TokenStruct::create(Token::Ident, Span::new(13..14), "b", Vec::new(), Vec::new()),
69 TokenStruct::create(Token::Plus, Span::new(15..16), "+", Vec::new(), Vec::new()),
70 TokenStruct::create(Token::Ident, Span::new(17..18), "c", Vec::new(), Vec::new()),
71 TokenStruct::create(
72 Token::Semicolon,
73 Span::new(19..20),
74 ";",
75 Vec::new(),
76 Vec::new(),
77 ),
78 ];
79
80 let mut arena: NodeArena<Token, Rule, RawNodeId> = NodeArena::new();
81 let mut state = ParserState::new(&tokens, &mut arena, false, ());
82
83 println!("Parsing with error recovery enabled...");
84 println!("Input: a + invalid ; b + c ;");
85 println!();
86
87 match parser.parse_rule(Rule::Statement, &mut state) {
89 Ok(_) => {
90 println!("✓ Parsed successfully (with recovery)!");
91 }
92 Err(e) => {
93 println!("✗ Parse error: {:?}", e);
94 println!("Note: Error recovery attempted to sync at semicolon");
95 }
96 }
97}