瀏覽代碼

HUE-9370 [frontend] Add parser generation based on structure.json file definition

Johan Ahlen 5 年之前
父節點
當前提交
8ce1d058c3
共有 1 個文件被更改,包括 88 次插入53 次删除
  1. 88 53
      tools/jison/generateParsers.js

+ 88 - 53
tools/jison/generateParsers.js

@@ -234,42 +234,70 @@ const listDir = folder =>
     });
   });
 
+const addParserDefinition = (sources, dialect, autocomplete, lexer) => {
+  const parserName = dialect + (autocomplete ? 'AutocompleteParser' : 'SyntaxParser');
+
+  const parserDefinition = {
+    sources: sources,
+    lexer: 'sql/' + dialect + '/' + lexer,
+    target: 'sql/' + dialect + '/' + parserName + '.jison',
+    sqlParser: autocomplete ? 'AUTOCOMPLETE' : 'SYNTAX',
+    outputFolder: OUTPUT_FOLDER + 'sql/' + dialect + '/',
+    afterParse: contents =>
+      new Promise(resolve => {
+        resolve(
+          LICENSE +
+            contents
+              .replace(
+                'var ' + parserName + ' = ',
+                "import SqlParseSupport from 'parse/sql/" +
+                  dialect +
+                  "/sqlParseSupport';\n\nvar " +
+                  parserName +
+                  ' = '
+              )
+              .replace(
+                'loc: yyloc,',
+                "loc: lexer.yylloc, ruleId: stack.slice(stack.length - 2, stack.length).join(''),"
+              ) +
+            '\nexport default ' +
+            parserName +
+            ';\n'
+        );
+      })
+  };
+
+  parserDefinitions[parserName] = parserDefinition;
+};
+
+const addParsersFromStructure = (structure, dialect) => {
+  addParserDefinition(
+    structure.autocomplete.map(source => 'sql/' + dialect + '/' + source),
+    dialect,
+    true,
+    structure.lexer
+  );
+  addParserDefinition(
+    structure.syntax.map(source => 'sql/' + dialect + '/' + source),
+    dialect,
+    false,
+    structure.lexer
+  );
+};
+
 const findParser = (fileIndex, folder, sharedFiles, autocomplete) => {
   const prefix = autocomplete ? 'autocomplete' : 'syntax';
   if (fileIndex[prefix + '_header.jison'] && fileIndex[prefix + '_footer.jison']) {
-    const parserName = folder + (autocomplete ? 'AutocompleteParser' : 'SyntaxParser');
-    const parserDefinition = {
-      sources: ['sql/' + folder + '/' + prefix + '_header.jison'].concat(sharedFiles),
-      lexer: 'sql/' + folder + '/sql.jisonlex',
-      target: 'sql/' + folder + '/' + parserName + '.jison',
-      sqlParser: autocomplete ? 'AUTOCOMPLETE' : 'SYNTAX',
-      outputFolder: OUTPUT_FOLDER + 'sql/' + folder + '/',
-      afterParse: contents =>
-        new Promise(resolve => {
-          resolve(
-            LICENSE +
-              contents
-                .replace(
-                  'var ' + parserName + ' = ',
-                  "import SqlParseSupport from 'parse/sql/" +
-                    folder +
-                    "/sqlParseSupport';\n\nvar " +
-                    parserName +
-                    ' = '
-                )
-                .replace(
-                  'loc: yyloc,',
-                  "loc: lexer.yylloc, ruleId: stack.slice(stack.length - 2, stack.length).join(''),"
-                ) +
-              '\nexport default ' +
-              parserName +
-              ';\n'
-          );
-        })
-    };
-
-    parserDefinition.sources.push('sql/' + folder + '/' + prefix + '_footer.jison');
-    parserDefinitions[parserName] = parserDefinition;
+    addParserDefinition(
+      [
+        'sql/' + folder + '/' + prefix + '_header.jison',
+        ...sharedFiles,
+        'sql/' + folder + '/' + prefix + '_footer.jison'
+      ],
+      folder,
+      autocomplete,
+      'sql.jisonlex'
+    );
   } else {
     console.log(
       "Warn: Could not find '" +
@@ -291,28 +319,35 @@ const identifySqlParsers = () =>
       const promises = [];
       files.forEach(folder => {
         promises.push(
-          listDir(JISON_FOLDER + 'sql/' + folder).then(jisonFiles => {
-            const fileIndex = {};
-            jisonFiles.forEach(jisonFile => {
-              fileIndex[jisonFile] = true;
-            });
-
-            const sharedFiles = jisonFiles
-              .filter(jisonFile => jisonFile.indexOf('sql_') !== -1)
-              .map(jisonFile => 'sql/' + folder + '/' + jisonFile);
-
-            if (fileIndex['sql.jisonlex']) {
-              findParser(fileIndex, folder, sharedFiles, true);
-              findParser(
-                fileIndex,
-                folder,
-                sharedFiles.filter(path => path.indexOf('_error.jison') === -1),
-                false
+          listDir(JISON_FOLDER + 'sql/' + folder).then(async jisonFiles => {
+            if (jisonFiles.find(fileName => fileName === 'structure.json')) {
+              const structure = JSON.parse(
+                await readFile(JISON_FOLDER + 'sql/' + folder + '/structure.json')
               );
+              addParsersFromStructure(structure, folder);
             } else {
-              console.log(
-                "Warn: Could not find 'sql.jisonlex' in " + JISON_FOLDER + 'sql/' + folder + '/'
-              );
+              const fileIndex = {};
+              jisonFiles.forEach(jisonFile => {
+                fileIndex[jisonFile] = true;
+              });
+
+              const sharedFiles = jisonFiles
+                .filter(jisonFile => jisonFile.indexOf('sql_') !== -1)
+                .map(jisonFile => 'sql/' + folder + '/' + jisonFile);
+
+              if (fileIndex['sql.jisonlex']) {
+                findParser(fileIndex, folder, sharedFiles, true);
+                findParser(
+                  fileIndex,
+                  folder,
+                  sharedFiles.filter(path => path.indexOf('_error.jison') === -1),
+                  false
+                );
+              } else {
+                console.log(
+                  "Warn: Could not find 'sql.jisonlex' in " + JISON_FOLDER + 'sql/' + folder + '/'
+                );
+              }
             }
           })
         );