custom grammar errors, better handling of user facing errors
fuckery for modules in grammar, maybe fixable?
This commit is contained in:
25
grammar/src/custom_error.rs
Normal file
25
grammar/src/custom_error.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
pub enum UserErrorTypes {
|
||||
NumberTooBigUsize,
|
||||
NumberTooBigi64,
|
||||
}
|
||||
|
||||
impl Display for UserErrorTypes {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::NumberTooBigUsize =>
|
||||
write!(f, "Specified number is too big (greater than {})",
|
||||
usize::MAX),
|
||||
Self::NumberTooBigi64 =>
|
||||
write!(f, "Specified number is too big (lesser than {} or \
|
||||
greater than {})",
|
||||
i64::MIN, i64::MAX),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UserError {
|
||||
pub token: (usize, String, usize),
|
||||
pub error: UserErrorTypes,
|
||||
}
|
||||
@ -8,9 +8,14 @@ use rsprocess::element::IdType;
|
||||
use rsprocess::translator::Translator;
|
||||
use execution::presets;
|
||||
use rsprocess::graph;
|
||||
use crate::custom_error;
|
||||
|
||||
grammar(translator: &mut Translator);
|
||||
|
||||
extern {
|
||||
type Error = custom_error::UserError;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -31,7 +36,7 @@ match {
|
||||
"Print", "Save",
|
||||
"Dot", "GraphML", "Serialize",
|
||||
"Stats", "Target", "Run", "Loop", "Frequency", "LimitFrequency",
|
||||
"FastFrequency", "Digraph", "Bisimilarity",
|
||||
"FastFrequency", "Digraph", "Bisimilarity", "Limit",
|
||||
"Deserialize",
|
||||
"?",
|
||||
"Hide",
|
||||
@ -160,10 +165,38 @@ LiteralProcess: String = {
|
||||
"relabel" => <>.into(),
|
||||
};
|
||||
|
||||
// all numbers are i64
|
||||
Num: i64 = {
|
||||
NUMBER =>? i64::from_str(<>)
|
||||
.map_err(|_| ParseError::User { error: "Number is too big" })
|
||||
<sign: "-"?> <start: @L> <n: NUMBER> <end: @R> =>? {
|
||||
if sign.is_some() {
|
||||
i64::from_str(n)
|
||||
.map(|n| -n)
|
||||
.map_err(|_| ParseError::User {
|
||||
error: custom_error::UserError {
|
||||
token: (start, n.into(), end),
|
||||
error: custom_error::UserErrorTypes::NumberTooBigi64
|
||||
}
|
||||
})
|
||||
} else {
|
||||
i64::from_str(n)
|
||||
.map_err(|_| ParseError::User {
|
||||
error: custom_error::UserError {
|
||||
token: (start, n.into(), end),
|
||||
error: custom_error::UserErrorTypes::NumberTooBigi64
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
NumUsize: usize = {
|
||||
<start: @L> <n: NUMBER> <end: @R> =>? usize::from_str(n)
|
||||
.map_err(|_| ParseError::User {
|
||||
error: custom_error::UserError {
|
||||
token: (start, n.into(), end),
|
||||
error: custom_error::UserErrorTypes::NumberTooBigUsize
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
Path: String = {
|
||||
@ -1037,12 +1070,12 @@ Instruction: presets::Instruction = {
|
||||
"Stats"
|
||||
">" <so: SaveOptions> =>
|
||||
presets::Instruction::Stats { so },
|
||||
"Target"
|
||||
"Target" <limit: ("(" "Limit" ":" NumUsize ")")?>
|
||||
">" <so: SaveOptions> =>
|
||||
presets::Instruction::Target { so },
|
||||
"Run"
|
||||
presets::Instruction::Target { so, limit: limit.map(|l| l.3) },
|
||||
"Run" <limit: ("(" "Limit" ":" NumUsize ")")?>
|
||||
">" <so: SaveOptions> =>
|
||||
presets::Instruction::Run { so },
|
||||
presets::Instruction::Run { so, limit: limit.map(|l| l.3) },
|
||||
"Loop" "(" <symbol: Literal> ")"
|
||||
">" <so: SaveOptions> =>
|
||||
presets::Instruction::Loop { symbol, so },
|
||||
|
||||
@ -1,3 +1,9 @@
|
||||
mod custom_error;
|
||||
|
||||
pub mod user_error {
|
||||
pub use crate::custom_error::*;
|
||||
}
|
||||
|
||||
lalrpop_util::lalrpop_mod!(
|
||||
#[allow(clippy::uninlined_format_args)] pub grammar, // name of module
|
||||
"/grammar.rs" // location of parser
|
||||
|
||||
Reference in New Issue
Block a user