summaryrefslogtreecommitdiff
path: root/grammar/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'grammar/src/lib.rs')
-rw-r--r--grammar/src/lib.rs20
1 files changed, 20 insertions, 0 deletions
diff --git a/grammar/src/lib.rs b/grammar/src/lib.rs
index ab0f693..21ce2b4 100644
--- a/grammar/src/lib.rs
+++ b/grammar/src/lib.rs
@@ -25,6 +25,12 @@ use std::{
fmt::Display,
};
+/// The index of the starting non-terminal.
+///
+/// By convention this is the zero-th non-terminal. I define this
+/// constant just for the sake of clarity.
+pub const START_NONTERMINAL: usize = 0;
+
/// The type of a terminal.
///
/// For the time being this is a wrapper around a string, but in the
@@ -478,8 +484,17 @@ impl Grammar {
/// Return true if and only if the terminal can appear as the
/// first terminal in a string expanded from the non-terminal.
+ ///
+ /// # Errors
+ ///
+ /// If `non_terminal` or `terminal` is out of bounds, the function
+ /// returns an error indicating this fact.
#[inline]
pub fn is_first_of(&self, non_terminal: usize, terminal: usize) -> Result<bool, Error> {
+ if terminal >= self.ter_num() {
+ return Err(Error::IndexOutOfBounds(terminal, self.ter_num()));
+ }
+
Ok(self
.firsts
.get(non_terminal)
@@ -488,6 +503,11 @@ impl Grammar {
}
/// Return true if and only if the non-terminal is nullable.
+ ///
+ /// # Error
+ ///
+ /// If `non_terminal` is out of bounds, return the corresponding
+ /// error.
#[inline]
pub fn is_nullable(&self, non_terminal: usize) -> Result<bool, Error> {
Ok(self