Skip to content

tanvirtin/lunaites

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lunaites 🌙

Handwritten Lua parser that transforms your Lua source code into Abstract Syntax Tree.

Supported Lua versions:

Requirements

Usage

const { Parser } from './lunaites/parser/mod.ts';

const source = `
local sup = "Hello, world!");
print(sup);
`
const parser = new Parser(source);

const ast = parser.parse();

Live demo

Run the following command

make watch

And then paste in or type your lua source code into lunaites/core/scratchpad/scratchpad.

The ast representation of the source code will be piped to standard output as you make changes to this file.

Lua 5.1 Grammar


chunk ::= {stat [`;´]} [laststat [`;´]]

block ::= chunk

stat ::=  varlist `=´ explist | 
        functioncall | 
        do block end | 
        while exp do block end | 
        repeat block until exp | 
        if exp then block {elseif exp then block} [else block] end | 
        for Name `=´ exp `,´ exp [`,´ exp] do block end | 
        for namelist in explist do block end | 
        function funcname funcbody | 
        local function Name funcbody | 
        local namelist [`=´ explist] 

laststat ::= return [explist] | break

funcname ::= Name {`.´ Name} [`:´ Name]

varlist ::= var {`,´ var}

var ::=  Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name 

namelist ::= Name {`,´ Name}

explist ::= {exp `,´} exp

exp ::=  nil | false | true | Number | String | `...´ | function | 
                prefixexp | tableconstructor | exp binop exp | unop exp 

prefixexp ::= var | functioncall | `(´ exp `)´

functioncall ::=  prefixexp args | prefixexp `:´ Name args 

args ::=  `(´ [explist] `)´ | tableconstructor | String 

function ::= function funcbody

funcbody ::= `(´ [parlist] `)´ block end

parlist ::= namelist [`,´ `...´] | `...´

tableconstructor ::= `{´ [fieldlist] `}´

fieldlist ::= field {fieldsep field} [fieldsep]

field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp

fieldsep ::= `,´ | `;´

binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `%´ | `..´ | 
                `<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ | 
                and | or

	unop ::= `-´ | not | `#´

Why

  • Curiosity to learn how programming languages are parsed. Best way to learn more was to implement one for a language used by many.
  • Lua parsers are usually written using recursive descent algorithm. Lunaites implements a precedence parsing algorithm to solve the problem, called Pratt Parsing.
  • Understand and utilize Backus–Naur form.

What's supported

  • Lua 5.1
  • Lua 5.2
  • Lua 5.3
  • Lua 5.4
  • LuaJIT
  • Lossless
  • Better error reporting
  • Scope metadata

Tests

Run the following commands

make smoke-tests
make integration-tests
make snapshot-tests
make unit-tests

or

make tests

References:

Notes: