---- -- Lpeg Grammar for parsing `alive` code. -- -- @module parsing import Cell, RootCell, ArrayCell, StructCell, Constant, TemplateString, Tag from require 'alv.ast' import R, S, P, V, C, Ct from require 'lpeg' -- whitespace wc = S ' \t\r\n' cexpr = (P '(') * ((V 'cexpr') + (1 - P ')'))^0 * (P ')') ccell = P { (P '#') * (V 'cexpr') :cexpr } cline = (P '##') * (1 - (P '\n'))^0 comment = cline + ccell mspace = (comment + wc)^0 / 1 -- optional whitespace space = (wc^1 * (comment^0 * wc)^0) / 1 -- required whitespace -- atoms digit = R '09' first = (R 'az', 'AZ') + S '-_+*^%/.=~!?$><' sym = first * (first + digit)^0 / Constant\parse 'sym' strd = '"' * (C ((P '\\"') + (P '\\\\') + (1 - P '"'))^0) * '"' / Constant\parse 'str', '\"' strq = "'" * (C ((P "\\'") + (P '\\\\') + (1 - P "'"))^0) * "'" / Constant\parse 'str', '\'' str = strd + strq int = digit^1 fract = digit^1 * '/' * digit^1 float = (digit^1 * '.' * digit^0) + (digit^0 * '.' * digit^1) num = ((P '-')^-1 * (float + fract + int)) / Constant\parse 'num' tag = (P '[') * (digit^1 / Tag.parse) * (P ']') tpltext = ((P '\\"') + (P '\\\\') + (P '\\$') + (1 - (P '"') - (P '$')))^1 / 1 tplcont = Ct (('$' * (V 'expr')) + tpltext)^0 tplstr = (P '$') * tag^-1 * sym * '"' * tplcont * '"' / TemplateString\parse expitem = tplstr + (V 'expr') explist = Ct mspace * (expitem * (space * expitem)^0 * mspace)^-1 cell = (P '(') * tag^-1 * explist * (P ')') / Cell.parse array = (P '[') * explist * (P ']') / ArrayCell\parse struct = (P '{') * explist * (P '}') / StructCell\parse atom = num + sym + str expr = cell + array + struct + atom root = P { explist / RootCell\parse :expr } cell = P { cell :expr } tplstr = P { tplstr :expr } program = root * -1 --- exports -- @table exports -- @tfield pattern comment -- @tfield pattern space -- @tfield pattern atom -- @tfield pattern expr -- @tfield pattern explist -- @tfield pattern explist -- @tfield pattern cell -- @tfield pattern root -- @tfield pattern program the main parsing entrypoint { :comment :space :atom :expr :explist :tplstr :cell :root :program }