Simplify some more parsing checks less general error messages

This commit is contained in:
NGnius (Graham) 2022-02-24 16:41:56 -05:00
parent 9a80931f1d
commit 4e5d7474b3
11 changed files with 39 additions and 78 deletions

View file

@ -162,9 +162,9 @@ pub(crate) fn standard_vocab(vocabulary: &mut MpsLanguageDictionary) {
// sorters // sorters
.add(crate::lang::vocabulary::sorters::empty_sort()) .add(crate::lang::vocabulary::sorters::empty_sort())
.add(crate::lang::vocabulary::sorters::shuffle_sort()) // accepts ~(shuffle) .add(crate::lang::vocabulary::sorters::shuffle_sort()) // accepts ~(shuffle)
.add(crate::lang::vocabulary::sorters::field_sort()) // accepts any ~(something)
.add(crate::lang::vocabulary::sorters::bliss_sort()) .add(crate::lang::vocabulary::sorters::bliss_sort())
.add(crate::lang::vocabulary::sorters::bliss_next_sort()) .add(crate::lang::vocabulary::sorters::bliss_next_sort())
.add(crate::lang::vocabulary::sorters::field_sort()) // accepts any ~(something)
// iter blocks // iter blocks
.add( .add(
crate::lang::MpsItemBlockFactory::new() crate::lang::MpsItemBlockFactory::new()

View file

@ -2,7 +2,7 @@ use std::collections::VecDeque;
use std::fmt::{Debug, Display, Error, Formatter}; use std::fmt::{Debug, Display, Error, Formatter};
use super::utility::{assert_comparison_operator, comparison_op}; use super::utility::{assert_comparison_operator, comparison_op};
use crate::lang::utility::{assert_token, assert_type, check_is_type, assert_empty}; use crate::lang::utility::{assert_token, assert_type, check_is_type};
use crate::lang::MpsLanguageDictionary; use crate::lang::MpsLanguageDictionary;
use crate::lang::MpsTypePrimitive; use crate::lang::MpsTypePrimitive;
use crate::lang::{MpsFilterFactory, MpsFilterPredicate, MpsFilterStatementFactory}; use crate::lang::{MpsFilterFactory, MpsFilterPredicate, MpsFilterStatementFactory};
@ -104,16 +104,15 @@ pub struct FieldFilterFactory;
impl MpsFilterFactory<FieldFilter> for FieldFilterFactory { impl MpsFilterFactory<FieldFilter> for FieldFilterFactory {
fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool { fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool {
let tokens_len = tokens.len(); let tokens_len = tokens.len();
(tokens_len >= 3 (tokens_len >= 2
// field > variable OR field < variable // field > variable OR field < variable
&& tokens[0].is_name() && tokens[0].is_name()
&& (tokens[1].is_open_angle_bracket() || tokens[1].is_close_angle_bracket()) && (tokens[1].is_open_angle_bracket() || tokens[1].is_close_angle_bracket()))
&& (tokens[2].is_name() || check_is_type(tokens[2]))) || (tokens_len >= 3 // field >= variable OR field <= variable OR field != variable
|| (tokens_len >= 4 // field >= variable OR field <= variable OR field != variable
&& tokens[0].is_name() && tokens[0].is_name()
&& (tokens[1].is_open_angle_bracket() || tokens[1].is_close_angle_bracket() || tokens[1].is_equals() || tokens[1].is_exclamation()) && (tokens[1].is_open_angle_bracket() || tokens[1].is_close_angle_bracket() || tokens[1].is_equals() || tokens[1].is_exclamation())
&& tokens[2].is_equals() && tokens[2].is_equals()
&& (tokens[3].is_name() || check_is_type(tokens[3]))) && !(tokens_len > 3 && tokens[3].is_equals()))
} }
fn build_filter( fn build_filter(
@ -132,7 +131,7 @@ impl MpsFilterFactory<FieldFilter> for FieldFilterFactory {
let compare_operator = assert_comparison_operator(tokens)?; let compare_operator = assert_comparison_operator(tokens)?;
if check_is_type(&tokens[0]) { if check_is_type(&tokens[0]) {
let value = VariableOrValue::Value(assert_type(tokens)?); let value = VariableOrValue::Value(assert_type(tokens)?);
assert_empty(tokens)?; //assert_empty(tokens)?;
Ok(FieldFilter { Ok(FieldFilter {
field_name: field, field_name: field,
field_errors: FieldFilterErrorHandling::Error, field_errors: FieldFilterErrorHandling::Error,
@ -149,7 +148,7 @@ impl MpsFilterFactory<FieldFilter> for FieldFilterFactory {
MpsToken::Name("variable_name".into()), MpsToken::Name("variable_name".into()),
tokens, tokens,
)?); )?);
assert_empty(tokens)?; //assert_empty(tokens)?;
Ok(FieldFilter { Ok(FieldFilter {
field_name: field, field_name: field,
field_errors: FieldFilterErrorHandling::Error, field_errors: FieldFilterErrorHandling::Error,

View file

@ -2,7 +2,7 @@ use std::collections::VecDeque;
use super::utility::assert_comparison_operator; use super::utility::assert_comparison_operator;
use super::{field_filter::VariableOrValue, FieldFilter, FieldFilterErrorHandling}; use super::{field_filter::VariableOrValue, FieldFilter, FieldFilterErrorHandling};
use crate::lang::utility::{assert_token, assert_token_raw, assert_type, check_is_type, assert_empty}; use crate::lang::utility::{assert_token, assert_token_raw, assert_type, check_is_type};
use crate::lang::MpsLanguageDictionary; use crate::lang::MpsLanguageDictionary;
use crate::lang::SyntaxError; use crate::lang::SyntaxError;
use crate::lang::{MpsFilterFactory, MpsFilterStatementFactory}; use crate::lang::{MpsFilterFactory, MpsFilterStatementFactory};
@ -13,17 +13,15 @@ pub struct FieldFilterMaybeFactory;
impl MpsFilterFactory<FieldFilter> for FieldFilterMaybeFactory { impl MpsFilterFactory<FieldFilter> for FieldFilterMaybeFactory {
fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool { fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool {
let tokens_len = tokens.len(); let tokens_len = tokens.len();
(tokens_len >= 4 // field > variable OR field < variable (tokens_len >= 3 // field > variable OR field < variable
&& tokens[0].is_name() && tokens[0].is_name()
&& (tokens[1].is_interrogation() || tokens[1].is_exclamation()) && (tokens[1].is_interrogation() || tokens[1].is_exclamation())
&& (tokens[2].is_open_angle_bracket() || tokens[2].is_close_angle_bracket()) && (tokens[2].is_open_angle_bracket() || tokens[2].is_close_angle_bracket()))
&& (tokens[3].is_name() || check_is_type(tokens[3]))) || (tokens_len >= 4 // field >= variable OR field <= variable OR field != variable
|| (tokens_len >= 5 // field >= variable OR field <= variable OR field != variable
&& tokens[0].is_name() && tokens[0].is_name()
&& (tokens[1].is_interrogation() || tokens[1].is_exclamation()) && (tokens[1].is_interrogation() || tokens[1].is_exclamation())
&& (tokens[2].is_open_angle_bracket() || tokens[2].is_close_angle_bracket() || tokens[2].is_equals() || tokens[2].is_exclamation()) && (tokens[2].is_open_angle_bracket() || tokens[2].is_close_angle_bracket() || tokens[2].is_equals() || tokens[2].is_exclamation())
&& tokens[3].is_equals() && tokens[3].is_equals())
&& (tokens[4].is_name() || check_is_type(tokens[4])))
} }
fn build_filter( fn build_filter(
@ -53,7 +51,7 @@ impl MpsFilterFactory<FieldFilter> for FieldFilterMaybeFactory {
let compare_operator = assert_comparison_operator(tokens)?; let compare_operator = assert_comparison_operator(tokens)?;
if check_is_type(&tokens[0]) { if check_is_type(&tokens[0]) {
let value = VariableOrValue::Value(assert_type(tokens)?); let value = VariableOrValue::Value(assert_type(tokens)?);
assert_empty(tokens)?; //assert_empty(tokens)?;
Ok(FieldFilter { Ok(FieldFilter {
field_name: field, field_name: field,
field_errors: error_f, field_errors: error_f,
@ -70,7 +68,7 @@ impl MpsFilterFactory<FieldFilter> for FieldFilterMaybeFactory {
MpsToken::Name("variable_name".into()), MpsToken::Name("variable_name".into()),
tokens, tokens,
)?); )?);
assert_empty(tokens)?; //assert_empty(tokens)?;
Ok(FieldFilter { Ok(FieldFilter {
field_name: field, field_name: field,
field_errors: error_f, field_errors: error_f,

View file

@ -2,7 +2,7 @@ use std::collections::VecDeque;
use std::fmt::{Debug, Display, Error, Formatter}; use std::fmt::{Debug, Display, Error, Formatter};
use super::field_filter::{FieldFilterErrorHandling, VariableOrValue}; use super::field_filter::{FieldFilterErrorHandling, VariableOrValue};
use crate::lang::utility::{assert_name, assert_token, assert_token_raw, check_name, assert_empty}; use crate::lang::utility::{assert_name, assert_token, assert_token_raw, check_name};
use crate::lang::MpsLanguageDictionary; use crate::lang::MpsLanguageDictionary;
use crate::lang::MpsTypePrimitive; use crate::lang::MpsTypePrimitive;
use crate::lang::{MpsFilterFactory, MpsFilterPredicate, MpsFilterStatementFactory}; use crate::lang::{MpsFilterFactory, MpsFilterPredicate, MpsFilterStatementFactory};
@ -72,15 +72,13 @@ pub struct FieldLikeFilterFactory;
impl MpsFilterFactory<FieldLikeFilter> for FieldLikeFilterFactory { impl MpsFilterFactory<FieldLikeFilter> for FieldLikeFilterFactory {
fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool { fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool {
let tokens_len = tokens.len(); let tokens_len = tokens.len();
(tokens_len >= 3 // field like variable (tokens_len >= 2 // field like variable
&& tokens[0].is_name() && tokens[0].is_name()
&& check_name("like", tokens[1]) && check_name("like", tokens[1]))
&& (tokens[2].is_name() || tokens[2].is_literal())) || (tokens_len >= 3 // field? like variable OR field! like variable
|| (tokens_len >= 4 // field? like variable OR field! like variable
&& tokens[0].is_name() && tokens[0].is_name()
&& (tokens[1].is_interrogation() || tokens[1].is_exclamation()) && (tokens[1].is_interrogation() || tokens[1].is_exclamation())
&& check_name("like", tokens[2]) && check_name("like", tokens[2]))
&& (tokens[3].is_name() || tokens[3].is_literal()))
} }
fn build_filter( fn build_filter(
@ -116,7 +114,7 @@ impl MpsFilterFactory<FieldLikeFilter> for FieldLikeFilterFactory {
tokens, tokens,
)?; )?;
let value = VariableOrValue::Value(MpsTypePrimitive::String(literal)); let value = VariableOrValue::Value(MpsTypePrimitive::String(literal));
assert_empty(tokens)?; //assert_empty(tokens)?;
Ok(FieldLikeFilter { Ok(FieldLikeFilter {
field_name: field, field_name: field,
field_errors: error_handling, field_errors: error_handling,
@ -131,7 +129,7 @@ impl MpsFilterFactory<FieldLikeFilter> for FieldLikeFilterFactory {
MpsToken::Name("variable_name".into()), MpsToken::Name("variable_name".into()),
tokens, tokens,
)?); )?);
assert_empty(tokens)?; //assert_empty(tokens)?;
Ok(FieldLikeFilter { Ok(FieldLikeFilter {
field_name: field, field_name: field,
field_errors: FieldFilterErrorHandling::Error, field_errors: FieldFilterErrorHandling::Error,

View file

@ -4,7 +4,7 @@ use std::fmt::{Debug, Display, Error, Formatter};
use regex::Regex; use regex::Regex;
use super::field_filter::{FieldFilterErrorHandling, VariableOrValue}; use super::field_filter::{FieldFilterErrorHandling, VariableOrValue};
use crate::lang::utility::{assert_name, assert_token, assert_token_raw, check_name, assert_empty}; use crate::lang::utility::{assert_name, assert_token, assert_token_raw, check_name};
use crate::lang::MpsLanguageDictionary; use crate::lang::MpsLanguageDictionary;
use crate::lang::MpsTypePrimitive; use crate::lang::MpsTypePrimitive;
use crate::lang::{MpsFilterFactory, MpsFilterPredicate, MpsFilterStatementFactory}; use crate::lang::{MpsFilterFactory, MpsFilterPredicate, MpsFilterStatementFactory};
@ -83,15 +83,13 @@ pub struct FieldRegexFilterFactory;
impl MpsFilterFactory<FieldRegexFilter> for FieldRegexFilterFactory { impl MpsFilterFactory<FieldRegexFilter> for FieldRegexFilterFactory {
fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool { fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool {
let tokens_len = tokens.len(); let tokens_len = tokens.len();
(tokens_len >= 3 // field like variable (tokens_len >= 2 // field like variable
&& tokens[0].is_name() && tokens[0].is_name()
&& check_name("matches", tokens[1]) && check_name("matches", tokens[1]))
&& (tokens[2].is_name() || tokens[2].is_literal())) || (tokens_len >= 3 // field? like variable OR field! like variable
|| (tokens_len >= 4 // field? like variable OR field! like variable
&& tokens[0].is_name() && tokens[0].is_name()
&& (tokens[1].is_interrogation() || tokens[1].is_exclamation()) && (tokens[1].is_interrogation() || tokens[1].is_exclamation())
&& check_name("matches", tokens[2]) && check_name("matches", tokens[2]))
&& (tokens[3].is_name() || tokens[3].is_literal()))
} }
fn build_filter( fn build_filter(
@ -133,7 +131,7 @@ impl MpsFilterFactory<FieldRegexFilter> for FieldRegexFilterFactory {
})?; })?;
let compiled_cache = (literal.clone(), regex_c); let compiled_cache = (literal.clone(), regex_c);
let value = VariableOrValue::Value(MpsTypePrimitive::String(literal)); let value = VariableOrValue::Value(MpsTypePrimitive::String(literal));
assert_empty(tokens)?; //assert_empty(tokens)?;
Ok(FieldRegexFilter { Ok(FieldRegexFilter {
field_name: field, field_name: field,
field_errors: error_handling, field_errors: error_handling,
@ -149,7 +147,7 @@ impl MpsFilterFactory<FieldRegexFilter> for FieldRegexFilterFactory {
MpsToken::Name("variable_name".into()), MpsToken::Name("variable_name".into()),
tokens, tokens,
)?); )?);
assert_empty(tokens)?; //assert_empty(tokens)?;
Ok(FieldRegexFilter { Ok(FieldRegexFilter {
field_name: field, field_name: field,
field_errors: FieldFilterErrorHandling::Error, field_errors: FieldFilterErrorHandling::Error,

View file

@ -101,40 +101,12 @@ pub struct RangeFilterFactory;
impl MpsFilterFactory<RangeFilter> for RangeFilterFactory { impl MpsFilterFactory<RangeFilter> for RangeFilterFactory {
fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool { fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool {
( tokens.len() >= 2
// .. && ((tokens.len() >= 2 && tokens[0].is_dot() && tokens[1].is_dot())
tokens.len() == 2 && tokens[0].is_dot() && tokens[1].is_dot() || (tokens.len() >= 3
) || (tokens.len() == 3
&& ((
// ..number
tokens[0].is_dot() && tokens[1].is_dot() && Lookup::check_is(tokens[2])
) || (
// number..
Lookup::check_is(tokens[0]) && tokens[1].is_dot() && tokens[2].is_dot()
)))
|| (tokens.len() == 4
&& ((
// number..number
Lookup::check_is(tokens[0])
&& tokens[1].is_dot()
&& tokens[2].is_dot()
&& Lookup::check_is(tokens[3])
) || (
// ..=number
tokens[0].is_dot()
&& tokens[1].is_dot()
&& tokens[2].is_equals()
&& Lookup::check_is(tokens[3])
)))
|| (
// number..=number
tokens.len() == 5
&& Lookup::check_is(tokens[0]) && Lookup::check_is(tokens[0])
&& tokens[1].is_dot() && tokens[1].is_dot()
&& tokens[2].is_dot() && tokens[2].is_dot()))
&& tokens[3].is_equals()
&& Lookup::check_is(tokens[4])
)
} }
fn build_filter( fn build_filter(

View file

@ -90,9 +90,7 @@ pub struct UniqueFilterFactory;
impl MpsFilterFactory<UniqueFieldFilter> for UniqueFilterFactory { impl MpsFilterFactory<UniqueFieldFilter> for UniqueFilterFactory {
fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool { fn is_filter(&self, tokens: &VecDeque<&MpsToken>) -> bool {
(tokens.len() == 2 || tokens.len() == 3) tokens.len() >= 2 && check_name("unique", &tokens[0])
&& check_name("unique", &tokens[0])
&& tokens[1].is_name()
} }
fn build_filter( fn build_filter(

View file

@ -147,9 +147,7 @@ pub struct BlissNextSorterFactory;
impl MpsSorterFactory<BlissNextSorter> for BlissNextSorterFactory { impl MpsSorterFactory<BlissNextSorter> for BlissNextSorterFactory {
fn is_sorter(&self, tokens: &VecDeque<&MpsToken>) -> bool { fn is_sorter(&self, tokens: &VecDeque<&MpsToken>) -> bool {
tokens.len() == 2 tokens.len() > 1 && check_name("advanced", tokens[0]) && check_name("bliss_next", tokens[1])
&& check_name("advanced", tokens[0])
&& check_name("bliss_next", tokens[1])
} }
fn build_sorter( fn build_sorter(

View file

@ -141,7 +141,7 @@ pub struct BlissSorterFactory;
impl MpsSorterFactory<BlissSorter> for BlissSorterFactory { impl MpsSorterFactory<BlissSorter> for BlissSorterFactory {
fn is_sorter(&self, tokens: &VecDeque<&MpsToken>) -> bool { fn is_sorter(&self, tokens: &VecDeque<&MpsToken>) -> bool {
tokens.len() == 2 tokens.len() > 1
&& check_name("advanced", tokens[0]) && check_name("advanced", tokens[0])
&& check_name("bliss_first", tokens[1]) && check_name("bliss_first", tokens[1])
} }

View file

@ -60,7 +60,7 @@ pub struct FieldSorterFactory;
impl MpsSorterFactory<FieldSorter> for FieldSorterFactory { impl MpsSorterFactory<FieldSorter> for FieldSorterFactory {
fn is_sorter(&self, tokens: &VecDeque<&MpsToken>) -> bool { fn is_sorter(&self, tokens: &VecDeque<&MpsToken>) -> bool {
tokens.len() == 1 && tokens[0].is_name() !tokens.is_empty() && tokens[0].is_name()
} }
fn build_sorter( fn build_sorter(

View file

@ -71,8 +71,8 @@ pub struct ShuffleSorterFactory;
impl MpsSorterFactory<ShuffleSorter> for ShuffleSorterFactory { impl MpsSorterFactory<ShuffleSorter> for ShuffleSorterFactory {
fn is_sorter(&self, tokens: &VecDeque<&MpsToken>) -> bool { fn is_sorter(&self, tokens: &VecDeque<&MpsToken>) -> bool {
(tokens.len() == 1 && check_name("shuffle", &tokens[0])) (!tokens.is_empty() && check_name("shuffle", &tokens[0]))
|| (tokens.len() == 2 || (tokens.len() > 1
&& check_name("random", &tokens[0]) && check_name("random", &tokens[0])
&& check_name("shuffle", &tokens[1])) && check_name("shuffle", &tokens[1]))
} }