aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/mbe_parser.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-04-25 19:59:34 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-04-25 19:59:34 +0100
commit42c4e0f378faeabd425392d4a7a7839bd7e8ac2f (patch)
treef48081403383b7a00a3c297b2ff24a7c11ddd07e /crates/ra_mbe/src/mbe_parser.rs
parent5bbd9f43cc217a44445fde91b4b53ca85d78cd92 (diff)
parent1908819bf6432016527f4bd3b0f22500b85cab5f (diff)
Merge #1209
1209: Bugs fixes And Improvements of MBE r=matklad a=edwin0cheng This PR fixed / improve followings things: * Add `token` `$repeat` separator support: Previously $repeat only support single punct separator. * Fixed a bug which expand infinite pattern, see `test_match_group_in_group` * Correctly handle +,*,? case of $repeat patterns * Increase the limit of $repeat patterns (128 => 65536), personally i think we could remove this limit as we seem to fix all major loop bugs * **Re-enable tt matcher** * Better meta item parsing. * Add related tests and add some real world test cases. * Add more debug information. Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_mbe/src/mbe_parser.rs')
-rw-r--r--crates/ra_mbe/src/mbe_parser.rs40
1 files changed, 27 insertions, 13 deletions
diff --git a/crates/ra_mbe/src/mbe_parser.rs b/crates/ra_mbe/src/mbe_parser.rs
index 0710062d9..c7ab463e2 100644
--- a/crates/ra_mbe/src/mbe_parser.rs
+++ b/crates/ra_mbe/src/mbe_parser.rs
@@ -74,18 +74,11 @@ fn parse_var(p: &mut TtCursor, transcriber: bool) -> Result<crate::Var, ParseErr
74 Ok(crate::Var { text, kind }) 74 Ok(crate::Var { text, kind })
75} 75}
76 76
77fn parse_repeat(p: &mut TtCursor, transcriber: bool) -> Result<crate::Repeat, ParseError> { 77fn mk_repeat(
78 let subtree = p.eat_subtree().unwrap(); 78 rep: char,
79 let mut subtree = parse_subtree(subtree, transcriber)?; 79 subtree: crate::Subtree,
80 subtree.delimiter = crate::Delimiter::None; 80 separator: Option<crate::Separator>,
81 let sep = p.eat_punct().ok_or(ParseError::Expected(String::from("separator")))?; 81) -> Result<crate::Repeat, ParseError> {
82 let (separator, rep) = match sep.char {
83 '*' | '+' | '?' => (None, sep.char),
84 char => {
85 (Some(char), p.eat_punct().ok_or(ParseError::Expected(String::from("separator")))?.char)
86 }
87 };
88
89 let kind = match rep { 82 let kind = match rep {
90 '*' => crate::RepeatKind::ZeroOrMore, 83 '*' => crate::RepeatKind::ZeroOrMore,
91 '+' => crate::RepeatKind::OneOrMore, 84 '+' => crate::RepeatKind::OneOrMore,
@@ -95,6 +88,27 @@ fn parse_repeat(p: &mut TtCursor, transcriber: bool) -> Result<crate::Repeat, Pa
95 Ok(crate::Repeat { subtree, kind, separator }) 88 Ok(crate::Repeat { subtree, kind, separator })
96} 89}
97 90
91fn parse_repeat(p: &mut TtCursor, transcriber: bool) -> Result<crate::Repeat, ParseError> {
92 let subtree = p.eat_subtree().unwrap();
93 let mut subtree = parse_subtree(subtree, transcriber)?;
94 subtree.delimiter = crate::Delimiter::None;
95
96 if let Some(rep) = p.at_punct() {
97 match rep.char {
98 '*' | '+' | '?' => {
99 p.bump();
100 return mk_repeat(rep.char, subtree, None);
101 }
102 _ => {}
103 }
104 }
105
106 let sep = p.eat_seperator().ok_or(ParseError::Expected(String::from("separator")))?;
107 let rep = p.eat_punct().ok_or(ParseError::Expected(String::from("repeat")))?;
108
109 mk_repeat(rep.char, subtree, Some(sep))
110}
111
98#[cfg(test)] 112#[cfg(test)]
99mod tests { 113mod tests {
100 use ra_syntax::{ast, AstNode}; 114 use ra_syntax::{ast, AstNode};
@@ -109,7 +123,7 @@ mod tests {
109 is_valid("($i:ident) => ()"); 123 is_valid("($i:ident) => ()");
110 expect_err("$i:ident => ()", "subtree"); 124 expect_err("$i:ident => ()", "subtree");
111 expect_err("($i:ident) ()", "`=`"); 125 expect_err("($i:ident) ()", "`=`");
112 expect_err("($($i:ident)_) => ()", "separator"); 126 expect_err("($($i:ident)_) => ()", "repeat");
113 } 127 }
114 128
115 fn expect_err(macro_body: &str, expected: &str) { 129 fn expect_err(macro_body: &str, expected: &str) {