Repository: DmitrySoshnikov/regexp-tree
Pull request #68 (2017-04-26 09:45:28)

Fixing character group parsing with punctuation symbols
`/ ([.|,])/g` is now valid regexp

It is magic a little for me, so I just hope I will not break something with this fix :)


Patch:
diff --git a/src/parser/generated/regexp-tree.js b/src/parser/generated/regexp-tree.js
index 147180f..c44b509 100644
--- a/src/parser/generated/regexp-tree.js
+++ b/src/parser/generated/regexp-tree.js
@@ -339,6 +339,8 @@ const lexRules = [[/^#[^\n]+/, function() { /* skip comments */ }, ["x"]],
 [/^-/, function() { return 'DASH' }, ["class"]],
 [/^\//, function() { return 'CHAR' }, ["class"]],
 [/^#/, function() { return 'CHAR' }, ["class"]],
+[/^\|/, function() { return 'CHAR' }, ["class"]],
+[/^\./, function() { return 'CHAR' }, ["class"]],
 [/^\{/, function() { return 'CHAR' }, ["class"]],
 [/^\{\d+\}/, function() { return 'RANGE_EXACT' }, ],
 [/^\{\d+,\}/, function() { return 'RANGE_OPEN' }, ],
@@ -381,7 +383,7 @@ const lexRules = [[/^#[^\n]+/, function() { /* skip comments */ }, ["x"]],
 [/^[^*?+\[()]/, function() { return 'CHAR' }, ],
 [/^\[\^/, function() {  this.pushState('class'); return 'NEG_CLASS'  }, ],
 [/^\[/, function() {  this.pushState('class'); return 'L_BRACKET'  }, ]];
-const lexRulesByConditions = {"INITIAL":[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,26,27,28,29,30,31,32,33,37,38,39,40,41,42,43,44,45,46,47],"x":[0,1,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,26,27,28,29,30,31,32,33,37,38,39,40,41,42,43,44,45,46,47],"class":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47]};
+const lexRulesByConditions = {"INITIAL":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,28,29,30,31,32,33,34,35,39,40,41,42,43,44,45,46,47,48,49],"x":[0,1,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,28,29,30,31,32,33,34,35,39,40,41,42,43,44,45,46,47,48,49],"class":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49]};
 
 const EOF_TOKEN = {
   type: EOF,
diff --git a/src/parser/regexp.bnf b/src/parser/regexp.bnf
index fa53454..08dbea8 100644
--- a/src/parser/regexp.bnf
+++ b/src/parser/regexp.bnf
@@ -55,6 +55,8 @@ GROUP_NAME              ([\w$]|\\'u'[0-9a-fA-F]{4}|\\'u{'[0-9a-fA-F]{1,}'}')+
 <class>'-'               return 'DASH'
 <class>'/'               return 'CHAR'
 <class>'#'               return 'CHAR'
+<class>'|'               return 'CHAR'
+<class>'.'               return 'CHAR'
 
 <class>'{'               return 'CHAR'
 


Test patch:
diff --git a/src/parser/__tests__/parser-basic-test.js b/src/parser/__tests__/parser-basic-test.js
index 5d73ea3..d70f625 100644
--- a/src/parser/__tests__/parser-basic-test.js
+++ b/src/parser/__tests__/parser-basic-test.js
@@ -140,6 +140,163 @@ describe('basic', () => {
     });
   });
 
+  it('character class with punctuation symbols', () => {
+    expect(re('/[!"#$%&\'()*+,./:;<=>?@\^_`{|}~-]/')).toEqual({
+      type: 'RegExp',
+      body: {
+        type: 'CharacterClass',
+        expressions: [
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '!'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '"'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '#'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '$'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '%'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '&'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '\''
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '('
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: ')'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '*'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '+'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: ','
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '.'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '/'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: ':'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: ';'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '<'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '='
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '>'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '?'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '@'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '^'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '_'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '`'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '{'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '|'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '}'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '~'
+          },
+          {
+            type: 'Char',
+            kind: 'simple',
+            value: '-'
+          }
+        ]
+      },
+      flags: ''
+    });
+  });
+
   it('capturing group numbers', () => {
     expect(re('/(?:)(a)(?:)(?<name>b)/')).toEqual({
       type: 'RegExp',