aboutsummaryrefslogtreecommitdiffstats
path: root/src/parse
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/mod.rs35
-rw-r--r--src/parse/regex/mod.rs33
2 files changed, 64 insertions, 4 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index b3855a8..b07d5f9 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -426,7 +426,7 @@ impl Parse for Block {
fn parse(b: &mut Cursor<'_>) -> Result<Self> {
let mut commands = Vec::new();
- b.consume_keyword(Keyword::OpenBrace)?;
+ b.expect_keyword(Keyword::OpenBrace)?;
loop {
while {
@@ -444,7 +444,7 @@ impl Parse for Block {
commands.push(cmd);
}
- let finished_parsing = match b.consume_keyword(Keyword::CloseBrace) {
+ let finished_parsing = match b.expect_keyword(Keyword::CloseBrace) {
Ok(_) => true,
Err(_) if b.is_completion() => false,
Err(e) => Err(e)?,
@@ -1365,7 +1365,10 @@ impl From<OtherHighlights> for HighlightKind {
pub enum OtherHighlights {
String,
Variable,
+ Regex,
+ RegexSymbol,
Escapes,
+ SyntaxError,
}
impl OtherHighlights {
@@ -1374,6 +1377,9 @@ impl OtherHighlights {
OtherHighlights::String => b"string",
OtherHighlights::Variable => b"var",
OtherHighlights::Escapes => b"escape",
+ OtherHighlights::Regex => b"regex",
+ OtherHighlights::RegexSymbol => b"regexsym",
+ OtherHighlights::SyntaxError => b"syntax_error",
}
}
}
@@ -1634,6 +1640,31 @@ impl<'a> Cursor<'a> {
T::parse(self)
}
+ fn expect_keyword(&mut self, kw: Keyword) -> Result<()> {
+ if !self.is_completion() {
+ return self.consume_keyword(kw)
+ }
+
+ // very lax parsing that consumes everything in its way until the keyword arrives
+ self.spaces();
+ let begin = self.loc();
+ loop {
+ let end = self.loc_u32();
+ if self.consume_keyword(kw).is_ok() {
+ if end > begin.start {
+ self.highlight(begin.to(end), OtherHighlights::SyntaxError);
+ }
+ return Ok(());
+ } else if self.has() {
+ self.adv();
+ } else {
+ break;
+ }
+ }
+ self.highlight_from(begin, OtherHighlights::SyntaxError);
+ Err(ParseError::ExpectedKeyword(kw))
+ }
+
fn consume_keyword(&mut self, kw: Keyword) -> Result<()> {
let bytes = kw.as_bytes();
diff --git a/src/parse/regex/mod.rs b/src/parse/regex/mod.rs
index d5e4cdf..98056cb 100644
--- a/src/parse/regex/mod.rs
+++ b/src/parse/regex/mod.rs
@@ -1,3 +1,5 @@
+use crate::parse::OtherHighlights;
+
use super::{Parse, ParseError, Result};
mod byte_range;
@@ -16,10 +18,19 @@ pub enum Pattern {
impl Parse for Pattern {
fn parse(b: &mut super::Cursor<'_>) -> super::Result<Self> {
- parse_alt(b)
+ let begin = b.loc();
+ let result = parse0(b);
+ if result.is_ok() {
+ b.highlight_from(begin, OtherHighlights::Regex);
+ }
+ result
}
}
+fn parse0(s: &mut super::Cursor<'_>) -> Result<Pattern> {
+ parse_alt(s)
+}
+
fn parse_alt(s: &mut super::Cursor<'_>) -> Result<Pattern> {
let mut seqs = vec![];
loop {
@@ -27,8 +38,10 @@ fn parse_alt(s: &mut super::Cursor<'_>) -> Result<Pattern> {
if seq != Pattern::Nothing {
seqs.push(seq);
}
+ let begin = s.loc();
if s.has() && s.peek() == b'|' {
s.adv();
+ s.highlight_from(begin, OtherHighlights::RegexSymbol);
} else {
break;
}
@@ -70,17 +83,22 @@ fn parse_rep(s: &mut super::Cursor<'_>) -> Result<Pattern> {
return Ok(atom);
}
+ let begin = s.loc();
+
match s.peek() {
b'*' => {
s.adv();
+ s.highlight_from(begin, OtherHighlights::RegexSymbol);
Ok(Pattern::Rep(Box::new(atom), 0, None))
}
b'+' => {
s.adv();
+ s.highlight_from(begin, OtherHighlights::RegexSymbol);
Ok(Pattern::Rep(Box::new(atom), 1, None))
}
b'?' => {
s.adv();
+ s.highlight_from(begin, OtherHighlights::RegexSymbol);
Ok(Pattern::Rep(Box::new(atom), 0, Some(1)))
}
_ => Ok(atom),
@@ -99,21 +117,26 @@ fn parse_atom(s: &mut super::Cursor<'_>) -> Result<Pattern> {
return Ok(Pattern::Nothing);
}
+ let begin = s.loc();
+
match s.peek() {
b'[' => {
s.adv();
+ s.highlight_from(begin, OtherHighlights::RegexSymbol);
let mut ranges = Vec::new();
loop {
if !s.has() {
return Err(ParseError::Eof);
}
+ let begin = s.loc();
let tok = s.adv();
if tok == b']' {
if ranges.is_empty() {
todo!("error handling for empty alternative list");
}
+ s.highlight_from(begin, OtherHighlights::RegexSymbol);
return Ok(Pattern::Alt(ranges));
}
@@ -121,8 +144,10 @@ fn parse_atom(s: &mut super::Cursor<'_>) -> Result<Pattern> {
return Err(ParseError::Unknown(tok));
}
+ let begin = s.loc();
if s.has() && s.peek() == b'-' {
s.adv();
+ s.highlight_from(begin, OtherHighlights::RegexSymbol);
if !s.has() {
return Err(ParseError::Eof);
@@ -141,17 +166,21 @@ fn parse_atom(s: &mut super::Cursor<'_>) -> Result<Pattern> {
}
b'(' => {
s.adv();
- let inner = Pattern::parse(s)?;
+ s.highlight_from(begin, OtherHighlights::RegexSymbol);
+ let inner = parse0(s)?;
if !s.has() {
return Err(ParseError::Eof);
}
+ let begin = s.loc();
if s.adv() != b')' {
return Err(ParseError::Expected(')'));
}
+ s.highlight_from(begin, OtherHighlights::RegexSymbol);
Ok(inner)
}
b'.' => {
s.adv();
+ s.highlight_from(begin, OtherHighlights::RegexSymbol);
Ok(Pattern::Range(0, 127))
}
x if is_symbol(x) => Ok(Pattern::Nothing),