antlr | Cell 7 | Cell 9 | Search

The antlrToESTree function converts an ANTLR-generated tree into an ESTree (ECMA Script Abstract Syntax Tree) by performing various operations such as node replacement and logging. It uses functions like selectDom, treeToHtml, and replace to manipulate the tree and create a new ESTree representation.

Run example

npm run import -- "antlr tree to es"

antlr tree to es

var assert = require('assert')
var importer= require('../Core')
var {treeToHtml, htmlToTree} = importer.import("tree to html",
"html to tree")
var {selectDom} = importer.import("select tree")
var {transpile, replace} = importer.import("transpile code")

function antlrToESTree(tree) {
    console.log(tree)
    var dom = selectDom('./*', treeToHtml([tree]))
    
    selectDom([
        `//TerminalNode/ancestor::ThetypenameContext
        |//TerminalNode/ancestor::SimpletypespecifierContext`,
        replace(ctx => {
            var {range, value} = htmlToTree(selectDom('.//TerminalNode', ctx))
            return selectDom('./*', treeToHtml({
                type: 'Type',
                name: value,
                range: range,
            }))
        })
    ], dom)
    
    
    selectDom([
        `//TerminalNode/ancestor::IdexpressionContext`,
        replace(ctx => {
            if(selectDom('.//TerminalNode/ancestor::ClassnameContext', ctx)) {
                var {range, value} = htmlToTree(selectDom('.//TerminalNode[./parent::ClassnameContext]', ctx))
                return selectDom('./*', treeToHtml({
                    type: 'UnaryExpression',
                    operator: '~',
                    argument: {
                        type: 'Identifier',
                        name: value,
                        kind: null,
                        pointer: false,
                        range: range
                    },
                    prefix: true
                }))
            }
            var {range, value} = htmlToTree(selectDom('.//TerminalNode', ctx))
            return selectDom('./*', treeToHtml({
                type: 'Identifier',
                name: value,
                kind: null,
                pointer: false,
                range: range,
            }))
        })
    ], dom)
    
    selectDom([
        `//MemberdeclarationContext`,
        replace(ctx => {
            var {kind, key, semi} = selectDom({
                kind: './/Type',
                key: './/Identifier',
                semi: './/TerminalNode[@value = ";"]'
            }, ctx)
            var id = htmlToTree(key)
            id.kind = htmlToTree(kind)
            return selectDom('./*', treeToHtml({
                type: 'Property',
                kind: 'init',
                key: id,
                method: false,
                computed: false,
                value: null,
                shorthand: false,
                range: [
                    htmlToTree(kind).range[0],
                    htmlToTree(semi).range[1]
                ]
            }))
        })
    ], dom)
    
    selectDom([
        `//SimpledeclarationContext[
            .//ClassheadContext//TerminalNode[@value = "struct"]
        ]`,
        replace(ctx => {
            var {typedef, body, id, superClass, semi} = selectDom({
                typedef: './/TerminalNode[@value = "typedef"]',
                id: './/InitdeclaratorContext//Identifier',
                body: ['.//Property'],
                superClass: './/ClasskeyContext//@value',
                semi: './TerminalNode[@value = ";"]'
            }, ctx)
            return selectDom('./*', treeToHtml({
                type: 'ClassExpression',
                id: htmlToTree(id),
                superClass: superClass,
                body: {
                    type: 'ClassBody',
                    body: htmlToTree(body)
                },
                typedef: true,
                range: [
                    htmlToTree(typedef).range[0],
                    htmlToTree(semi).range[1]
                ]
            }))
        })
    ], dom)
    
    selectDom([
        `//ParameterdeclarationContext`,
        replace(ctx => {
            var {type, constant, ptr, id} = selectDom({
                type: './/Type',
                constant: './/TerminalNode[@value="const"]/@value',
                ptr: './/TerminalNode[@value="*"]/@value',
                id: './/Identifier'
            }, ctx)
            if(!id) return type
            var result = Object.assign(htmlToTree(id), {
                kind: htmlToTree(type),
                pointer: !!ptr
            })
            return selectDom('./*', treeToHtml(result))
        })
    ], dom)
    
    /*
    selectDom([
        `//SimpledeclarationContext`,
        replace(ctx => {
            var {type, constant, ptr, ids} = selectDom({
                static: './/TerminalNode[@value="static"]',
                type: './/Type',
                constant: './/TerminalNode[@value="const"]/@value',
                ptr: './/TerminalNode[@value="*"]/@value',
                ids: ['.//Identifier'],
                semi: './TerminalNode[@value = ";"]'
            }, ctx)
            var result = {
                type: 'VariableDeclaration',
                declarations: htmlToTree(ids).map(id => ({
                    type: 'VariableDeclarator',
                    id: Object.assign(id, {
                        kind: htmlToTree(type),
                        pointer: !!ptr
                    }),
                    init: null
                })),
                kind: constant ? 'const' : 'let',
                range: [
                    
                ]
            }
            return selectDom('./*', treeToHtml(result))
        })
    ], dom)
    */
    
    return htmlToTree(dom)
}

module.exports = antlrToESTree

What the code could have been:

const { assert } = require('assert');
const { importer } = require('../Core');
const {
  treeToHtml,
  htmlToTree,
  selectDom,
} = importer.import(['tree to html', 'html to tree','select tree']);
const { transpile, replace } = importer.import('transpile code');

/**
 * Converts an ANTLR AST to an ESTree.
 *
 * @param {import('antlr4/runtime/ParseTree').ParseTree} tree - The ANTLR AST to convert.
 * @returns {import('estree').ESTree} The converted ESTree.
 */
function antlrToESTree(tree) {
  console.log(tree);

  const dom = selectDom('./*', treeToHtml([tree]));

  selectDom([
    `//TerminalNode/ancestor::ThetypenameContext
     |//TerminalNode/ancestor::SimpletypespecitorContext`,
    replace(ctx => {
      const { range, value } = htmlToTree(selectDom('.//TerminalNode', ctx));
      return selectDom('./*', treeToHtml({
        type: 'Type',
        name: value,
        range,
      }));
    }),
  ], dom);

  selectDom([
    `//TerminalNode/ancestor::IdexpressionContext`,
    replace(ctx => {
      if (selectDom('.//TerminalNode/ancestor::ClassnameContext', ctx)) {
        const { range, value } = htmlToTree(
          selectDom('.//TerminalNode[./parent::ClassnameContext]', ctx),
        );
        return selectDom('./*', treeToHtml({
          type: 'UnaryExpression',
          operator: '~',
          argument: {
            type: 'Identifier',
            name: value,
            kind: null,
            pointer: false,
            range,
          },
          prefix: true,
        }));
      }

      const { range, value } = htmlToTree(selectDom('.//TerminalNode', ctx));
      return selectDom('./*', treeToHtml({
        type: 'Identifier',
        name: value,
        kind: null,
        pointer: false,
        range,
      }));
    }),
  ], dom);

  selectDom([
    `//MemberdeclarationContext`,
    replace(ctx => {
      const { kind, key, semi } = selectDom({
        kind: './/Type',
        key: './/Identifier',
        semi: './/TerminalNode[@value = ";"]',
      }, ctx);
      const id = htmlToTree(key);
      id.kind = htmlToTree(kind);
      return selectDom('./*', treeToHtml({
        type: 'Property',
        kind: 'init',
        key: id,
        method: false,
        computed: false,
        value: null,
        shorthand: false,
        range: [
          htmlToTree(kind).range[0],
          htmlToTree(semi).range[1],
        ],
      }));
    }),
  ], dom);

  selectDom([
    `//SimpledeclarationContext[
     .//ClassheadContext//TerminalNode[@value = "struct"]
    ]`,
    replace(ctx => {
      const { typedef, body, id, superClass, semi } = selectDom({
        typedef: './/TerminalNode[@value = "typedef"]',
        id: './/InitdeclaratorContext//Identifier',
        body: ['.//Property'],
        superClass: './/ClasskeyContext//@value',
        semi: './TerminalNode[@value = ";"]',
      }, ctx);
      return selectDom('./*', treeToHtml({
        type: 'ClassExpression',
        id: htmlToTree(id),
        superClass,
        body: {
          type: 'ClassBody',
          body: htmlToTree(body),
        },
        typedef: true,
        range: [
          htmlToTree(typedef).range[0],
          htmlToTree(semi).range[1],
        ],
      }));
    }),
  ], dom);

  selectDom([
    `//ParameterdeclarationContext`,
    replace(ctx => {
      const { type, constant, ptr, id } = selectDom({
        type: './/Type',
        constant: './/TerminalNode[@value="const"]/@value',
        ptr: './/TerminalNode[@value="*"]/@value',
        id: './/Identifier',
      }, ctx);
      if (!id) return type;
      const result = Object.assign(
        htmlToTree(id),
        {
          kind: htmlToTree(type),
          pointer:!!ptr,
        },
      );
      return selectDom('./*', treeToHtml(result));
    }),
  ], dom);

  return htmlToTree(dom);
}

module.exports = antlrToESTree;

Function Breakdown: antlrToESTree

The antlrToESTree function appears to be a part of a code generator or transformer that converts an ANTLR-generated tree into an ESTree (ECMA Script Abstract Syntax Tree).

Parameters

Functionality

The function performs the following operations:

  1. Logging and Initial Tree Conversion: It logs the input tree and converts it into an HTML string using the treeToHtml function.
  2. Selecting Terminal Nodes: It uses the selectDom function to select Terminal Node elements within the HTML string.
  3. Replacing Terminal Nodes (Type): It replaces Terminal Nodes that are ancestors of ThetypeNameContext or SimpleTypeSpecifierContext elements with a new Type node. The old Type node is extracted from the Terminal Node and the new Type node is created with the same range and value.
  4. Replacing Terminal Nodes (IdExpression): It replaces Terminal Nodes that are descendants of IdExpressionContext elements. If the Terminal Node is a descendant of a ClassnameContext element, it creates a UnaryExpression node with the Terminal Node's value as the argument. Otherwise, it creates an Identifier node with the Terminal Node's value.
  5. Replacing MemberDeclarationContext: It replaces MemberDeclarationContext elements by creating a new node with the same kind, key, and semi-colon information.

Functions Used

Assumptions

This function appears to be part of a larger code generator or transformer, and it assumes the presence of certain functions and variables, such as importer, selectDom, treeToHtml, and htmlToTree.