diff options
| author | Jonas Maier <jonas@x77.dev> | 2026-06-01 21:55:53 +0200 |
|---|---|---|
| committer | Jonas Maier <jonas@x77.dev> | 2026-06-01 21:55:53 +0200 |
| commit | c73ed9310d8162b71183688de62bf8c1fc8420df (patch) | |
| tree | c49063954f665a072cb8e63b10c4e95e31769826 /src/parse/regex/mod.rs | |
| parent | c52169f535f89c0300ec06e13ddcaa7e0f459a0b (diff) | |
| download | pish-c73ed9310d8162b71183688de62bf8c1fc8420df.tar.gz | |
syntax highlighting for regex; syntax highlighting syntax errors
Diffstat (limited to 'src/parse/regex/mod.rs')
| -rw-r--r-- | src/parse/regex/mod.rs | 33 |
1 files changed, 31 insertions, 2 deletions
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), |
