diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-25 19:59:34 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-25 19:59:34 +0100 |
commit | 42c4e0f378faeabd425392d4a7a7839bd7e8ac2f (patch) | |
tree | f48081403383b7a00a3c297b2ff24a7c11ddd07e /crates/ra_mbe/src/mbe_parser.rs | |
parent | 5bbd9f43cc217a44445fde91b4b53ca85d78cd92 (diff) | |
parent | 1908819bf6432016527f4bd3b0f22500b85cab5f (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.rs | 40 |
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 | ||
77 | fn parse_repeat(p: &mut TtCursor, transcriber: bool) -> Result<crate::Repeat, ParseError> { | 77 | fn 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 | ||
91 | fn 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)] |
99 | mod tests { | 113 | mod 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) { |