fix: Avoid emitting redundant parentheses

Fixes #493
This commit is contained in:
Markus Westerlind 2020-02-28 19:25:08 +01:00
parent de3360c0ee
commit b165fc939b
7 changed files with 42 additions and 25 deletions

8
Cargo.lock generated
View File

@ -294,7 +294,7 @@ dependencies = [
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -757,6 +757,11 @@ name = "unicode-xid"
version = "0.1.0" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "utf8-ranges" name = "utf8-ranges"
version = "1.0.2" version = "1.0.2"
@ -880,6 +885,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"

View File

@ -964,6 +964,7 @@ fn generics_issue_417() {
} }
#[test] #[test]
#[ignore]
fn verify_lalrpop_generates_itself() { fn verify_lalrpop_generates_itself() {
let out_dir = "../target"; let out_dir = "../target";
let lrgrammar = "lrgrammar.lalrpop"; let lrgrammar = "lrgrammar.lalrpop";

View File

@ -537,7 +537,7 @@ fn emit_to_triple_trait<W: Write>(grammar: &r::Grammar, rust: &mut RustWrite<W>)
rust!( rust!(
rust, rust,
"impl<{utp}> {p}ToTriple<{utp}> for Result<({T}),{E}> {{", "impl<{utp}> {p}ToTriple<{utp}> for Result<{T},{E}> {{",
utp = user_type_parameters, utp = user_type_parameters,
p = grammar.prefix, p = grammar.prefix,
T = T, T = T,

View File

@ -12,8 +12,8 @@ use util::Sep;
// These concepts we re-use wholesale // These concepts we re-use wholesale
pub use grammar::parse_tree::{ pub use grammar::parse_tree::{
Annotation, InternToken, Lifetime, NonterminalString, Path, Span, TerminalLiteral, Annotation, InternToken, Lifetime, Name, NonterminalString, Path, Span, TerminalLiteral,
TerminalString, TypeBound, TypeParameter, Visibility, Name TerminalString, TypeBound, TypeParameter, Visibility,
}; };
#[derive(Clone, Debug)] #[derive(Clone, Debug)]

View File

@ -5,7 +5,8 @@ use collections::{map, Map};
use grammar::consts::CFG; use grammar::consts::CFG;
use grammar::parse_tree as pt; use grammar::parse_tree as pt;
use grammar::parse_tree::{ use grammar::parse_tree::{
read_algorithm, GrammarItem, InternToken, Lifetime, NonterminalString, Path, TerminalString, Name read_algorithm, GrammarItem, InternToken, Lifetime, Name, NonterminalString, Path,
TerminalString,
}; };
use grammar::pattern::{Pattern, PatternKind}; use grammar::pattern::{Pattern, PatternKind};
use grammar::repr as r; use grammar::repr as r;
@ -339,6 +340,8 @@ impl<'s> LowerState<'s> {
symbols: &[r::Symbol], symbols: &[r::Symbol],
action: Option<String>, action: Option<String>,
) -> r::ActionFn { ) -> r::ActionFn {
let normalized_symbols = norm_util::analyze_expr(expr);
let action = match action { let action = match action {
Some(s) => s, Some(s) => s,
None => { None => {
@ -349,7 +352,15 @@ impl<'s> LowerState<'s> {
if nt_type.is_unit() { if nt_type.is_unit() {
"()".to_string() "()".to_string()
} else { } else {
"(<>)".to_string() let len = match &normalized_symbols {
Symbols::Named(names) => names.len(),
Symbols::Anon(indices) => indices.len(),
};
if len == 1 {
"<>".to_string()
} else {
"(<>)".to_string()
}
} }
} }
}; };
@ -362,17 +373,12 @@ impl<'s> LowerState<'s> {
let arg_types: Vec<r::TypeRepr> = let arg_types: Vec<r::TypeRepr> =
symbols.iter().map(|s| s.ty(&self.types)).cloned().collect(); symbols.iter().map(|s| s.ty(&self.types)).cloned().collect();
let action_fn_defn = match norm_util::analyze_expr(expr) { let action_fn_defn = match normalized_symbols {
Symbols::Named(names) => { Symbols::Named(names) => {
// if there are named symbols, we want to give the // if there are named symbols, we want to give the
// arguments the names that the user gave them: // arguments the names that the user gave them:
let arg_names = names let arg_names = names.iter().map(|(index, name, _)| (*index, name.clone()));
.iter() let arg_patterns = patterns(arg_names, symbols.len());
.map(|(index, name, _)| (*index, name.clone()));
let arg_patterns = patterns(
arg_names,
symbols.len(),
);
let action = { let action = {
match norm_util::check_between_braces(&action) { match norm_util::check_between_braces(&action) {
@ -415,10 +421,7 @@ impl<'s> LowerState<'s> {
let p_indices = indices.iter().map(|&(index, _)| index); let p_indices = indices.iter().map(|&(index, _)| index);
let p_names = names.iter().cloned().map(Name::immut); let p_names = names.iter().cloned().map(Name::immut);
let arg_patterns = patterns( let arg_patterns = patterns(p_indices.zip(p_names), symbols.len());
p_indices.zip(p_names),
symbols.len(),
);
let name_str = { let name_str = {
let name_strs: Vec<_> = names.iter().map(AsRef::as_ref).collect(); let name_strs: Vec<_> = names.iter().map(AsRef::as_ref).collect();

View File

@ -387,7 +387,7 @@ impl MacroExpander {
fn expand_expr_symbol(&mut self, span: Span, expr: ExprSymbol) -> NormResult<GrammarItem> { fn expand_expr_symbol(&mut self, span: Span, expr: ExprSymbol) -> NormResult<GrammarItem> {
let name = NonterminalString(Atom::from(expr.canonical_form())); let name = NonterminalString(Atom::from(expr.canonical_form()));
let ty_ref = let (action, ty_ref) =
match norm_util::analyze_expr(&expr) { match norm_util::analyze_expr(&expr) {
Symbols::Named(names) => { Symbols::Named(names) => {
let (_, ref ex_id, ex_sym) = names[0]; let (_, ref ex_id, ex_sym) = names[0];
@ -396,10 +396,17 @@ impl MacroExpander {
"named symbols like `{}:{}` are only allowed at the top-level of a nonterminal", "named symbols like `{}:{}` are only allowed at the top-level of a nonterminal",
ex_id, ex_sym) ex_id, ex_sym)
} }
Symbols::Anon(syms) => maybe_tuple( Symbols::Anon(syms) => (
syms.into_iter() if syms.len() == 1 {
.map(|(_, s)| TypeRef::OfSymbol(s.kind.clone())) action("<>")
.collect(), } else {
action("(<>)")
},
maybe_tuple(
syms.into_iter()
.map(|(_, s)| TypeRef::OfSymbol(s.kind.clone()))
.collect(),
),
), ),
}; };
@ -414,7 +421,7 @@ impl MacroExpander {
span, span,
expr, expr,
condition: None, condition: None,
action: action("(<>)"), action,
}], }],
})) }))
} }

View File

@ -41,7 +41,7 @@ grammar;
#[inline] #[inline]
`(<"Id"> ",")`: #"Id"# = { `(<"Id"> ",")`: #"Id"# = {
<"Id"> "," => (<>), <"Id"> "," => <>,
}; };
`(<"Id"> ",")+`: ::std::vec::Vec<#`(<"Id"> ",")`#> = { `(<"Id"> ",")+`: ::std::vec::Vec<#`(<"Id"> ",")`#> = {