-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from metaborg/regex
Regex
- Loading branch information
Showing
18 changed files
with
2,160 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,7 @@ jobs: | |
uses: actions-rs/cargo@v1 | ||
with: | ||
command: test | ||
args: --all-features | ||
|
||
test-miri: | ||
name: Test Miri | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,40 @@ | ||
use crate::label::impl_label; | ||
use crate::regex::RegexInput; | ||
|
||
use proc_macro::TokenStream; | ||
use syn::{parse_macro_input, DeriveInput}; | ||
|
||
mod label; | ||
mod regex; | ||
|
||
#[proc_macro_derive(Label)] | ||
pub fn label_derive(input: TokenStream) -> TokenStream { | ||
let input = parse_macro_input!(input as DeriveInput); | ||
impl_label(input) | ||
} | ||
|
||
/// Syntax: `$attrs type $type<$alphabet_type> = regex`. | ||
/// For example: | ||
/// | ||
/// ```rust | ||
/// # use std::borrow; | ||
/// use scopegraphs::*; | ||
/// | ||
/// pub enum Alphabet { | ||
/// A, | ||
/// B, | ||
/// C, | ||
/// } | ||
/// use Alphabet::*; | ||
/// | ||
/// compile_regex!(type Machine<Alphabet> = A* B); | ||
/// assert!(Machine::new().accepts([A, B])); | ||
/// ``` | ||
/// | ||
/// # Attributes | ||
/// * `#[graph="$path"]` location to put a graphviz dot file representing the generated finite state machine. (only with the `dot` feature) | ||
#[proc_macro] | ||
pub fn compile_regex(input: TokenStream) -> TokenStream { | ||
let input = parse_macro_input!(input as RegexInput); | ||
input.compile() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
use std::rc::Rc; | ||
|
||
use proc_macro::TokenStream; | ||
use scopegraphs_regular_expressions::Regex; | ||
use syn::parse::{Parse, ParseStream}; | ||
use syn::{Attribute, Ident, Meta, Token, Type}; | ||
|
||
#[cfg(feature = "dot")] | ||
use std::fs::File; | ||
#[cfg(feature = "dot")] | ||
use syn::{Expr, ExprLit, Lit, MetaNameValue}; | ||
|
||
pub(crate) struct RegexInput { | ||
attrs: Vec<Attribute>, | ||
_type: Token![type], | ||
name: Ident, | ||
_open: Token![<], | ||
alphabet_type: Type, | ||
_close: Token![>], | ||
_equals: Token![=], | ||
regex: Regex, | ||
errors: Vec<syn::Error>, | ||
} | ||
|
||
impl Parse for RegexInput { | ||
fn parse(input: ParseStream) -> syn::Result<Self> { | ||
let attrs = input.call(Attribute::parse_outer)?; | ||
let _type = input.parse()?; | ||
let name = input.parse()?; | ||
let _open = input.parse()?; | ||
let alphabet_type = input.parse()?; | ||
let _close = input.parse()?; | ||
let _equals = input.parse()?; | ||
let (regex, errors) = match input.parse() { | ||
Ok(re) => (re, vec![]), | ||
Err(err) => (Regex::Complement(Rc::new(Regex::EmptySet)), vec![err]), | ||
}; | ||
Ok(Self { | ||
attrs, | ||
_type, | ||
name, | ||
_open, | ||
alphabet_type, | ||
_close, | ||
_equals, | ||
regex, | ||
errors, | ||
}) | ||
} | ||
} | ||
|
||
impl RegexInput { | ||
pub fn compile(self) -> TokenStream { | ||
let mut errors = self.errors; | ||
#[cfg(feature = "dot")] | ||
let mut graph = None; | ||
|
||
for i in self.attrs { | ||
let attr = i.meta.clone(); | ||
match attr { | ||
#[cfg(feature = "dot")] | ||
Meta::NameValue(MetaNameValue { | ||
path, | ||
value: | ||
Expr::Lit(ExprLit { | ||
lit: Lit::Str(s), .. | ||
}), | ||
.. | ||
}) if path.is_ident("graph") => { | ||
graph = Some(s); | ||
} | ||
i => errors.push(syn::Error::new_spanned(i, "unexpected attribute")), | ||
} | ||
} | ||
|
||
let compiled = self.regex.compile(); | ||
|
||
#[cfg(feature = "dot")] | ||
if let Some(path) = graph { | ||
let path = path.value(); | ||
let mut f = File::create(&path) | ||
.unwrap_or_else(|e| panic!("can't open dot file for graphing at {path}: {e}")); | ||
compiled | ||
.output_dot(&mut f) | ||
.unwrap_or_else(|e| panic!("failed while graphing at {path}: {e}")); | ||
} | ||
|
||
compiled | ||
.emit(&self.name, &self.alphabet_type, errors) | ||
.into() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "scopegraphs-regular-expressions" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
[dependencies] | ||
syn = { version = "2.0.29", features = ["full", "extra-traits"] } | ||
quote = { version = "1.0.33" , optional = true} | ||
proc-macro2 = "1.0.69" | ||
thiserror = "1.0.50" | ||
|
||
[features] | ||
rust-code-emitting = ["quote"] | ||
pretty-print = ["quote"] | ||
dot = ["pretty-print"] | ||
dynamic = ["quote"] |
Oops, something went wrong.