Open Sourcing language-solidity, a Solidity parser written in TypeScript

Kwang Yul Seo
CodeChain
Published in
2 min readApr 30, 2018

Posted by CodeChain Team on Tue, Nov 7, 2017

Solidity is a new experimental language for writing smart contracts. It is still in an early stage of development and lacks the tooling needed to be considered a serious programming language. One of the big problems that Solidity has is that it lacks a formal language specification. The official Solidity compiler is the only Solidity compiler available and unfortunately it is its implementation detail, and not the spec, that specifies the behavior of the programs. So it is not easy to write a spec-conforming language tool without reusing the source code of the compiler.

Many Solidity tools such as Solium and vscode-solidity are written in JavaScript/TypeScript. They use Consensys’ solidity-parser or its variant solparseto parse a Solidity program into a syntax tree. But these parsers do not conform to the specification. They work fine for simple imports parsing, but for full Solidity parsing its structure is too different from the official Solidity specification (or C++ implementation). They keep breaking for all sorts of edge cases.

Since CodeChain team needed a 100% compatible Solidity parser to implement advanced language server features such as auto-completion, formatting and renaming, we wrote a spec conforming Solidity parser in TypeScript and decided to release it as an open source project.

language-solidity currently provides the lexer, parser and AST nodes for manipulating Solidity programs. The code is based on the Solidity compiler written in C++, and it passes all the parser tests of the compiler.

Here’s an example program which extracts the contract names from the given Solidity program:

import * as fs from "fs";

import {
ASTVisitor,
CharStream,
ContractDefinition,
DiagnosticReporter,
Parser,
Scanner,
SourceUnit
} from "../src";

class ContractNameCollector extends ASTVisitor {
public contractNames: string[] = [];

constructor(node: SourceUnit) {
super();
node.accept(this);
}

public visitContractDefinition(node: ContractDefinition): boolean {
this.contractNames.push(node.name);
return true;
}
}

function main() {
const source = fs.readFileSync("MetaCoin.sol").toString();
const scanner = new Scanner(new CharStream(source));
const reporter = new DiagnosticReporter();
const parser = new Parser(reporter);
const node = parser.parse(scanner);
const collector = new ContractNameCollector(node);
console.log(collector.contractNames);
}

main();

Our Solidity language server has already begun to use language-solidity for imports parsing and will use it to implement other advanced IDE features. We certainly believe the newly Solidity parser will help the Solidity community create better tooling.

--

--