From 96ec8b631989c13aa0cfef3c242e1774afaf3144 Mon Sep 17 00:00:00 2001 From: Shoofle Munroe Date: Wed, 7 Aug 2013 13:19:52 -0400 Subject: [PATCH] Woo! Made an indentation grammar! Kinda! --- ..._editors_with_contenteditable.article.html | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/articles/text_editors_with_contenteditable.article.html b/articles/text_editors_with_contenteditable.article.html index acaf687..dda0faa 100644 --- a/articles/text_editors_with_contenteditable.article.html +++ b/articles/text_editors_with_contenteditable.article.html @@ -174,4 +174,34 @@ identifier = letters:[A-Za-z]+ { return letters.join(""); } whitespace = [ \n\t]* +

So, it nearly killed me, but I managed to figure out how to make a parser (using pegjs) that actually parses indentation-based grammars! The basic way it works is that as it matches a line, it reads in the number of spaces before it. Using that, it figures out what indentation level it's at - then, as it's returning the line's payload, it puts the payload into the right code block. It's hacky and awful but I think I understand how it works. I'd rather move the logic into the block rule rather than the line rule, but that's pretty simple in theory. Here you go: +


+{ var code = [];
+  var indentations = [0];
+  var current_head = [code]; }
+
+b = line* { return code; }
+line = 
+  (spaces:" "* & 
+  { var level = spaces.length;
+    if (level > indentations[indentations.length-1]) {
+      indentations.push(level);
+      var new_block = [];
+      current_head[current_head.length-1].push(new_block);
+      current_head.push(new_block)
+    } else if (indentations.indexOf(level) == -1) {
+      return false; 
+    } else {
+      while (indentations[indentations.length-1] != level) {
+        indentations.pop()
+        current_head.pop()
+      }
+    }
+    return true; } 
+  { return spaces.length; })
+  payload:("ab" bs:"b"+ "a" { return "ab" + bs.join("") + "a"; }) 
+  "\n"
+  { current_head[current_head.length-1].push(payload);
+    return payload; }
+