Giter Club home page Giter Club logo

solidity-antlr4's Introduction

Solidity ANTLR4

Solidity Language Lexer and Parser, generated by official ANTLR4 grammar.

NPM version NPM downloads CI status codecov MIT License

Contributors Issues Stargazers Follow Twitter

Change Log · Report Bug · Pull Request

Installation

$ npm install solidity-antlr4

It will be pnpm/yarn add solidity-antlr4 if you use pnpm or yarn.

Usage

Language Parser

  • parse(code, [options]): parse() parses the provided code as an entire Solidity source unit.
  • options:
    • tolerant: boolean, default is false. If true, the parser will try to parse as much as possible, even if the input is invalid, and never throw an error.
    • selector: function, default is (p) => p.sourceUnit(). If provided, the parser will only return the nodes that match the selector. It will be useful when you want to parse a specific node.
  • output: SyntaxNode, the root node of the AST.
// parse.mjs
import { parse } from 'solidity-antlr4';

const code = `// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract HelloWorld {
  string public greet = "Hello World!";
}
`;

const ast = parse(code, { tolerant: true, selector: (p) => p.sourceUnit() });
// SourceUnit {
//   type: 'SourceUnit',
//   src: '32:88',
//   range: [ 32, 120 ],
//   location: Location {
//     start: Position { line: 2, column: 0 },
//     end: Position { line: 6, column: 0 }
//   },
//   context: SourceUnitContext {...},
//   nodes: [
//     PragmaDirective {
//       type: 'PragmaDirective',
//       literals: [Array]
//     },
//     ContractDefinition {
//       type: 'ContractDefinition',
//       name: [Identifier],
//       contractKind: 'contract',
//       abstract: false,
//       baseContracts: [],
//       nodes: [Array]
//     }
//   ]
// }

Tokenizer

  • tokenizer(code, [options]): tokenizer() parses the provided code as tokens.
  • options:
    • tolerant: boolean, default is false.
  • output: SyntaxToken[].
// tokenizer.mjs
import { tokenizer } from 'solidity-antlr4';

const tokens = tokenizer(code, { tolerant: true });
// [
//   {
//     type: 'SourceUnit',
//     src: '32:88',
//     range: [ 32, 120 ],
//     location: Location {
//       start: Position { line: 2, column: 0 },
//       end: Position { line: 6, column: 0 }
//     }
//   },
//   ...
// ]

Traverse AST

We can use it alongside the parser to traverse nodes.

// visit.mjs
import { parse, visit, serialize } from 'solidity-antlr4';

const ast = parse(code);

// Use `visit` to traverse ast by enter/exit node type.
visit(ast, {
  enter: ({ node, parent }) => {
    console.log(node.type, parent?.type); // print node type
  },
  exit: () => {}, // will call when exit node
  Identifier: ({ node: identifierNode }) => {
    console.log(identifierNode.name); // print identifier name
  },
  exitContractDefinition: ({ node: contractDefinitionNode }) => {
    // will call when exit ContractDefinition node
  }
});

// Use `serialize` to modify ast.
const newAST = serialize(ast, ({ node }) => {
  // do something
  if (node.type === 'Identifier') {
    return node.name;
  }
  return node;
})
// traverse.mjs
import { parse, traverse } from 'solidity-antlr4';

const ast = parse(code);

const newAST = traverse(ast, (path) => {
  // path.path => `SourceUnit.ContractDefinition.FunctionDefinition` ...
  // path.node => current node
  // path.parentPath => parent node path
  // path.depth => current node depth
  // path.stop(); => stop traverse
  // path.rewrite({...}); => rewrite current node
  // path.matches({ type: 'xxx' }); => check if current node matches the given filter
  // return () => {}; => will call when exit node
});

Low-level API

Not recommended, but you can use it if you want.

import { SolidityLexer, SolidityParser, CharStreams, CommonTokenStream } from 'solidity-antlr4';

const code = `...`; // code here

const input = CharStreams.fromString(code);
const lexer = new SolidityLexer(input);
const tokens = new CommonTokenStream(lexer);
const parser = new SolidityParser(tokens);

const parseTree = parser.sourceUnit();

// do something with parseTree

License

MIT

solidity-antlr4's People

Contributors

jeasonstudio avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

solidity-antlr4's Issues

[Bug] Unable to run example code.

import { parse } from 'solididty-antlr4';

const code = `// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract HelloWorld {
  string public greet = "Hello World!";
}
`;

const { parseTree, syntaxTree: ast, errors } = parse(code);
// SyntaxTree: { type: "SourceUnit", nodes: [...], rage: [0, 136], location: {...} }

Also, there's a typo i believe it should be solidity instead of solididty.

After fixing it I'm still unable to run getting the error when running node main.js .

import { parse } from 'solidity-antlr4';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1153:20)
    at Module._compile (node:internal/modules/cjs/loader:1205:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)
    at Module.load (node:internal/modules/cjs/loader:1091:32)
    at Module._load (node:internal/modules/cjs/loader:938:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12)
    at node:internal/main/run_main_module:23:47

Node.js v20.9.0

After setting package.json type as module to resolve that error

import { parse } from 'solidity-antlr4';
         ^^^^^
SyntaxError: Named export 'parse' not found. The requested module 'solidity-antlr4' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'solidity-antlr4';
const { parse } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:131:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:213:5)
    at async ModuleLoader.import (node:internal/modules/esm/loader:316:24)
    at async loadESM (node:internal/process/esm_loader:34:7)
    at async handleMainPromise (node:internal/modules/run_main:66:12)

Node.js v20.9.0

After changing to use

import pkg from 'solidity-antlr4';
const { parse } = pkg;

The following error then occurs.

(node:11672) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
Error parsing Solidity code: C:\Users\trans\OneDrive - Nanyang Technological University\Desktop\Github repos\web3\gpt-auditor\node_modules\solidity-antlr4\dist\esm\index.js:1
export * from "./grammar";
^^^^^^

SyntaxError: Unexpected token 'export'
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1153:20)
    at Module._compile (node:internal/modules/cjs/loader:1205:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)
    at Module.load (node:internal/modules/cjs/loader:1091:32)
    at Module._load (node:internal/modules/cjs/loader:938:12)
    at cjsLoader (node:internal/modules/esm/translators:284:17)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:234:7)
    at ModuleJob.run (node:internal/modules/esm/module_job:217:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:316:24)

Changing file to use .mjs did not resolve the error as well.

Thanks for taking a look at it and please do let me know if I'm trying to use this wrongly lol

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.