Mirror: The magical sticky regex-based parser generator 🧙

Remove type fields from AST output

Changed files
+8 -46
src
+1 -3
src/codegen.js
··· 95 95 }; 96 96 97 97 const astChild = (ast, depth, opts) => 98 - ast.type === 'expression' 99 - ? astExpression(ast, depth, opts) 100 - : astGroup(ast, depth, opts); 98 + ast.expression ? astExpression(ast, depth, opts) : astGroup(ast, depth, opts); 101 99 102 100 const astRepeating = (ast, depth, opts) => { 103 101 const label = `loop_${depth}`;
+1 -14
src/parser.js
··· 4 4 5 5 const sequenceStack = []; 6 6 const rootSequence = { 7 - type: 'sequence', 8 7 sequence: [], 9 - alternation: null, 10 8 }; 11 9 12 10 let currentGroup = null; ··· 15 13 16 14 while (stackIndex < quasis.length + expressions.length) { 17 15 if (stackIndex % 2 !== 0) { 18 - const expression = expressions[stackIndex++ >> 1]; 19 - 20 16 currentSequence.sequence.push({ 21 - type: 'expression', 22 - expression, 23 - quantifier: null, 17 + expression: expressions[stackIndex++ >> 1], 24 18 }); 25 19 } 26 20 ··· 32 26 continue; 33 27 } else if (char === '|' && currentSequence.sequence.length > 0) { 34 28 currentSequence = currentSequence.alternation = { 35 - type: 'sequence', 36 29 sequence: [], 37 - alternation: null, 38 30 }; 39 31 40 32 continue; ··· 44 36 if (currentSequence) continue; 45 37 } else if (char === '(') { 46 38 currentGroup = { 47 - type: 'group', 48 39 sequence: { 49 - type: 'sequence', 50 40 sequence: [], 51 - alternation: null, 52 41 }, 53 - capture: null, 54 - quantifier: null, 55 42 }; 56 43 57 44 sequenceStack.push(currentSequence);
+6 -29
src/parser.test.js
··· 4 4 5 5 it('supports parsing expressions', () => { 6 6 expect(parseTag`${1}`).toEqual({ 7 - type: 'sequence', 8 7 sequence: [ 9 8 { 10 - type: 'expression', 11 9 expression: 1, 12 - quantifier: null, 10 + quantifier: undefined, 13 11 }, 14 12 ], 15 - alternation: null, 13 + alternation: undefined, 16 14 }); 17 15 }); 18 16 ··· 20 18 let ast; 21 19 22 20 ast = parseTag`${1}?`; 23 - expect(ast).toHaveProperty('sequence.0.type', 'expression'); 24 21 expect(ast).toHaveProperty('sequence.0.quantifier', '?'); 25 22 26 23 ast = parseTag`${1}+`; 27 - expect(ast).toHaveProperty('sequence.0.type', 'expression'); 28 24 expect(ast).toHaveProperty('sequence.0.quantifier', '+'); 29 25 30 26 ast = parseTag`${1}*`; 31 - expect(ast).toHaveProperty('sequence.0.type', 'expression'); 32 27 expect(ast).toHaveProperty('sequence.0.quantifier', '*'); 33 28 }); 34 29 ··· 37 32 38 33 ast = parseTag`${1} | ${2}`; 39 34 expect(ast).toHaveProperty('sequence.length', 1); 40 - expect(ast).toHaveProperty('sequence.0.type', 'expression'); 41 35 expect(ast).toHaveProperty('sequence.0.expression', 1); 42 - expect(ast).toHaveProperty('alternation.type', 'sequence'); 43 36 expect(ast).toHaveProperty('alternation.sequence.0.expression', 2); 44 37 45 38 ast = parseTag`${1}? | ${2}?`; ··· 51 44 52 45 ast = parseTag`(${1} ${2})`; 53 46 expect(ast).toHaveProperty('sequence.length', 1); 54 - expect(ast).toHaveProperty('sequence.0.type', 'group'); 55 47 expect(ast).toHaveProperty('sequence.0.sequence.sequence.length', 2); 56 48 expect(ast).toHaveProperty('sequence.0.sequence.sequence.0.expression', 1); 57 49 expect(ast).toHaveProperty('sequence.0.sequence.sequence.1.expression', 2); 58 50 59 51 ast = parseTag`(${1} ${2}?)?`; 60 52 expect(ast).toHaveProperty('sequence.length', 1); 61 - expect(ast).toHaveProperty('sequence.0.type', 'group'); 62 53 expect(ast).toHaveProperty('sequence.0.quantifier', '?'); 63 - expect(ast).toHaveProperty('sequence.0.sequence.sequence.0.quantifier', null); 54 + expect(ast).toHaveProperty( 55 + 'sequence.0.sequence.sequence.0.quantifier', 56 + undefined 57 + ); 64 58 }); 65 59 66 60 it('supports non-capturing groups', () => { 67 61 const ast = parseTag`(?: ${1})`; 68 62 expect(ast).toHaveProperty('sequence.length', 1); 69 - expect(ast).toHaveProperty('sequence.0.type', 'group'); 70 63 expect(ast).toHaveProperty('sequence.0.capture', ':'); 71 64 expect(ast).toHaveProperty('sequence.0.sequence.sequence.length', 1); 72 65 }); ··· 74 67 it('supports positive lookahead groups', () => { 75 68 const ast = parseTag`(?= ${1})`; 76 69 expect(ast).toHaveProperty('sequence.length', 1); 77 - expect(ast).toHaveProperty('sequence.0.type', 'group'); 78 70 expect(ast).toHaveProperty('sequence.0.capture', '='); 79 71 expect(ast).toHaveProperty('sequence.0.sequence.sequence.length', 1); 80 72 }); ··· 82 74 it('supports negative lookahead groups', () => { 83 75 const ast = parseTag`(?! ${1})`; 84 76 expect(ast).toHaveProperty('sequence.length', 1); 85 - expect(ast).toHaveProperty('sequence.0.type', 'group'); 86 77 expect(ast).toHaveProperty('sequence.0.capture', '!'); 87 78 expect(ast).toHaveProperty('sequence.0.sequence.sequence.length', 1); 88 79 }); ··· 90 81 it('supports groups with alternates', () => { 91 82 expect(parseTag`(${1} | ${2}) ${3}`).toMatchInlineSnapshot(` 92 83 Object { 93 - "alternation": null, 94 84 "sequence": Array [ 95 85 Object { 96 - "capture": null, 97 - "quantifier": null, 98 86 "sequence": Object { 99 87 "alternation": Object { 100 - "alternation": null, 101 88 "sequence": Array [ 102 89 Object { 103 90 "expression": 2, 104 - "quantifier": null, 105 - "type": "expression", 106 91 }, 107 92 ], 108 - "type": "sequence", 109 93 }, 110 94 "sequence": Array [ 111 95 Object { 112 96 "expression": 1, 113 - "quantifier": null, 114 - "type": "expression", 115 97 }, 116 98 ], 117 - "type": "sequence", 118 99 }, 119 - "type": "group", 120 100 }, 121 101 Object { 122 102 "expression": 3, 123 - "quantifier": null, 124 - "type": "expression", 125 103 }, 126 104 ], 127 - "type": "sequence", 128 105 } 129 106 `); 130 107 });