From 91ad7e33cd8be14fc68ca66970779d7e771d4b5e Mon Sep 17 00:00:00 2001 From: James Coglan Date: Tue, 13 Jun 2017 21:21:03 +0100 Subject: [PATCH] Replace the type annotation with an action for building string nodes. --- src/ast/string.js | 29 +++++++++++++++++++++++++++++ src/compiler.js | 13 ++++++++++--- src/compiler/grammar.js | 3 ++- src/compiler/string.js | 20 -------------------- src/meta_grammar.js | 5 ++--- src/meta_grammar.peg | 3 ++- 6 files changed, 45 insertions(+), 28 deletions(-) create mode 100644 src/ast/string.js delete mode 100644 src/compiler/string.js diff --git a/src/ast/string.js b/src/ast/string.js new file mode 100644 index 0000000..e1508d6 --- /dev/null +++ b/src/ast/string.js @@ -0,0 +1,29 @@ +'use strict'; + +var util = require('../util'); + +var String = function(text) { + this._text = text; + this._value = eval(text); +}; + +util.assign(String.prototype, { + toSexp: function() { + return ['string', this._value]; + }, + + compile: function(builder, address, action) { + var value = this._value, + length = value.length, + chunk = builder.chunk_(length); + + builder.if_(builder.stringMatch_(chunk, value), function(builder) { + var of = builder.offset_(); + builder.syntaxNode_(address, of, of + ' + ' + length, null, action); + }, function(builder) { + builder.failure_(address, this._text); + }, this); + } +}); + +module.exports = String; diff --git a/src/compiler.js b/src/compiler.js index 5fdb91c..bf1302c 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -17,8 +17,15 @@ var types = { Reference: require('./compiler/reference'), Repeat: require('./compiler/repeat'), Sequence: require('./compiler/sequence'), - SequencePart: require('./compiler/sequence_part'), - String: require('./compiler/string') + SequencePart: require('./compiler/sequence_part') +}; + +var String = require('./ast/string'); + +var actions = { + string: function(text, a, b, elements) { + return new String(text.substring(a, b)); + } }; var Compiler = function(grammarText, builder) { @@ -30,7 +37,7 @@ util.assign(Compiler.prototype, { parseTree: function() { if (this._tree) return this._tree; - this._tree = metagrammar.parse(this._grammarText, {types: types}); + this._tree = metagrammar.parse(this._grammarText, {types: types, actions: actions}); if (this._tree) return this._tree; var message = metagrammar.formatError(metagrammar.Parser.lastError); diff --git a/src/compiler/grammar.js b/src/compiler/grammar.js index ee1216d..c9654d9 100644 --- a/src/compiler/grammar.js +++ b/src/compiler/grammar.js @@ -16,7 +16,8 @@ module.exports = { compile: function(builder) { var scan = function(node, callback, context) { callback.call(context, node); - node.forEach(function(child) { scan(child, callback, context) }); + if (node.forEach) + node.forEach(function(child) { scan(child, callback, context) }); }; builder.package_(this.grammarName(), function(builder) { diff --git a/src/compiler/string.js b/src/compiler/string.js deleted file mode 100644 index baff8f1..0000000 --- a/src/compiler/string.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -module.exports = { - toSexp: function() { - return ['string', eval(this.text)]; - }, - - compile: function(builder, address, action) { - var string = eval(this.text), - length = string.length, - chunk = builder.chunk_(length); - - builder.if_(builder.stringMatch_(chunk, string), function(builder) { - var of = builder.offset_(); - builder.syntaxNode_(address, of, of + ' + ' + length, null, action); - }, function(builder) { - builder.failure_(address, this.text); - }, this); - } -}; diff --git a/src/meta_grammar.js b/src/meta_grammar.js index ca75e2b..115a721 100644 --- a/src/meta_grammar.js +++ b/src/meta_grammar.js @@ -1837,7 +1837,7 @@ if (elements0 === null) { address0 = FAILURE; } else { - address0 = new TreeNode(this._input.substring(index2, this._offset), index2, elements0); + address0 = this._actions.string(this._input, index2, this._offset, elements0); this._offset = this._offset; } if (address0 === FAILURE) { @@ -1989,14 +1989,13 @@ if (elements3 === null) { address0 = FAILURE; } else { - address0 = new TreeNode(this._input.substring(index6, this._offset), index6, elements3); + address0 = this._actions.string(this._input, index6, this._offset, elements3); this._offset = this._offset; } if (address0 === FAILURE) { this._offset = index1; } } - extend(address0, this._types.String); this._cache._string_expression[index0] = [address0, this._offset]; return address0; }, diff --git a/src/meta_grammar.peg b/src/meta_grammar.peg index d2c92e7..b211af9 100644 --- a/src/meta_grammar.peg +++ b/src/meta_grammar.peg @@ -57,7 +57,8 @@ predicated_atom <- predicate:("&" / "!") atom reference_expression <- identifier !assignment -string_expression <- ('"' ("\\" . / [^"])* '"' / "'" ("\\" . / [^'])* "'") +string_expression <- '"' ("\\" . / [^"])* '"' %string + / "'" ("\\" . / [^'])* "'" %string ci_string_expression <- "`" ("\\" . / [^`])* "`"