Skip to content

Commit 86e5061

Browse files
committed
parser: refactors
1 parent 4c3b211 commit 86e5061

File tree

3 files changed

+25
-29
lines changed

3 files changed

+25
-29
lines changed

src/backend/errors/backend_error.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ impl BackendError {
4444
kind: BackendErrorKind::FixupFailed,
4545
}
4646
}
47-
pub fn parse3_invalid_string_name(line: usize) -> Self {
47+
pub fn invalid_string_name(line: usize) -> Self {
4848
BackendError {
4949
main_location: ErrorLocation::LineOnly(line),
5050
relevant_lines: line..=line,
5151
kind: BackendErrorKind::InvalidStringName,
5252
}
5353
}
54-
pub fn parse3_invalid_character(line: u32, char: u32, c: char) -> Self {
54+
pub fn invalid_character(line: u32, char: u32, c: Option<char>) -> Self {
5555
BackendError {
5656
main_location: ErrorLocation::LineAndChar(line, char),
5757
kind: BackendErrorKind::Parse3InvalidCharacter(c),

src/backend/errors/backend_error_kind.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ pub enum BackendErrorKind {
33
IOError(std::io::Error),
44
FmtError(std::fmt::Error),
55
EmptyScore,
6-
// maybe this shouldn't be an error?
76
NoClosingBarline,
8-
Parse3InvalidCharacter(char),
7+
Parse3InvalidCharacter(Option<char>),
98
FixupFailed,
109
InvalidStringName,
1110
BendOnInvalid,
@@ -28,10 +27,13 @@ impl BackendErrorKind {
2827

2928
BackendErrorKind::NoClosingBarline => (
3029
"No closing barline".into(),
31-
"Lines in a part must end with a barline, but this one doesn't".into(),
30+
"Lines in a part must end with a barline, but this one doesn't.".into(),
3231
),
3332
BackendErrorKind::Parse3InvalidCharacter(c) => {
34-
("Invalid character".into(), format!("The character {c} is not valid here."))
33+
("Invalid character".into(), match c {
34+
Some(c) => format!("The character {c} is not valid here."),
35+
None => format!("This character is not valid here."),
36+
})
3537
}
3638
BackendErrorKind::FixupFailed => (
3739
"Fixup failed".into(),

src/parser/parser.rs

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ use std::ops::RangeInclusive;
1010

1111
pub fn line_is_valid(line: &str) -> bool {
1212
let line = line.trim();
13-
let first_is_alphanumeric = line.chars().next().map(|x| x.is_alphanumeric()).unwrap_or(false);
14-
let second_is_measure_sep = line.as_bytes().get(1).map(|x| *x == b'|').unwrap_or(false);
13+
let mut chars = line.chars();
14+
let first_is_alphanumeric = chars.next().map(|x| x.is_alphanumeric()).unwrap_or(false);
15+
let second_is_measure_sep = chars.next().map(|x| x == '|').unwrap_or(false);
1516
let last_is_measure_end = line.ends_with('|');
1617
let ret = first_is_alphanumeric && second_is_measure_sep && last_is_measure_end;
1718
traceln!("line_is_valid({line}) -> {ret}");
@@ -76,19 +77,17 @@ impl ParseResult {
7677
pub fn parse(lines: &[String]) -> ParseResult {
7778
let mut r = ParseResult::new();
7879
let mut part_first_line = 0;
79-
while part_first_line + 5 < lines.len() {
80+
'outer: loop {
8081
// find a part
81-
while part_first_line + 5 < lines.len() {
82+
loop {
83+
if part_first_line + 5 >= lines.len() {
84+
break 'outer;
85+
}
8286
if line_is_valid(&lines[part_first_line]) && line_is_valid(&lines[part_first_line + 5])
8387
{
8488
break;
8589
}
86-
part_first_line += 1;
87-
}
88-
// hack: the loop above will fail if there is extra content after the last part, so we just exit out here
89-
if part_first_line + 5 >= lines.len() {
90-
traceln!("extra content after last part, shutdown");
91-
break;
90+
part_first_line += 1
9291
}
9392
traceln!("parse3: Found part {part_first_line}..={}", part_first_line + 5);
9493
r.offsets.push((part_first_line as u32, r.tick_stream.len() as u32));
@@ -102,14 +101,12 @@ pub fn parse(lines: &[String]) -> ParseResult {
102101
// parse prelude and last char
103102
for (line_idx, line) in part.iter_mut().enumerate() {
104103
let Ok((rem, string_name)) = string_name()(line) else {
105-
r.error =
106-
Some(BackendError::parse3_invalid_string_name(part_first_line + line_idx));
104+
r.error = Some(BackendError::invalid_string_name(part_first_line + line_idx));
107105
return r;
108106
};
109107
r.base_notes.push(string_name);
110108
let Ok((rem, _)) = super::char('|')(rem) else {
111-
r.error =
112-
Some(BackendError::parse3_invalid_string_name(part_first_line + line_idx));
109+
r.error = Some(BackendError::invalid_string_name(part_first_line + line_idx));
113110
return r;
114111
};
115112
*line = rem;
@@ -147,9 +144,8 @@ pub fn parse(lines: &[String]) -> ParseResult {
147144
if let Some(TabElementError::FretTooLarge) = err {
148145
r.error = Some(BackendError::large_fret(line, char));
149146
} else {
150-
let invalid_src = part[s].chars().next().unwrap_or('\0'); // TODO: do not use null byte here
151-
let err =
152-
BackendError::parse3_invalid_character(line, char, invalid_src);
147+
let invalid_src = part[s].chars().next();
148+
let err = BackendError::invalid_character(line, char, invalid_src);
153149
r.error = Some(err);
154150
}
155151
return r;
@@ -176,7 +172,8 @@ pub fn parse(lines: &[String]) -> ParseResult {
176172
if let TabElement::Rest = elem {
177173
traceln!(depth = 2, "this is a rest so we try to parse the next element");
178174
let len_before = part[s].len();
179-
let next = tab_element3(part[s]).unwrap();
175+
let next = tab_element3(part[s]).unwrap(); // TODO: the unwrap here is ICE,
176+
// should error instead
180177
if len_before - next.0.len() > 1 {
181178
let (m_line, m_char) = source_location_from_stream(&r, elem_idx as u32);
182179
// just for a nicer error, show another multi line too
@@ -186,14 +183,10 @@ pub fn parse(lines: &[String]) -> ParseResult {
186183
Some(BackendError::both_slots_multichar(m_line, m_char, other));
187184
return r;
188185
}
186+
traceln!(depth = 1, "replaced this Rest with {:?}", next.1);
189187
let len = r.tick_stream.len(); // to make the borrow checker happy about borrowing &mut and &
190188
r.tick_stream[len - (6 - s)] = next.1;
191189
part[s] = next.0;
192-
traceln!(
193-
depth = 1,
194-
"replaced this Rest with {:?}",
195-
r.tick_stream[r.tick_stream.len() - (6 - s)]
196-
);
197190
} else {
198191
traceln!(depth = 2, "this is not a Rest, so we check the next element");
199192
if part[s].starts_with("-") {
@@ -224,6 +217,7 @@ pub fn parse(lines: &[String]) -> ParseResult {
224217
r
225218
}
226219

220+
/// A specialized, faster [source_location_from_stream]
227221
pub fn source_location_while_parsing(
228222
r: &ParseResult, part_first_line: u32, line_in_part: u32,
229223
) -> (u32, u32) {

0 commit comments

Comments
 (0)