about summary refs log tree commit diff stats
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/regex.js41
1 files changed, 27 insertions, 14 deletions
diff --git a/js/regex.js b/js/regex.js
index 14199af..86acf21 100644
--- a/js/regex.js
+++ b/js/regex.js
@@ -7,7 +7,8 @@ const tokenize = (pattern) => {
 
         if (char === '.' || char === '*' || char === '(' || char === ')' || char === '|') {
             tokens.push({
-                type: char
+                type: char,
+                value: char
             });
         } else if (char === '\\') { // Handle escaped characters
             i++;
@@ -40,10 +41,11 @@ const tokenize = (pattern) => {
 
 
 
+
 const parse = (tokens) => {
     let i = 0;
 
-    const parseExpression = () => {
+    const parseSequenceExpression = () => {
         const node = {
             type: 'sequence',
             elements: []
@@ -74,7 +76,7 @@ const parse = (tokens) => {
                 });
             } else if (token.type === '|') {
                 i++;
-                const right = parseExpression();
+                const right = parseSequenceExpression();
                 return {
                     type: 'alternation',
                     left: node,
@@ -82,9 +84,9 @@ const parse = (tokens) => {
                 };
             } else if (token.type === '(') {
                 i++;
-                node.elements.push(parseExpression());
+                node.elements.push(parseSequenceExpression());
             } else if (token.type === ')') {
-                break; // End of grouping
+                break; // End of a grouping
             }
 
             i++;
@@ -93,12 +95,12 @@ const parse = (tokens) => {
         return node;
     };
 
-    return parseExpression();
+    return parseSequenceExpression();
 };
 
 
 
-const match = (node, input) => {
+const evaluateMatch = (node) => (input) => {
     if (node.type === 'literal') {
         return input[0] === node.value ? input.slice(1) : null;
     }
@@ -108,7 +110,7 @@ const match = (node, input) => {
     if (node.type === 'star') {
         let remainder = input;
         while (remainder !== null) {
-            const next = match(node.element, remainder);
+            const next = evaluateMatch(node.element)(remainder);
             if (next === null) {
                 break;
             }
@@ -120,14 +122,14 @@ const match = (node, input) => {
         return node.value.includes(input[0]) ? input.slice(1) : null;
     }
     if (node.type === 'alternation') {
-        const remainderLeft = match(node.left, input);
-        const remainderRight = match(node.right, input);
+        const remainderLeft = evaluateMatch(node.left)(input);
+        const remainderRight = evaluateMatch(node.right)(input);
         return remainderLeft !== null ? remainderLeft : remainderRight;
     }
     if (node.type === 'sequence') {
         let remainder = input;
         for (const element of node.elements) {
-            remainder = match(element, remainder);
+            remainder = evaluateMatch(element)(remainder);
             if (remainder === null) {
                 return null;
             }
@@ -138,6 +140,17 @@ const match = (node, input) => {
 
 
 
+
+const assertEqual = (expected, actual, message) => {
+    if (expected !== actual) {
+        console.error(`FAIL: ${message}`);
+    } else {
+        console.log(`PASS: ${message}`);
+    }
+};
+
+
+
 const runTests = () => {
     const tests = [{
             pattern: "a.b*c",
@@ -212,11 +225,11 @@ const runTests = () => {
         }
     ];
 
-    tests.forEach(({pattern,input,expected}, index) => {
+    tests.forEach(({ pattern, input, expected }, index) => {
         const tokens = tokenize(pattern);
         const ast = parse(tokens);
-        const result = match(ast, input) !== null;
-        console.log(`Test ${index + 1}: ${result === expected ? 'PASS' : 'FAIL'}`);
+        const result = evaluateMatch(ast)(input) !== null;
+        assertEqual(expected, result, `Test ${index + 1}`);
     });
 };