diff --git a/src/syntax/def.lalrpop b/src/syntax/def.lalrpop index bbc6809..4a82e3f 100644 --- a/src/syntax/def.lalrpop +++ b/src/syntax/def.lalrpop @@ -785,7 +785,6 @@ pub Control: LogicLine = { ) .max() .unwrap(); - let mut cases_res = Vec::with_capacity(case_num_max + 1); // 用于填充填充case的行, 如果有追加在末尾的行则将其封装并替换填充 let mut fill_line = append @@ -841,6 +840,9 @@ pub Control: LogicLine = { catch_lines.push(Expand(out_block).into()) } + let mut cases_res = Vec::with_capacity(case_num_max + 1); + let mut cases_res_isline = vec![false; case_num_max + 1]; + let mut next_ignored_num = 0; for (mut nums, mut expand) in cases { if let Some(append) = &append { @@ -849,12 +851,22 @@ pub Control: LogicLine = { if nums.is_empty() { nums.push(next_ignored_num) } for num in nums { for _ in cases_res.len()..=num { - cases_res.push(fill_line.clone()) + cases_res.push(LogicLine::Ignore); } cases_res[num] = expand.clone().into(); + cases_res_isline[num] = true; next_ignored_num = num + 1; } } + // 将填充行填入填充case + let mut iter = cases_res_isline.into_iter().enumerate().peekable(); + while let Some((idx, is_line)) = iter.next() { + if is_line { continue } + match iter.peek() { + Some((_, true)) => cases_res[idx] = fill_line.clone(), + _ => (), + } + } debug_assert_eq!(cases_res.len(), case_num_max + 1); debug_assert_eq!(cases_res.len(), cases_res.capacity()); diff --git a/src/syntax/tests.rs b/src/syntax/tests.rs index e9ed7ac..1aa4a7d 100644 --- a/src/syntax/tests.rs +++ b/src/syntax/tests.rs @@ -3686,3 +3686,33 @@ fn switch_ignored_id_test() { "#).unwrap(), ); } + +#[test] +fn switch_append_tail_once_test() { + let parser = TopLevelParser::new(); + + // switch填充行仅最后一个进行填充 + + assert_eq!( + parse!(parser, r#" + switch x { + break; + case 6: + foo; + case 3: + bar; + } + "#).unwrap(), + parse!(parser, r#" + select x { + print; # ignore + print; + { break; } # switch的封装以限制作用域 + { bar; break; } + print; + { break; } + { foo; break; } + } + "#).unwrap(), + ); +}