From facb99e8bc22f85dcf0f68befb6d1d2dcb583037 Mon Sep 17 00:00:00 2001 From: Jeff Avallone Date: Wed, 26 Nov 2014 18:24:40 -0500 Subject: [PATCH] Beginning to add some functionality to the parser --- spec/parser/javascript_spec.js | 25 +++++++++++++++++-- src/js/main.js | 2 +- src/js/parser/javascript.js | 9 +++++++ .../grammar.peg} | 7 +++--- src/js/parser/javascript/regexp.js | 9 +++++++ src/js/parser/javascript/root.js | 25 +++++++++++++++++++ 6 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 src/js/parser/javascript.js rename src/js/parser/{javascript.peg => javascript/grammar.peg} (93%) create mode 100644 src/js/parser/javascript/regexp.js create mode 100644 src/js/parser/javascript/root.js diff --git a/spec/parser/javascript_spec.js b/spec/parser/javascript_spec.js index 1befbbc..b0620f4 100644 --- a/spec/parser/javascript_spec.js +++ b/spec/parser/javascript_spec.js @@ -1,7 +1,28 @@ -import parser from 'src/js/parser/javascript.peg'; +import parser from 'src/js/parser/javascript.js'; describe('parser/javascript.peg', function() { - pending(); + describe('regular expression literals', function() { + + describe('flags support', function() { + + it('handles the ignore case flag', function() { + expect(parser.parse('/test/i').flags().ignore_case).toEqual(true); + expect(parser.parse('/test/').flags().ignore_case).toEqual(false); + }); + + it('handles the global flag', function() { + expect(parser.parse('/test/g').flags().global).toEqual(true); + expect(parser.parse('/test/').flags().global).toEqual(false); + }); + + it('handles the multiline flag', function() { + expect(parser.parse('/test/m').flags().multiline).toEqual(true); + expect(parser.parse('/test/').flags().multiline).toEqual(false); + }); + + }); + + }); }); diff --git a/src/js/main.js b/src/js/main.js index ff636bc..fdfaec1 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -1,3 +1,3 @@ -import parser from './parser/javascript.peg'; +import parser from './parser/javascript.js'; window.parser = parser; diff --git a/src/js/parser/javascript.js b/src/js/parser/javascript.js new file mode 100644 index 0000000..fa20914 --- /dev/null +++ b/src/js/parser/javascript.js @@ -0,0 +1,9 @@ +import parser from './javascript/grammar.peg'; + +import Root from './javascript/root.js'; +import Regexp from './javascript/regexp.js'; + +parser.Parser.Root = Root; +parser.Parser.Regexp = Regexp; + +export default parser; diff --git a/src/js/parser/javascript.peg b/src/js/parser/javascript/grammar.peg similarity index 93% rename from src/js/parser/javascript.peg rename to src/js/parser/javascript/grammar.peg index a684d42..92ef7b1 100644 --- a/src/js/parser/javascript.peg +++ b/src/js/parser/javascript/grammar.peg @@ -1,8 +1,7 @@ grammar JavascriptRegexp - root <- regexp_literal / regexp - regexp_literal <- "/" regexp "/" [igm]* - regexp <- match ( "|" regexp )? - match <- anchor_start? ( ( subexp / charset / terminal ) repeat? )* anchor_end? + root <- ( ( "/" regexp "/" fl:[igm]* ) / regexp ) + regexp <- match ( "|" regexp )? + match <- anchor_start? ( ( subexp / charset / terminal ) repeat? )* anchor_end? anchor_start <- "^" anchor_end <- "$" repeat <- ( repeat_any / repeat_required / repeat_optional / repeat_spec ) repeat_greedy? diff --git a/src/js/parser/javascript/regexp.js b/src/js/parser/javascript/regexp.js new file mode 100644 index 0000000..a560227 --- /dev/null +++ b/src/js/parser/javascript/regexp.js @@ -0,0 +1,9 @@ +export default { + matches() { + if (this.elements[1].regexp) { + return [this.match].concat(this.elements[1].regexp.matches()); + } else { + return [this.match]; + } + } +}; diff --git a/src/js/parser/javascript/root.js b/src/js/parser/javascript/root.js new file mode 100644 index 0000000..a14847c --- /dev/null +++ b/src/js/parser/javascript/root.js @@ -0,0 +1,25 @@ +export default { + flags() { + var flags; + + if (this.fl) { + flags = this.fl.textValue; + } else { + flags = ''; + } + + return { + global: /g/.test(flags), + ignore_case: /i/.test(flags), + multiline: /m/.test(flags) + }; + }, + + expression() { + if (this.regexp) { + return this.regexp; + } else { + return this; + } + } +};