-- Frontend lexer for the parser local lex = require 'luainlua.parsing.lex' local re = require 'luainlua.parsing.re' local code_stack = {} local string_stack = {} local reference_stack = {} local quote_stack = {} local tag_stack = {} local function id(token) return function(...) return {token, ...} end end local function ignore(...) return end local function pop(stack) return table.remove(stack) end local function push(item, stack) table.insert(stack, item) end return lex.lex { root = { {'%eps', id 'EPS'}, {'\'\'', id 'EPS'}, {'%code', id 'TOP_LEVEL'}, {'%convert', id 'CONVERT'}, {'%prologue', id 'PROLOGUE'}, {'%epilogue', id 'EPILOGUE'}, {'%default', id 'DEFAULT'}, {'%production', id 'PRODUCTION'}, {'%file', id 'FILE'}, {'%require', id 'REQUIRE'}, {'%default.action', id 'DEFAULT_ACTION'}, {'%quote', id 'QUOTE'}, {'%resolve', id 'RESOLVE'}, {';', id 'SEMICOLON'}, {':=', id 'GETS'}, {'|', id 'OR'}, {'(', id 'LPAREN'}, {')', id 'RPAREN'}, {'*', id 'STAR'}, {'+', id 'PLUS'}, {'?', id 'MAYBE'}, {re '$(%a|_)(%a|%d|_|#|\')*', id 'VARIABLE'}, {re '(%a|_)(%a|%d|_|#|\')*', id 'IDENTIFIER'}, {'{:', function(piece, lexer) lexer:go 'code'; push('', code_stack) end}, {'"', function(piece, lexer) lexer:go 'string'; push('', string_stack) end}, {'\'', function(piece, lexer) lexer:go 'quote'; push('', quote_stack) end}, {'[:', function(piece, lexer) lexer:go 'reference'; push('', reference_stack) end}, {'<', function(piece, lexer) lexer:go 'tag'; push('', tag_stack) end}, {re '%s+', ignore}, {re '/%*', function(piece, lexer) lexer:go 'comment' end}, {re '//[^\n]+', ignore}, }, code = { {':}', function(piece, lexer) lexer:go 'root' return {'CODE', pop(code_stack)} end}, {re '.', function(piece, lexer) push(pop(code_stack) .. piece, code_stack) end} }, string = { {'"', function(piece, lexer) lexer:go 'root' return {'STRING', pop(string_stack)} end}, {re '.', function(piece, lexer) push(pop(string_stack) .. piece, string_stack) end} }, tag = { {'>', function(piece, lexer) lexer:go 'root' return {'TAG', pop(tag_stack)} end}, {re '.', function(piece, lexer) push(pop(tag_stack) .. piece, tag_stack) end} }, quote = { {'\'', function(piece, lexer) lexer:go 'root' return {'QUOTED', pop(quote_stack)} end}, {re '.', function(piece, lexer) push(pop(quote_stack) .. piece, quote_stack) end} }, reference = { {':]', function(piece, lexer) lexer:go 'root' return {'REFERENCE', pop(reference_stack)} end}, {re '.', function(piece, lexer) push(pop(reference_stack) .. piece, reference_stack) end} }, comment = { {re '%*/', function(piece, lexer) lexer:go 'root' end}, {re '.', ignore}, } }