Skip to content

Commit 0b981d1

Browse files
committed
Update public functions to return list of errors
1 parent ec6d906 commit 0b981d1

File tree

3 files changed

+39
-32
lines changed

3 files changed

+39
-32
lines changed

src/parsing/mod.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,13 @@ pub fn load(filename: &Path) -> Result<String, LoadingError> {
3535
}
3636
}
3737

38-
/// Parse text into a Technique object, or error out.
39-
pub fn parse<'i>(filename: &'i Path, content: &'i str) -> Result<Document<'i>, ParsingError<'i>> {
40-
let result = parser::parse_via_taking(filename, content);
38+
/// Parse text into a Document object, or return the list of errors
39+
/// encountered.
40+
pub fn parse<'i>(
41+
filename: &'i Path,
42+
content: &'i str,
43+
) -> Result<Document<'i>, Vec<ParsingError<'i>>> {
44+
let result = parser::parse_with_recovery(filename, content);
4145

4246
match result {
4347
Ok(document) => {
@@ -66,9 +70,9 @@ pub fn parse<'i>(filename: &'i Path, content: &'i str) -> Result<Document<'i>, P
6670
}
6771
Ok(document)
6872
}
69-
Err(error) => {
70-
debug!("error: {:?}", error);
71-
Err(error)
73+
Err(errors) => {
74+
debug!("errors: {}", errors.len());
75+
Err(errors)
7276
}
7377
}
7478
}

src/parsing/parser.rs

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,35 @@ use crate::language::*;
44
use crate::regex::*;
55

66
#[derive(Debug, PartialEq, Eq)]
7-
pub struct ParseResult<'i> {
7+
struct ParseResult<'i> {
88
pub document: Document<'i>,
99
pub errors: Vec<ParsingError<'i>>,
1010
}
1111

12-
impl<'i> ParseResult<'i> {
13-
pub fn has_errors(&self) -> bool {
14-
!self
15-
.errors
16-
.is_empty()
17-
}
18-
}
19-
20-
pub fn parse_with_recovery<'i>(path: &'i Path, content: &'i str) -> ParseResult<'i> {
21-
let mut input = Parser::new();
22-
input.filename(path);
23-
input.initialize(content);
24-
25-
input.parse_collecting_errors()
26-
}
27-
28-
pub fn parse_via_taking<'i>(
12+
// This could be adapted to return both the partial document and the errors.
13+
// But for our purposes if the parse fails then there's no point trying to do
14+
// deeper validation or analysis; the input syntax is broken and the user
15+
// needs to fix it. Should a partial parse turn out have meaning then the
16+
// return type of this can change to ParseResult<'i> but for now it is fine
17+
// to use Result.
18+
pub fn parse_with_recovery<'i>(
2919
path: &'i Path,
3020
content: &'i str,
31-
) -> Result<Document<'i>, ParsingError<'i>> {
21+
) -> Result<Document<'i>, Vec<ParsingError<'i>>> {
3222
let mut input = Parser::new();
3323
input.filename(path);
3424
input.initialize(content);
3525

36-
input.parse_from_start()
26+
let result = input.parse_collecting_errors();
27+
28+
if result
29+
.errors
30+
.is_empty()
31+
{
32+
Ok(result.document)
33+
} else {
34+
Err(result.errors)
35+
}
3736
}
3837

3938
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -140,8 +139,12 @@ impl<'i> Parser<'i> {
140139
self.offset += width;
141140
}
142141

143-
fn parse_from_start(&mut self) -> Result<Document<'i>, ParsingError<'i>> {
144-
// Check if header is present by looking for magic line
142+
fn parse_collecting_errors(&mut self) -> ParseResult<'i> {
143+
// Clear any existing errors
144+
self.problems
145+
.clear();
146+
147+
// Parse header, collecting errors instead of propagating
145148
let header = if is_magic_line(self.source) {
146149
Some(self.read_technique_header()?)
147150
} else {

tests/parsing/parser.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ mod verify {
44
use std::vec;
55

66
use technique::language::*;
7-
use technique::parsing::parser::{self, Parser};
7+
use technique::parsing::parser::Parser;
88

99
fn trim(s: &str) -> &str {
1010
s.strip_prefix('\n')
@@ -1089,7 +1089,7 @@ before_leaving :
10891089

10901090
#[test]
10911091
fn section_parsing() {
1092-
let result = technique::parsing::parser::parse_via_taking(
1092+
let result = technique::parsing::parser::parse_with_recovery(
10931093
Path::new(""),
10941094
trim(
10951095
r#"
@@ -1177,7 +1177,7 @@ second_section_second_procedure :
11771177

11781178
#[test]
11791179
fn section_with_procedures_only() {
1180-
let result = technique::parsing::parser::parse_via_taking(
1180+
let result = technique::parsing::parser::parse_with_recovery(
11811181
Path::new(""),
11821182
trim(
11831183
r#"
@@ -1248,7 +1248,7 @@ procedure_four : Concept -> Architecture
12481248

12491249
#[test]
12501250
fn section_with_procedures() {
1251-
let result = parser::parse_via_taking(
1251+
let result = technique::parsing::parser::parse_with_recovery(
12521252
Path::new(""),
12531253
trim(
12541254
r#"

0 commit comments

Comments
 (0)