summaryrefslogtreecommitdiff
path: root/src/parsing.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-05-02 09:07:38 +0200
committerLaurenz <laurmaedje@gmail.com>2019-05-02 09:07:38 +0200
commitbc78974fd2b03d195735f119db026bd4cd36f1c7 (patch)
treec198f4d153ede5f8b8919abc08e698eecd3ff7ce /src/parsing.rs
parent37c336063ba77d27b65d876f0161855517a6efb7 (diff)
Ignore escaped brackets for body measure 🐥
Diffstat (limited to 'src/parsing.rs')
-rw-r--r--src/parsing.rs70
1 files changed, 42 insertions, 28 deletions
diff --git a/src/parsing.rs b/src/parsing.rs
index 85949e57..924c3dde 100644
--- a/src/parsing.rs
+++ b/src/parsing.rs
@@ -504,16 +504,22 @@ impl<'s> Parser<'s> {
}
}
-/// Find the index of the first unbalanced closing bracket.
+/// Find the index of the first unbalanced (unescaped) closing bracket.
fn find_closing_bracket(src: &str) -> Option<usize> {
let mut parens = 0;
+ let mut escaped = false;
for (index, c) in src.char_indices() {
match c {
- ']' if parens == 0 => return Some(index),
- '[' => parens += 1,
- ']' => parens -= 1,
+ '\\' => {
+ escaped = !escaped;
+ continue;
+ },
+ ']' if !escaped && parens == 0 => return Some(index),
+ '[' if !escaped => parens += 1,
+ ']' if !escaped => parens -= 1,
_ => {},
}
+ escaped = false;
}
None
}
@@ -856,45 +862,53 @@ mod parse_tests {
T("of"), S, T("a"), S, T("function"), S, T("invocation.")
]);
test_scoped(&scope, "[func][Hello][modifier][Here][end]", tree! [
- F(func! {
- name => "func",
- body => tree! [ T("Hello") ],
- }),
- F(func! {
- name => "modifier",
- body => tree! [ T("Here") ],
- }),
- F(func! {
- name => "end",
- body => None,
- }),
- ]);
- test_scoped(&scope, "[func][]", tree! [
- F(func! {
- name => "func",
- body => tree! [],
- })
+ F(func! { name => "func", body => tree! [ T("Hello") ] }),
+ F(func! { name => "modifier", body => tree! [ T("Here") ] }),
+ F(func! { name => "end", body => None }),
]);
+ test_scoped(&scope, "[func][]", tree! [ F(func! { name => "func", body => tree! [] }) ]);
test_scoped(&scope, "[modifier][[func][call]] outside", tree! [
F(func! {
name => "modifier",
- body => tree! [
- F(func! {
- name => "func",
- body => tree! [ T("call") ],
- }),
- ],
+ body => tree! [ F(func! { name => "func", body => tree! [ T("call") ] }) ],
}),
S, T("outside")
]);
}
+ /// Test if escaped, but unbalanced parens are correctly parsed.
+ #[test]
+ fn parse_unbalanced_body_parens() {
+ let mut scope = Scope::new();
+ scope.add::<TreeFn>("code");
+
+ test_scoped(&scope, r"My [code][Close \]] end", tree! [
+ T("My"), S, F(func! {
+ name => "code",
+ body => tree! [ T("Close"), S, T("]") ]
+ }), S, T("end")
+ ]);
+ test_scoped(&scope, r"My [code][\[ Open] end", tree! [
+ T("My"), S, F(func! {
+ name => "code",
+ body => tree! [ T("["), S, T("Open") ]
+ }), S, T("end")
+ ]);
+ test_scoped(&scope, r"My [code][Open \] and \[ close]end", tree! [
+ T("My"), S, F(func! {
+ name => "code",
+ body => tree! [ T("Open"), S, T("]"), S, T("and"), S, T("["), S, T("close") ]
+ }), T("end")
+ ]);
+ }
+
/// Tests if the parser handles non-ASCII stuff correctly.
#[test]
fn parse_unicode() {
let mut scope = Scope::new();
scope.add::<BodylessFn>("func");
scope.add::<TreeFn>("bold");
+
test_scoped(&scope, "[func] ⺐.", tree! [
F(func! {
name => "func",