From bbabf59505266c1038916ad65d3f856fb8959d25 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Tue, 20 May 2014 12:49:30 -0700 Subject: [PATCH] Start of an actual parser. --- recentrunes.js | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ test.js | 10 +++++++ 2 files changed, 88 insertions(+) diff --git a/recentrunes.js b/recentrunes.js index 27eb41a..6d78900 100644 --- a/recentrunes.js +++ b/recentrunes.js @@ -1,6 +1,24 @@ var rr = {}; rr.Literal_ = function(value) { + this.value_ = value; +}; + +rr.Literal_.prototype.match = function(input) { + if (input.slice(0, this.value_.length) == this.value_) { + return [this.value_.length, null]; + } else { + return null; + } +}; + +rr.Literal_.prototype.search = function(input) { + var index = input.indexOf(this.value_); + if (index == -1) { + return null; + } else { + return index; + } }; rr.Literal = function(value) { @@ -11,6 +29,7 @@ rr.Literal.cache = {}; rr.Ref_ = function(key) { + this.key_ = key; }; rr.Ref = function(key) { @@ -32,6 +51,8 @@ rr.EndOfLine.cache = new rr.EndOfLine_(); rr.MultiLineText_ = function() { }; +rr.MultiLineText_.prototype.minimize = true; + rr.MultiLineText = function() { return rr.MultiLineText.cache; }; @@ -39,6 +60,7 @@ rr.MultiLineText.cache = new rr.MultiLineText_(); rr.Or_ = function(options) { + this.options_ = options; }; rr.Or = function() { @@ -49,6 +71,17 @@ rr.Or = function() { rr.SingleLineText_ = function() { }; +rr.SingleLineText_.prototype.minimize = true; + +rr.SingleLineText_.prototype.match = function(input) { + var newLine = input.indexOf('\n'); + if (newLine == -1) { + return [input.length, document.createTextNode(input)]; + } else { + return [newLine, document.createTextNode(input.slice(0, newLine))]; + } +}; + rr.SingleLineText = function() { return rr.SingleLineText.cache; }; @@ -67,6 +100,8 @@ rr.StartOfLine.cache = new rr.StartOfLine_(); rr.WordText_ = function() { }; +rr.WordText_.prototype.minimize = true; + rr.WordText = function() { return rr.WordText.cache; }; @@ -74,6 +109,7 @@ rr.WordText.cache = new rr.WordText_(); rr.ZeroOrMore_ = function(key) { + this.key_ = key; }; rr.ZeroOrMore = function(key) { @@ -88,4 +124,46 @@ var RecentRunes = function(dictionary) { }; RecentRunes.prototype.parse = function(nodeType, input) { + var ret = document.createElement(nodeType); + var rules = this.dictionary_[nodeType]; + var inputIndex = 0; + var lastRuleMinimize = false; + for (var i = 0; i < rules.length; i++) { + var rule = rules[i]; + if (rule.minimize) { + if (lastRuleMinimize) { + // Two minimize rules in a row is ambiguous + return null; + } + lastRuleMinimize = true; + continue; + } + if (lastRuleMinimize) { + // Check if this rule can find a match in the string + var loc = rule.search(input.slice(inputIndex)); + if (loc == null) { + return null; + } + + // Check if the previous rule will match the interim data + var prevMatch = rules[i - 1].match( + input.slice(inputIndex, inputIndex + loc)); + if (!prevMatch) { + return null; + }; + inputIndex += prevMatch[0]; + if (prevMatch[1]) { + ret.appendChild(prevMatch[1]); + } + } + var match = rule.match(input.slice(inputIndex)); + if (!match) { + return null; + } + inputIndex += match[0]; + if (match[1]) { + ret.appendChild(match[1]); + } + }; + return [inputIndex, ret]; }; diff --git a/test.js b/test.js index e69de29..6b664d2 100644 --- a/test.js +++ b/test.js @@ -0,0 +1,10 @@ +test('Simple', function() { + expect(0); + var grammar = { + 'rule1': [rr.Literal('=== '), rr.SingleLineText(), rr.Literal(' ===')], + 'rule2': [rr.SingleLineText(), rr.Literal('=')], + }; + var parser = new RecentRunes(grammar); + console.log(parser.parse('rule1', '=== bar ===')); + console.log(parser.parse('rule2', 'foo=\nbar=')); +});