1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
use std::path::PathBuf;
use anyhow::anyhow;
use parol_runtime::Location;
use thiserror::Error;
///
/// Error types used by the [crate::parser::ParolGrammar]'s semantic actions
#[derive(Error, Debug)]
pub enum ParolParserError {
/// Undeclared scanner found. Please declare a scanner via %scanner name {{...}}
#[error("{context} - Unknown scanner {name}")]
UnknownScanner {
/// Context (semantic action) where the error was issued
context: String,
/// Name of the unknown scanner state
name: String,
/// Source
input: PathBuf,
/// Location
token: Location,
},
/// Empty Groups () are not allowed.
#[error("{context} - Empty Group not allowed")]
EmptyGroup {
/// Context (semantic action) where the error was issued
context: String,
/// Source
input: PathBuf,
/// Start location
start: Location,
/// End location
end: Location,
},
/// Empty Optionals [] are not allowed.
#[error("{context} - Empty Optionals not allowed")]
EmptyOptional {
/// Context (semantic action) where the error was issued
context: String,
/// Source
input: PathBuf,
/// Start location
start: Location,
/// End location
end: Location,
},
/// Empty Repetitions {{}} are not allowed.
#[error("{context} - Empty Repetitions not allowed")]
EmptyRepetition {
/// Context (semantic action) where the error was issued
context: String,
/// Source
input: PathBuf,
/// Start location
start: Location,
/// End location
end: Location,
},
/// Multiple token aliases that expand to the same text will produce a terminal conflict.
#[error(
r"Multiple token aliases that expand to the same text:
'{first_alias}' and '{second_alias}' expand both to '{expanded}'."
)]
ConflictingTokenAliases {
/// First
first_alias: String,
/// Second
second_alias: String,
/// Expanded
expanded: String,
/// Source
input: PathBuf,
/// First alias
first: Location,
/// Second alias
second: Location,
},
/// Empty Scanner states are not allowed.
#[error("Empty scanner states ({empty_scanners:?}) found")]
EmptyScanners {
/// Names of the empty scanner states
empty_scanners: Vec<String>,
},
/// Unsupported grammar type
#[error("{grammar_type} - Unsupported grammar type")]
UnsupportedGrammarType {
/// The grammar type found
grammar_type: String,
/// Source
input: PathBuf,
/// Location
token: Location,
},
/// Unsupported feature
#[error("{feature} - Unsupported feature")]
UnsupportedFeature {
/// The feature found
feature: String,
/// Hint
hint: String,
/// Source
input: PathBuf,
/// Location
token: Location,
},
/// Invalid token in transition, e.g. a token that is not defined in the grammar
/// is used in a transition. Use a primary non-terminal for the token.
#[error(
"{context} - Invalid token '{token}' in transition. Use a primary non-terminal for the token."
)]
InvalidTokenInTransition {
/// Context where the error was issued
context: String,
/// Token that is not defined matched against a valid primary non-terminal
token: String,
/// Source file
input: PathBuf,
/// Location of the token
location: Location,
},
/// The token that is used to initiate a transition is not defined in this scanner.
#[error("{context} - Token '{token}' is not defined in scanner '{scanner}'")]
TokenIsNotInScanner {
/// Context where the error was issued
context: String,
/// The scanner where the token is not defined
scanner: String,
/// Token that is not defined in the scanner
token: String,
/// Source file
input: PathBuf,
/// Location of the token
location: Location,
},
/// Mixed scanner switching is not allowed - use either parser-based or scanner-based switching.
/// Parser-based switching is done via the %sc, %push and %pop directives productions.
/// Scanner-based switching is done via the %on directive in the header of the grammar file.
#[error("{context} - Mixed scanner switching is not allowed")]
MixedScannerSwitching {
/// Context where the error was issued
context: String,
/// Source file
input: PathBuf,
/// Location of the token
location: Location,
},
}
impl From<ParolParserError> for parol_runtime::ParolError {
fn from(err: ParolParserError) -> Self {
parol_runtime::ParolError::UserError(anyhow!(err))
}
}