• Stars
    star
    164
  • Rank 228,682 (Top 5 %)
  • Language
    C
  • License
    Apache License 2.0
  • Created over 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

JS parser in Web Assembly / C

Tests

A permissive JavaScript tokenizer and parser in C. See a demo syntax highlighter.

Supports ESM code only (i.e., type="module", which is implicitly strict). Supports all language features in the draft specification (as of January 2021).

This is compiled via Web Assembly to run on the web or inside Node without native bindings. It's not reentrant, so you can't parse another file from within its callbacks. It does not generate an AST (although does emit enough data to do so in JS), does not modify the input, and does not use malloc or free.

Usage

Import and install via your favourite package manager. This requires Node v13.10.0 or higher.

The parser works by invoking callbacks on every token as well as open/close announcements for a 'stack', which roughly maps to something you might make an AST node out of.

import {buildHarness} from 'gumnut';

const harness = await buildHarness();  // WebAssembly instantiation is async

const buffer = new TextEncoder().encode('console.info("hello");');
const memory = harness.prepare(buffer.length);
memory.set(buffer);

harness.handle({
  callback() {
    const type = harness.token.type();
    console.info('token', harness.token.type(), harness.token.string());
  },
  open(stackType) { /* open stack type, return false to skip contents */ },
  close(stackType) { /* close stack type */ },
});

harness.run();

This is fairly low-level and designed to be used by other tools.

Module Imports Rewriter

This provides a rewriter for unresolved ESM imports (i.e., those pointing to "node_modules"), which could be used as part of an ESM dev server. Usage:

import buildImportsRewriter from 'gumnut/imports';
import buildResolver from 'esm-resolve';

// WebAssembly instantiation is async
const run = await buildImportsRewriter(buildResolver);
run('./source.js', (part) => process.stdout.write(part));

This example uses esm-resolve, which implements an ESM resolver in pure JS.

Coverage

This correctly parses all 'pass-explicit' tests from test262-parser-tests, except those which rely on non-strict mode behavior (e.g., use variable names like static and let).

Note

JavaScript has a single open-ended 'after-the-fact' ambiguity for keywords, as async is not always a keywordβ€”even in strict mode. Here's an example:

// this is a function call of a method named "async"
async(/* anything can go here */) {}

// this is an async arrow function
async(/* anything can go here */) => {}

// this calls the async method on foo, and is _not_ ambiguous
foo.async() {}

This parser has to walk over code like this at most twice to resolve whether async is a keyword before continuing. See arrow functions break JavaScript parsers for more details.

It also needs to walk over non-async functions at most twiceβ€”like (a, b) =>β€”to correctly label the argument as either creating new variables in scope, or just using them (like a function call or simple parens).

History

Since engineers like to rewrite everything all the time, see the 2020 branch of this code.

More Repositories

1

kuto

Faster updates for big JS projects
TypeScript
509
star
2

rippleJS

vanilla Material Design ripples
JavaScript
189
star
3

fast-text-encoding

Fast polyfill for TextEncoder and TextDecoder, only supports UTF-8
JavaScript
101
star
4

scoped

Scoped CSS polyfill
TypeScript
92
star
5

fastgif

fastgif, fast Web Assembly GIF decoder based on Wuffs
HTML
69
star
6

undoer

Native undo/redo behavior for web
JavaScript
56
star
7

srcgraph

ES6 module code splitting via custom parser and Rollup
JavaScript
44
star
8

viz-observer

Notifies your code on DOM node move or resize
TypeScript
24
star
9

but-csv

479 byte CSV parser and builder
JavaScript
23
star
10

mobile-first

Custom element to contain content within mock device πŸ“±
JavaScript
19
star
11

cjs-loader

πŸ”₯πŸ‘¨β€πŸ’»πŸ”₯ This is a successful but terrible idea and should not be used by anyone.
JavaScript
17
star
12

sre2

non-standard implementation of RE2 in Go
Go
17
star
13

wasm-game

Pixel game written with Web Assembly
C
15
star
14

but-unzip

small ~1k unzip library
JavaScript
15
star
15

hey-elon

Hey, Elon Chrome Extension
JavaScript
13
star
16

https-forward

A forwarding HTTPS server using Let's Encrypt
Go
12
star
17

html-modules-polyfill

HTML Modules Rewriter
JavaScript
12
star
18

typed-event-types

Typed events for EventTarget subclasses
JavaScript
11
star
19

advanced-input

Advanced <input> or <textarea> elements
JavaScript
9
star
20

dhost

Never-caching development Node webserver
JavaScript
8
star
21

async-transforms

Asynchronous stream transforms for easier and faster Node pipelines, i.e. build tools
JavaScript
7
star
22

esm-resolve

Resolves ESM imports in Node
TypeScript
7
star
23

parq

Parquet reader in JS
TypeScript
7
star
24

tiddlycsv

small, streaming CSV parser (~1kb)
TypeScript
7
star
25

fusebase

πŸ› οΈ FUSE filesystem backed on the πŸ”₯ Firebase Database
Go
4
star
26

nicehttp

Convenience library for HTTP handlers in Go
Go
4
star
27

tr51

Go library to process TR51 (aka Emoji πŸ€”πŸ—œοΈπŸ”¨πŸŽ‰) data
Go
4
star
28

daikin-go

Raw interface to Daikin AC units with WiFi dongles
Go
4
star
29

tiny-stable-stringify

Sorted version of JSON.stringify
TypeScript
4
star
30

polymer-closure

Demo project for compiling Polymer elements
HTML
3
star
31

shactions

Google Smart Home Actions in Go
Go
3
star
32

promises

The missing Promise helpers your JavaScript project needs
JavaScript
3
star
33

mocha-headless-server

Headless Mocha testing on a local HTTP server
JavaScript
3
star
34

11ty-fast-dev

11ty-fast-dev
JavaScript
2
star
35

thorish

Useful JS concepts and data structures
TypeScript
2
star
36

hangar

Local daemon for developing distributed Fly.io servers
Go
2
star
37

atvlib

Apple TV control library in Go
Go
2
star
38

base-project

Sam's base JS project
Shell
2
star
39

split-dom

Helper JavaScript to split DOM nodes within text
JavaScript
2
star
40

wattson

Wattson control library
Go
2
star
41

fileparts

File object which can have its properties modified independently.
JavaScript
2
star
42

unicodeshrugforyou

¯‍\‍_‍(‍ツ‍)‍_‍/‍¯
HTML
2
star
43

thrift-tools

Work with Thrift definitions and data
TypeScript
2
star
44

airhorn-overlay

Airhorn Web Component
JavaScript
2
star
45

radhist

Radical HTML history library
JavaScript
2
star
46

matcher

Gem matcher game demo
JavaScript
1
star
47

no-www

no-www hosting
Go
1
star
48

gulp-tweakdom

DOM manipulation in Gulp
JavaScript
1
star
49

syncingabout

JavaScript
1
star
50

lcatalk

LCA Talk 2018
HTML
1
star
51

valuefs

FUSE filesystem for historic values
Go
1
star
52

pysucks

Demonstration of a sane Python loader
Python
1
star
53

sents-cli

Command-line filesystem watcher with low dependencies
JavaScript
1
star
54

choose

PWA for choosing
JavaScript
1
star
55

purge-gcloud-app

Purge old gcloud deployed App Engine versions
JavaScript
1
star
56

JsTower

JavaScript
1
star
57

redirects-yaml

Helps you define redirects in a YAML file
JavaScript
1
star
58

samthor

<script>alert('hi');</script>
1
star
59

stitch-demo

TypeScript
1
star
60

ok-emoji

Finds whether an emoji is supported in the browser
JavaScript
1
star