Apply nom-both

This commit is contained in:
dalance 2019-07-29 19:28:59 +09:00
parent d1e8de8664
commit bdddb4a8ce
12 changed files with 39 additions and 185 deletions

View File

@ -4,9 +4,8 @@ extern crate proc_macro;
use crate::proc_macro::TokenStream; use crate::proc_macro::TokenStream;
use quote::quote; use quote::quote;
use std::str::FromStr;
use syn::Data::{Enum, Struct}; 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)] #[proc_macro_derive(Node)]
pub fn node_derive(input: TokenStream) -> TokenStream { pub fn node_derive(input: TokenStream) -> TokenStream {
@ -155,120 +154,3 @@ fn impl_ref_node(ast: &DeriveInput) -> TokenStream {
}; };
gen.into() 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()
}

View File

@ -11,6 +11,7 @@ trace = ["nom-tracable/trace"]
[dependencies] [dependencies]
nom = "5.0.0" nom = "5.0.0"
nom_locate = "0.4.0" nom_locate = "0.4.0"
nom-both = {path = "../../nom-both/nom-both"}
nom-packrat = {path = "../../nom-packrat/nom-packrat"} nom-packrat = {path = "../../nom-packrat/nom-packrat"}
nom-recursive = {path = "../../nom-recursive/nom-recursive"} nom-recursive = {path = "../../nom-recursive/nom-recursive"}
nom-tracable = {path = "../../nom-tracable/nom-tracable"} nom-tracable = {path = "../../nom-tracable/nom-tracable"}

View File

@ -234,12 +234,12 @@ pub(crate) fn property_port_list(s: Span) -> IResult<Span, PropertyPortList> {
Ok((s, PropertyPortList { nodes: (a,) })) Ok((s, PropertyPortList { nodes: (a,) }))
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn property_port_item(s: Span) -> IResult<Span, PropertyPortItem> { pub(crate) fn property_port_item(s: Span) -> IResult<Span, PropertyPortItem> {
let (s, a) = many0(attribute_instance)(s)?; let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = opt(pair(local, opt(property_lvar_port_direction)))(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, d) = formal_port_identifier(s)?;
let (s, e) = many0(variable_dimension)(s)?; let (s, e) = many0(variable_dimension)(s)?;
let (s, f) = opt(pair(symbol("="), property_actual_arg))(s)?; let (s, f) = opt(pair(symbol("="), property_actual_arg))(s)?;
@ -724,12 +724,12 @@ pub(crate) fn sequence_port_list(s: Span) -> IResult<Span, SequencePortList> {
Ok((s, SequencePortList { nodes: (a,) })) Ok((s, SequencePortList { nodes: (a,) }))
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn sequence_port_item(s: Span) -> IResult<Span, SequencePortItem> { pub(crate) fn sequence_port_item(s: Span) -> IResult<Span, SequencePortItem> {
let (s, a) = many0(attribute_instance)(s)?; let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = opt(pair(local, opt(sequence_lvar_port_direction)))(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, d) = formal_port_identifier(s)?;
let (s, e) = many0(variable_dimension)(s)?; let (s, e) = many0(variable_dimension)(s)?;
let (s, f) = opt(pair(symbol("="), sequence_actual_arg))(s)?; let (s, f) = opt(pair(symbol("="), sequence_actual_arg))(s)?;

View File

@ -206,11 +206,11 @@ pub(crate) fn hierarchical_identifier_or_class_scope(
))(s) ))(s)
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn cover_point(s: Span) -> IResult<Span, CoverPoint> { pub(crate) fn cover_point(s: Span) -> IResult<Span, CoverPoint> {
let (s, a) = opt(triple( let (s, a) = opt(triple(
ambiguous_opt(data_type_or_implicit), both_opt(data_type_or_implicit),
cover_point_identifier, cover_point_identifier,
symbol(":"), symbol(":"),
))(s)?; ))(s)?;

View File

@ -30,12 +30,12 @@ pub(crate) fn function_body_declaration(s: Span) -> IResult<Span, FunctionBodyDe
))(s) ))(s)
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn function_body_declaration_without_port( pub(crate) fn function_body_declaration_without_port(
s: Span, s: Span,
) -> IResult<Span, FunctionBodyDeclaration> { ) -> IResult<Span, FunctionBodyDeclaration> {
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, b) = opt(interface_identifier_or_class_scope)(s)?;
let (s, c) = function_identifier(s)?; let (s, c) = function_identifier(s)?;
let (s, d) = symbol(";")(s)?; let (s, d) = symbol(";")(s)?;
@ -51,12 +51,12 @@ pub(crate) fn function_body_declaration_without_port(
)) ))
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn function_body_declaration_with_port( pub(crate) fn function_body_declaration_with_port(
s: Span, s: Span,
) -> IResult<Span, FunctionBodyDeclaration> { ) -> IResult<Span, FunctionBodyDeclaration> {
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, b) = opt(interface_identifier_or_class_scope)(s)?;
let (s, c) = function_identifier(s)?; let (s, c) = function_identifier(s)?;
let (s, d) = paren(opt(tf_port_list))(s)?; let (s, d) = paren(opt(tf_port_list))(s)?;

View File

@ -30,11 +30,11 @@ pub(crate) fn let_port_list(s: Span) -> IResult<Span, LetPortList> {
Ok((s, LetPortList { nodes: (a,) })) Ok((s, LetPortList { nodes: (a,) }))
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn let_port_item(s: Span) -> IResult<Span, LetPortItem> { pub(crate) fn let_port_item(s: Span) -> IResult<Span, LetPortItem> {
let (s, a) = many0(attribute_instance)(s)?; 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, c) = formal_port_identifier(s)?;
let (s, d) = many0(variable_dimension)(s)?; let (s, d) = many0(variable_dimension)(s)?;
let (s, e) = opt(pair(symbol("="), expression))(s)?; let (s, e) = opt(pair(symbol("="), expression))(s)?;

View File

@ -10,13 +10,13 @@ pub(crate) fn local_parameter_declaration(s: Span) -> IResult<Span, LocalParamet
))(s) ))(s)
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn local_parameter_declaration_param( pub(crate) fn local_parameter_declaration_param(
s: Span, s: Span,
) -> IResult<Span, LocalParameterDeclaration> { ) -> IResult<Span, LocalParameterDeclaration> {
let (s, a) = keyword("localparam")(s)?; 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)?; let (s, c) = list_of_param_assignments(s)?;
Ok(( Ok((
s, s,
@ -46,11 +46,11 @@ pub(crate) fn parameter_declaration(s: Span) -> IResult<Span, ParameterDeclarati
alt((parameter_declaration_param, parameter_declaration_type))(s) alt((parameter_declaration_param, parameter_declaration_type))(s)
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn parameter_declaration_param(s: Span) -> IResult<Span, ParameterDeclaration> { pub(crate) fn parameter_declaration_param(s: Span) -> IResult<Span, ParameterDeclaration> {
let (s, a) = keyword("parameter")(s)?; 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)?; let (s, c) = list_of_param_assignments(s)?;
Ok(( Ok((
s, s,

View File

@ -2,11 +2,11 @@ use crate::*;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn inout_declaration(s: Span) -> IResult<Span, InoutDeclaration> { pub(crate) fn inout_declaration(s: Span) -> IResult<Span, InoutDeclaration> {
let (s, a) = keyword("inout")(s)?; 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)?; let (s, c) = list_of_port_identifiers(s)?;
Ok((s, InoutDeclaration { nodes: (a, b, c) })) Ok((s, InoutDeclaration { nodes: (a, b, c) }))
} }
@ -16,11 +16,11 @@ pub(crate) fn input_declaration(s: Span) -> IResult<Span, InputDeclaration> {
alt((input_declaration_net, input_declaration_variable))(s) alt((input_declaration_net, input_declaration_variable))(s)
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn input_declaration_net(s: Span) -> IResult<Span, InputDeclaration> { pub(crate) fn input_declaration_net(s: Span) -> IResult<Span, InputDeclaration> {
let (s, a) = keyword("input")(s)?; 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)?; let (s, c) = list_of_port_identifiers(s)?;
Ok(( Ok((
s, s,
@ -28,11 +28,11 @@ pub(crate) fn input_declaration_net(s: Span) -> IResult<Span, InputDeclaration>
)) ))
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn input_declaration_variable(s: Span) -> IResult<Span, InputDeclaration> { pub(crate) fn input_declaration_variable(s: Span) -> IResult<Span, InputDeclaration> {
let (s, a) = keyword("input")(s)?; 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)?; let (s, c) = list_of_variable_identifiers(s)?;
Ok(( Ok((
s, s,
@ -45,11 +45,11 @@ pub(crate) fn output_declaration(s: Span) -> IResult<Span, OutputDeclaration> {
alt((output_declaration_net, output_declaration_variable))(s) alt((output_declaration_net, output_declaration_variable))(s)
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn output_declaration_net(s: Span) -> IResult<Span, OutputDeclaration> { pub(crate) fn output_declaration_net(s: Span) -> IResult<Span, OutputDeclaration> {
let (s, a) = keyword("output")(s)?; 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)?; let (s, c) = list_of_port_identifiers(s)?;
Ok(( Ok((
s, s,
@ -57,11 +57,11 @@ pub(crate) fn output_declaration_net(s: Span) -> IResult<Span, OutputDeclaration
)) ))
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn output_declaration_variable(s: Span) -> IResult<Span, OutputDeclaration> { pub(crate) fn output_declaration_variable(s: Span) -> IResult<Span, OutputDeclaration> {
let (s, a) = keyword("output")(s)?; 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)?; let (s, c) = list_of_variable_port_identifiers(s)?;
Ok(( Ok((
s, s,
@ -77,11 +77,11 @@ pub(crate) fn interface_port_declaration(s: Span) -> IResult<Span, InterfacePort
Ok((s, InterfacePortDeclaration { nodes: (a, b, c) })) Ok((s, InterfacePortDeclaration { nodes: (a, b, c) }))
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn ref_declaration(s: Span) -> IResult<Span, RefDeclaration> { pub(crate) fn ref_declaration(s: Span) -> IResult<Span, RefDeclaration> {
let (s, a) = keyword("ref")(s)?; 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)?; let (s, c) = list_of_variable_identifiers(s)?;
Ok((s, RefDeclaration { nodes: (a, b, c) })) Ok((s, RefDeclaration { nodes: (a, b, c) }))
} }

View File

@ -71,13 +71,13 @@ pub(crate) fn tf_port_list(s: Span) -> IResult<Span, TfPortList> {
Ok((s, TfPortList { nodes: (a,) })) Ok((s, TfPortList { nodes: (a,) }))
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn tf_port_item(s: Span) -> IResult<Span, TfPortItem> { pub(crate) fn tf_port_item(s: Span) -> IResult<Span, TfPortItem> {
let (s, a) = many0(attribute_instance)(s)?; let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = opt(tf_port_direction)(s)?; let (s, b) = opt(tf_port_direction)(s)?;
let (s, c) = opt(var)(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( let (s, e) = opt(triple(
port_identifier, port_identifier,
many0(variable_dimension), many0(variable_dimension),
@ -103,13 +103,13 @@ pub(crate) fn tf_port_direction(s: Span) -> IResult<Span, TfPortDirection> {
))(s) ))(s)
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn tf_port_declaration(s: Span) -> IResult<Span, TfPortDeclaration> { pub(crate) fn tf_port_declaration(s: Span) -> IResult<Span, TfPortDeclaration> {
let (s, a) = many0(attribute_instance)(s)?; let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = tf_port_direction(s)?; let (s, b) = tf_port_direction(s)?;
let (s, c) = opt(var)(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, e) = list_of_tf_variable_identifiers(s)?;
let (s, f) = symbol(";")(s)?; let (s, f) = symbol(";")(s)?;
Ok(( Ok((

View File

@ -18,13 +18,13 @@ pub(crate) fn data_declaration(s: Span) -> IResult<Span, DataDeclaration> {
))(s) ))(s)
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn data_declaration_variable(s: Span) -> IResult<Span, DataDeclaration> { pub(crate) fn data_declaration_variable(s: Span) -> IResult<Span, DataDeclaration> {
let (s, a) = opt(r#const)(s)?; let (s, a) = opt(r#const)(s)?;
let (s, b) = opt(var)(s)?; let (s, b) = opt(var)(s)?;
let (s, c) = opt(lifetime)(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, e) = list_of_variable_decl_assignments(s)?;
let (s, f) = symbol(";")(s)?; let (s, f) = symbol(";")(s)?;
Ok(( Ok((
@ -127,13 +127,13 @@ pub(crate) fn net_declaration(s: Span) -> IResult<Span, NetDeclaration> {
))(s) ))(s)
} }
#[parser(Ambiguous)] #[both_parser]
#[tracable_parser] #[tracable_parser]
pub(crate) fn net_declaration_net_type(s: Span) -> IResult<Span, NetDeclaration> { pub(crate) fn net_declaration_net_type(s: Span) -> IResult<Span, NetDeclaration> {
let (s, a) = net_type(s)?; let (s, a) = net_type(s)?;
let (s, b) = opt(strength)(s)?; let (s, b) = opt(strength)(s)?;
let (s, c) = opt(vector_scalar)(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, e) = opt(delay3)(s)?;
let (s, f) = list_of_net_decl_assignments(s)?; let (s, f) = list_of_net_decl_assignments(s)?;
let (s, g) = symbol(";")(s)?; let (s, g) = symbol(";")(s)?;

View File

@ -31,12 +31,12 @@ pub(crate) use nom::error::{make_error, ErrorKind};
pub(crate) use nom::multi::*; pub(crate) use nom::multi::*;
pub(crate) use nom::sequence::*; pub(crate) use nom::sequence::*;
pub(crate) use nom::{Err, IResult}; 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_packrat::{self, packrat_parser, HasExtraState};
pub(crate) use nom_recursive::{recursive_parser, HasRecursiveInfo, RecursiveInfo}; pub(crate) use nom_recursive::{recursive_parser, HasRecursiveInfo, RecursiveInfo};
pub(crate) use nom_tracable::tracable_parser; pub(crate) use nom_tracable::tracable_parser;
#[cfg(feature = "trace")] #[cfg(feature = "trace")]
pub(crate) use nom_tracable::{HasTracableInfo, TracableInfo}; pub(crate) use nom_tracable::{HasTracableInfo, TracableInfo};
pub(crate) use sv_parser_macros::*;
pub(crate) use sv_parser_syntaxtree::*; pub(crate) use sv_parser_syntaxtree::*;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -495,35 +495,6 @@ where
} }
} }
pub(crate) fn none<'a, O, F>(_f: F) -> impl Fn(Span<'a>) -> IResult<Span<'a>, Option<O>>
where
F: Fn(Span<'a>) -> IResult<Span<'a>, 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<Span<'a>, O>
where
F: Fn(Span<'a>) -> IResult<Span<'a>, O>,
G: Fn(Span<'a>) -> IResult<Span<'a>, 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<Span<'a>, O>
where
F: Fn(Span<'a>) -> IResult<Span<'a>, O>,
G: Fn(Span<'a>) -> IResult<Span<'a>, O>,
{
move |s: Span<'a>| {
let (s, x) = g(s)?;
Ok((s, x))
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[tracable_parser] #[tracable_parser]