summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRory Dudley2024-02-28 22:49:37 -0700
committerRory Dudley2024-02-28 22:49:37 -0700
commite03f1cff8886be20f6c765a01c0ebd7d93a9663a (patch)
treefa7976b5b3fc09251a40d1450505d55d17ded4fd
parentb8db4a0cda9eb080c9e89c635be4c9abfc9f88d6 (diff)
downloaddwarvish-e03f1cff8886be20f6c765a01c0ebd7d93a9663a.tar.gz
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.
-rw-r--r--src/recite.rs31
1 files 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<String> = Vec::new(); // Stack for each stanza
let mut word: Vec<char> = 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