lwb_parser/parser/peg/
parser_core_file.rs1use crate::parser::peg::parse_error::{Expect, PEGParseError};
2use crate::parser::peg::parse_result::ParseResult;
3use crate::parser::peg::parser_core::{ParserContext, ParserState};
4use crate::parser::peg::parser_core_ast::{CoreAst, ParsePairRaw};
5use crate::parser::peg::parser_core_expression::{
6 parse_expression_name, skip_single_layout, ExpressionContext,
7};
8use crate::sources::source_file::{SourceFile, SourceFileIterator};
9use crate::sources::span::Span;
10use std::collections::{HashMap, VecDeque};
11
12#[allow(clippy::unnecessary_unwrap)] pub fn parse_file<'src>(
17 ast: &'src CoreAst<'src>,
18 file: &'src SourceFile,
19) -> (ParsePairRaw, Vec<PEGParseError>) {
20 let mut state = ParserContext {
22 file,
23 ast,
24 errors: HashMap::new(),
25 };
26
27 let mut errors = vec![];
29
30 let mut last_err_pos: Option<usize> = None;
31 let mut last_err_offset = 0usize;
32 loop {
33 let (res, err) = parse_file_sub(&state, state.ast.starting_sort, file.iter());
34 if !res.ok {
35 let err = err.expect("Not ok means an error happened.");
36
37 if last_err_pos.is_none()
39 || last_err_pos.unwrap() + last_err_offset < res.pos_err.position()
40 {
41 errors.push(err);
42 last_err_pos = Some(res.pos_err.position());
43 last_err_offset = 0;
44 state.errors.insert(last_err_pos.unwrap(), last_err_offset);
45
46 continue;
47 } else {
48 let len_left = res.pos_err.clone().count();
50 if last_err_offset >= len_left {
51 return (res.result, errors);
52 }
53
54 last_err_offset += 1;
56 state.errors.insert(last_err_pos.unwrap(), last_err_offset);
57 }
58 } else {
59 return (res.result, errors);
60 }
61 }
62}
63
64pub fn parse_file_sub<'src>(
65 state: &ParserContext<'src>,
66 sort: &'src str,
67 pos: SourceFileIterator<'src>,
68) -> (ParseResult<'src, ParsePairRaw>, Option<PEGParseError>) {
69 let mut cache = ParserState {
70 cache: HashMap::new(),
71 cache_stack: VecDeque::new(),
72 best_error: None,
73 no_layout_nest_count: 0usize,
74 no_errors_nest_count: 0usize,
75 allow_layout: true,
76 };
77
78 let mut res = parse_expression_name(state, &mut cache, sort, pos);
79 if !res.ok {
80 return (res, Some(cache.best_error.unwrap()));
81 }
82
83 loop {
85 let (ok, after_layout_pos) = skip_single_layout(
86 state,
87 &mut cache,
88 res.pos.clone(),
89 &ExpressionContext::empty(),
90 );
91 if !ok {
92 break;
93 };
94 res.pos = after_layout_pos;
95 }
96
97 if res.pos.peek().is_none() {
98 (res, None)
99 } else {
100 res.ok = false;
104 match cache.best_error {
105 Some(err) => (res, Some(err)),
106 None => {
107 let curpos = res.pos.position();
108 while res.pos.next().is_some() {}
109 let endpos = res.pos.position();
110 (
111 res,
112 Some(PEGParseError::expect(
113 Span::from_end(state.file, curpos, endpos),
114 Expect::NotEntireInput(),
115 &ExpressionContext::empty(),
116 )),
117 )
118 }
119 }
120 }
121}