diff --git a/sv-parser-macros/src/lib.rs b/sv-parser-macros/src/lib.rs index 718781a..d73dafe 100644 --- a/sv-parser-macros/src/lib.rs +++ b/sv-parser-macros/src/lib.rs @@ -4,9 +4,8 @@ extern crate proc_macro; use crate::proc_macro::TokenStream; use quote::quote; -use std::str::FromStr; use syn::Data::{Enum, Struct}; -use syn::{self, parse_macro_input, AttributeArgs, DeriveInput, ItemFn, Meta, NestedMeta, Stmt}; +use syn::{self, DeriveInput}; #[proc_macro_derive(Node)] pub fn node_derive(input: TokenStream) -> TokenStream { @@ -155,120 +154,3 @@ fn impl_ref_node(ast: &DeriveInput) -> TokenStream { }; gen.into() } - -#[proc_macro_attribute] -pub fn parser(attr: TokenStream, item: TokenStream) -> TokenStream { - let attr = parse_macro_input!(attr as AttributeArgs); - let item = parse_macro_input!(item as ItemFn); - impl_parser(&attr, &item) -} - -fn impl_parser(attr: &AttributeArgs, item: &ItemFn) -> TokenStream { - let ambiguous = impl_parser_attribute(attr); - - let body = if ambiguous { - impl_parser_body_ambiguous(&item) - } else { - impl_parser_body(&item) - }; - let body = parse_macro_input!(body as Stmt); - - let mut item = item.clone(); - - item.block.stmts.clear(); - item.block.stmts.push(body); - - let gen = quote! { - #item - }; - gen.into() -} - -fn impl_parser_attribute(attr: &AttributeArgs) -> bool { - let mut ambiguous = false; - - for a in attr { - match a { - NestedMeta::Meta(Meta::Word(x)) if x == "Ambiguous" => ambiguous = true, - _ => panic!(), - } - } - - ambiguous -} - -fn impl_parser_body(item: &ItemFn) -> TokenStream { - let mut gen = quote! {}; - for s in &item.block.stmts { - gen = quote! { - #gen - #s - }; - } - let gen = quote! { - { - #gen - } - }; - gen.into() -} - -fn impl_parser_body_ambiguous(item: &ItemFn) -> TokenStream { - let mut token = quote! {}; - for s in &item.block.stmts { - token = quote! { - #token - #s - }; - } - let mut token = token.to_string(); - - let ambiguous_cnt: Vec<&str> = token.matches("ambiguous").collect(); - let ambiguous_cnt = ambiguous_cnt.len(); - - let mut replace_parsers = Vec::new(); - for i in 0..ambiguous_cnt { - let pos = token.find("ambiguous").unwrap(); - let (head, rest) = token.split_at(pos); - if rest.starts_with("ambiguous_opt") { - let rest = rest.replacen("ambiguous_opt", &format!("amb_temporary{}", i), 1); - token = format!("{}{}", head, rest); - replace_parsers.push(("opt", "none")); - } else if rest.starts_with("ambiguous_alt") { - let rest = rest.replacen("ambiguous_alt", &format!("amb_temporary{}", i), 1); - token = format!("{}{}", head, rest); - replace_parsers.push(("alt_left", "alt_right")); - } - } - - let mut gen = quote! {}; - for i in 0..2_u32.pow(ambiguous_cnt as u32) { - let mut token = token.clone(); - for j in 0..ambiguous_cnt { - let (p0, p1) = replace_parsers[j]; - let repl = if ((i >> j) & 1) == 0 { p0 } else { p1 }; - token = token.replace(&format!("amb_temporary{}", j), repl); - } - let token = format!("{{ {} }}", token); - let token = TokenStream::from_str(&token).unwrap(); - let token = parse_macro_input!(token as Stmt); - gen = quote! { - #gen - |s| #token, - }; - } - - let gen = quote! { - alt(( - #gen - ))(s) - }; - - let gen = quote! { - { - #gen - } - }; - - gen.into() -} diff --git a/sv-parser-parser/Cargo.toml b/sv-parser-parser/Cargo.toml index 2464b2d..00a0d49 100644 --- a/sv-parser-parser/Cargo.toml +++ b/sv-parser-parser/Cargo.toml @@ -11,6 +11,7 @@ trace = ["nom-tracable/trace"] [dependencies] nom = "5.0.0" nom_locate = "0.4.0" +nom-both = {path = "../../nom-both/nom-both"} nom-packrat = {path = "../../nom-packrat/nom-packrat"} nom-recursive = {path = "../../nom-recursive/nom-recursive"} nom-tracable = {path = "../../nom-tracable/nom-tracable"} diff --git a/sv-parser-parser/src/declarations/assertion_declarations.rs b/sv-parser-parser/src/declarations/assertion_declarations.rs index 6b3672a..e91968b 100644 --- a/sv-parser-parser/src/declarations/assertion_declarations.rs +++ b/sv-parser-parser/src/declarations/assertion_declarations.rs @@ -234,12 +234,12 @@ pub(crate) fn property_port_list(s: Span) -> IResult { Ok((s, PropertyPortList { nodes: (a,) })) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn property_port_item(s: Span) -> IResult { let (s, a) = many0(attribute_instance)(s)?; let (s, b) = opt(pair(local, opt(property_lvar_port_direction)))(s)?; - let (s, c) = ambiguous_opt(property_formal_type)(s)?; + let (s, c) = both_opt(property_formal_type)(s)?; let (s, d) = formal_port_identifier(s)?; let (s, e) = many0(variable_dimension)(s)?; let (s, f) = opt(pair(symbol("="), property_actual_arg))(s)?; @@ -724,12 +724,12 @@ pub(crate) fn sequence_port_list(s: Span) -> IResult { Ok((s, SequencePortList { nodes: (a,) })) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn sequence_port_item(s: Span) -> IResult { let (s, a) = many0(attribute_instance)(s)?; let (s, b) = opt(pair(local, opt(sequence_lvar_port_direction)))(s)?; - let (s, c) = ambiguous_opt(sequence_formal_type)(s)?; + let (s, c) = both_opt(sequence_formal_type)(s)?; let (s, d) = formal_port_identifier(s)?; let (s, e) = many0(variable_dimension)(s)?; let (s, f) = opt(pair(symbol("="), sequence_actual_arg))(s)?; diff --git a/sv-parser-parser/src/declarations/covergroup_declarations.rs b/sv-parser-parser/src/declarations/covergroup_declarations.rs index 438d5df..5437f2e 100644 --- a/sv-parser-parser/src/declarations/covergroup_declarations.rs +++ b/sv-parser-parser/src/declarations/covergroup_declarations.rs @@ -206,11 +206,11 @@ pub(crate) fn hierarchical_identifier_or_class_scope( ))(s) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn cover_point(s: Span) -> IResult { let (s, a) = opt(triple( - ambiguous_opt(data_type_or_implicit), + both_opt(data_type_or_implicit), cover_point_identifier, symbol(":"), ))(s)?; diff --git a/sv-parser-parser/src/declarations/function_declarations.rs b/sv-parser-parser/src/declarations/function_declarations.rs index 19e9cd7..559b6ac 100644 --- a/sv-parser-parser/src/declarations/function_declarations.rs +++ b/sv-parser-parser/src/declarations/function_declarations.rs @@ -30,12 +30,12 @@ pub(crate) fn function_body_declaration(s: Span) -> IResult IResult { - let (s, a) = ambiguous_opt(function_data_type_or_implicit)(s)?; + let (s, a) = both_opt(function_data_type_or_implicit)(s)?; let (s, b) = opt(interface_identifier_or_class_scope)(s)?; let (s, c) = function_identifier(s)?; let (s, d) = symbol(";")(s)?; @@ -51,12 +51,12 @@ pub(crate) fn function_body_declaration_without_port( )) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn function_body_declaration_with_port( s: Span, ) -> IResult { - let (s, a) = ambiguous_opt(function_data_type_or_implicit)(s)?; + let (s, a) = both_opt(function_data_type_or_implicit)(s)?; let (s, b) = opt(interface_identifier_or_class_scope)(s)?; let (s, c) = function_identifier(s)?; let (s, d) = paren(opt(tf_port_list))(s)?; diff --git a/sv-parser-parser/src/declarations/let_declarations.rs b/sv-parser-parser/src/declarations/let_declarations.rs index 5313623..13c854e 100644 --- a/sv-parser-parser/src/declarations/let_declarations.rs +++ b/sv-parser-parser/src/declarations/let_declarations.rs @@ -30,11 +30,11 @@ pub(crate) fn let_port_list(s: Span) -> IResult { Ok((s, LetPortList { nodes: (a,) })) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn let_port_item(s: Span) -> IResult { let (s, a) = many0(attribute_instance)(s)?; - let (s, b) = ambiguous_opt(let_formal_type)(s)?; + let (s, b) = both_opt(let_formal_type)(s)?; let (s, c) = formal_port_identifier(s)?; let (s, d) = many0(variable_dimension)(s)?; let (s, e) = opt(pair(symbol("="), expression))(s)?; diff --git a/sv-parser-parser/src/declarations/module_parameter_declarations.rs b/sv-parser-parser/src/declarations/module_parameter_declarations.rs index d4fbbf7..38a699d 100644 --- a/sv-parser-parser/src/declarations/module_parameter_declarations.rs +++ b/sv-parser-parser/src/declarations/module_parameter_declarations.rs @@ -10,13 +10,13 @@ pub(crate) fn local_parameter_declaration(s: Span) -> IResult IResult { let (s, a) = keyword("localparam")(s)?; - let (s, b) = ambiguous_opt(data_type_or_implicit)(s)?; + let (s, b) = both_opt(data_type_or_implicit)(s)?; let (s, c) = list_of_param_assignments(s)?; Ok(( s, @@ -46,11 +46,11 @@ pub(crate) fn parameter_declaration(s: Span) -> IResult IResult { let (s, a) = keyword("parameter")(s)?; - let (s, b) = ambiguous_opt(data_type_or_implicit)(s)?; + let (s, b) = both_opt(data_type_or_implicit)(s)?; let (s, c) = list_of_param_assignments(s)?; Ok(( s, diff --git a/sv-parser-parser/src/declarations/port_declarations.rs b/sv-parser-parser/src/declarations/port_declarations.rs index 956b4ed..d2baa6f 100644 --- a/sv-parser-parser/src/declarations/port_declarations.rs +++ b/sv-parser-parser/src/declarations/port_declarations.rs @@ -2,11 +2,11 @@ use crate::*; // ----------------------------------------------------------------------------- -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn inout_declaration(s: Span) -> IResult { let (s, a) = keyword("inout")(s)?; - let (s, b) = ambiguous_opt(net_port_type)(s)?; + let (s, b) = both_opt(net_port_type)(s)?; let (s, c) = list_of_port_identifiers(s)?; Ok((s, InoutDeclaration { nodes: (a, b, c) })) } @@ -16,11 +16,11 @@ pub(crate) fn input_declaration(s: Span) -> IResult { alt((input_declaration_net, input_declaration_variable))(s) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn input_declaration_net(s: Span) -> IResult { let (s, a) = keyword("input")(s)?; - let (s, b) = ambiguous_opt(net_port_type)(s)?; + let (s, b) = both_opt(net_port_type)(s)?; let (s, c) = list_of_port_identifiers(s)?; Ok(( s, @@ -28,11 +28,11 @@ pub(crate) fn input_declaration_net(s: Span) -> IResult )) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn input_declaration_variable(s: Span) -> IResult { let (s, a) = keyword("input")(s)?; - let (s, b) = ambiguous_alt(variable_port_type, implicit_var)(s)?; + let (s, b) = both_alt(variable_port_type, implicit_var)(s)?; let (s, c) = list_of_variable_identifiers(s)?; Ok(( s, @@ -45,11 +45,11 @@ pub(crate) fn output_declaration(s: Span) -> IResult { alt((output_declaration_net, output_declaration_variable))(s) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn output_declaration_net(s: Span) -> IResult { let (s, a) = keyword("output")(s)?; - let (s, b) = ambiguous_opt(net_port_type)(s)?; + let (s, b) = both_opt(net_port_type)(s)?; let (s, c) = list_of_port_identifiers(s)?; Ok(( s, @@ -57,11 +57,11 @@ pub(crate) fn output_declaration_net(s: Span) -> IResult IResult { let (s, a) = keyword("output")(s)?; - let (s, b) = ambiguous_alt(variable_port_type, implicit_var)(s)?; + let (s, b) = both_alt(variable_port_type, implicit_var)(s)?; let (s, c) = list_of_variable_port_identifiers(s)?; Ok(( s, @@ -77,11 +77,11 @@ pub(crate) fn interface_port_declaration(s: Span) -> IResult IResult { let (s, a) = keyword("ref")(s)?; - let (s, b) = ambiguous_alt(variable_port_type, implicit_var)(s)?; + let (s, b) = both_alt(variable_port_type, implicit_var)(s)?; let (s, c) = list_of_variable_identifiers(s)?; Ok((s, RefDeclaration { nodes: (a, b, c) })) } diff --git a/sv-parser-parser/src/declarations/task_declarations.rs b/sv-parser-parser/src/declarations/task_declarations.rs index dc6bd31..5c6798d 100644 --- a/sv-parser-parser/src/declarations/task_declarations.rs +++ b/sv-parser-parser/src/declarations/task_declarations.rs @@ -71,13 +71,13 @@ pub(crate) fn tf_port_list(s: Span) -> IResult { Ok((s, TfPortList { nodes: (a,) })) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn tf_port_item(s: Span) -> IResult { let (s, a) = many0(attribute_instance)(s)?; let (s, b) = opt(tf_port_direction)(s)?; let (s, c) = opt(var)(s)?; - let (s, d) = ambiguous_opt(data_type_or_implicit)(s)?; + let (s, d) = both_opt(data_type_or_implicit)(s)?; let (s, e) = opt(triple( port_identifier, many0(variable_dimension), @@ -103,13 +103,13 @@ pub(crate) fn tf_port_direction(s: Span) -> IResult { ))(s) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn tf_port_declaration(s: Span) -> IResult { let (s, a) = many0(attribute_instance)(s)?; let (s, b) = tf_port_direction(s)?; let (s, c) = opt(var)(s)?; - let (s, d) = ambiguous_opt(data_type_or_implicit)(s)?; + let (s, d) = both_opt(data_type_or_implicit)(s)?; let (s, e) = list_of_tf_variable_identifiers(s)?; let (s, f) = symbol(";")(s)?; Ok(( diff --git a/sv-parser-parser/src/declarations/type_declarations.rs b/sv-parser-parser/src/declarations/type_declarations.rs index f012563..c188806 100644 --- a/sv-parser-parser/src/declarations/type_declarations.rs +++ b/sv-parser-parser/src/declarations/type_declarations.rs @@ -18,13 +18,13 @@ pub(crate) fn data_declaration(s: Span) -> IResult { ))(s) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn data_declaration_variable(s: Span) -> IResult { let (s, a) = opt(r#const)(s)?; let (s, b) = opt(var)(s)?; let (s, c) = opt(lifetime)(s)?; - let (s, d) = ambiguous_opt(data_type_or_implicit)(s)?; + let (s, d) = both_opt(data_type_or_implicit)(s)?; let (s, e) = list_of_variable_decl_assignments(s)?; let (s, f) = symbol(";")(s)?; Ok(( @@ -127,13 +127,13 @@ pub(crate) fn net_declaration(s: Span) -> IResult { ))(s) } -#[parser(Ambiguous)] +#[both_parser] #[tracable_parser] pub(crate) fn net_declaration_net_type(s: Span) -> IResult { let (s, a) = net_type(s)?; let (s, b) = opt(strength)(s)?; let (s, c) = opt(vector_scalar)(s)?; - let (s, d) = ambiguous_opt(data_type_or_implicit)(s)?; + let (s, d) = both_opt(data_type_or_implicit)(s)?; let (s, e) = opt(delay3)(s)?; let (s, f) = list_of_net_decl_assignments(s)?; let (s, g) = symbol(";")(s)?; diff --git a/sv-parser-parser/src/lib.rs b/sv-parser-parser/src/lib.rs index 34b2247..5e4bbcf 100644 --- a/sv-parser-parser/src/lib.rs +++ b/sv-parser-parser/src/lib.rs @@ -31,12 +31,12 @@ pub(crate) use nom::error::{make_error, ErrorKind}; pub(crate) use nom::multi::*; pub(crate) use nom::sequence::*; pub(crate) use nom::{Err, IResult}; +pub(crate) use nom_both::both_parser; pub(crate) use nom_packrat::{self, packrat_parser, HasExtraState}; pub(crate) use nom_recursive::{recursive_parser, HasRecursiveInfo, RecursiveInfo}; pub(crate) use nom_tracable::tracable_parser; #[cfg(feature = "trace")] pub(crate) use nom_tracable::{HasTracableInfo, TracableInfo}; -pub(crate) use sv_parser_macros::*; pub(crate) use sv_parser_syntaxtree::*; // ----------------------------------------------------------------------------- diff --git a/sv-parser-parser/src/utils.rs b/sv-parser-parser/src/utils.rs index 4d9ef65..3f38437 100644 --- a/sv-parser-parser/src/utils.rs +++ b/sv-parser-parser/src/utils.rs @@ -495,35 +495,6 @@ where } } -pub(crate) fn none<'a, O, F>(_f: F) -> impl Fn(Span<'a>) -> IResult, Option> -where - F: Fn(Span<'a>) -> IResult, O>, -{ - move |s: Span<'a>| Ok((s, None)) -} - -pub(crate) fn alt_left<'a, O, F, G>(f: F, _g: G) -> impl Fn(Span<'a>) -> IResult, O> -where - F: Fn(Span<'a>) -> IResult, O>, - G: Fn(Span<'a>) -> IResult, O>, -{ - move |s: Span<'a>| { - let (s, x) = f(s)?; - Ok((s, x)) - } -} - -pub(crate) fn alt_right<'a, O, F, G>(_f: F, g: G) -> impl Fn(Span<'a>) -> IResult, O> -where - F: Fn(Span<'a>) -> IResult, O>, - G: Fn(Span<'a>) -> IResult, O>, -{ - move |s: Span<'a>| { - let (s, x) = g(s)?; - Ok((s, x)) - } -} - // ----------------------------------------------------------------------------- #[tracable_parser]