From e03f1cff8886be20f6c765a01c0ebd7d93a9663a Mon Sep 17 00:00:00 2001 From: Rory Dudley Date: Wed, 28 Feb 2024 22:49:37 -0700 Subject: Parser comments and error checking Added an index to keep track of what position each char is at in the loop. Added a more verbose error message, which prints out the column that the parse error was detected, as well as the glyph that threw the error. Added more comments to the '&', whitespace, and char match statements. Changed parser behavior, so that a ';' glyph without a stanza does not cause a parser error. --- src/recite.rs | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/recite.rs b/src/recite.rs index 074f723..c8364e5 100644 --- a/src/recite.rs +++ b/src/recite.rs @@ -444,6 +444,7 @@ impl Poem { let mut stanza: Vec = Vec::new(); // Stack for each stanza let mut word: Vec = Vec::new(); // Stack for each word let mut prev: Option<&Verse> = None; // The previous verse + let mut i: usize = 0; // Keep track of our index into chars // Parse from left to right loop { @@ -455,12 +456,15 @@ impl Poem { // Print an error, and return None if a Meter was used without // a Stanza before it Some(meter) - if (meter == '|' || meter == '&' || meter == ';') + if ((meter == '|' || meter == '&') && Verse::cadence(prev) - && stanza.is_empty() => + && stanza.is_empty()) + || ((meter == '|' || meter == '&') && i == 0) => { - // TODO: Add more verbose error message - println!("dwvsh: parse error"); + eprintln!( + "dwvsh: parse error: verse must have a stanza: rune {} at column {}", + meter, i + ); return None; } @@ -549,18 +553,23 @@ impl Poem { } // A meter indicates the end of a verse - verses.push(Verse::new( - Stanza::new(stanza.clone()), - Meter::String, - Verse::couplet(prev), - )); + if !stanza.is_empty() { + verses.push(Verse::new( + Stanza::new(stanza.clone()), + Meter::String, + Verse::couplet(prev), + )); + } + // Clear the stacks stanza.clear(); word.clear(); } // The character is whitespace Some(char) if char == ' ' || char == '\t' => { + // If there are chars on the word stack, push that word + // onto the stanza if !word.is_empty() { stanza.push(word.iter().collect()); word.clear(); @@ -569,6 +578,7 @@ impl Poem { // The character is any other utf8 glyph Some(char) => { + // Add the character onto the current word stack word.push(char); } @@ -600,6 +610,9 @@ impl Poem { Some(verse) => Some(verse), None => None, }; + + // Increment the index + i += 1; } // Return the (parsed) poem -- cgit v1.2.3