mp.lua (4580B)
1 local l = require("lexer") 2 local lex = l.new(...) 3 local P, R, S = lpeg.P, lpeg.R, lpeg.S 4 local T = function(name, patt) return lex:tag(name, patt) end 5 local any = P(1) 6 local dec = R"09" 7 local alpha = R("AZ", "az") 8 local hws = S"\t " 9 local vws = S"\n\r" 10 local ws = hws + vws 11 local function I(s) -- Case-insensitive string match 12 local p = P(true) 13 for i = 1, #s do 14 local c = s:sub(i, i) 15 p = p * (P(c:lower()) + P(c:upper())) 16 end 17 return p 18 end 19 local function N(p, min, max) 20 max = max or min 21 return p^min - p^(max+1) 22 end 23 24 local whitespace = T("whitespace", ws^1) 25 26 local comment_keyword = T("comment_keyword", I"todo" + I"xxx" + I"fixme") 27 local comment_text = T("comment_text", (any - P"\n" - comment_keyword)^1) 28 local comment = T("comment_text", P"%") * (comment_text + comment_keyword)^0 * T("whitespace", P"\n") 29 30 local numlit = T("numlit", (dec^0 * P".")^-1 * dec^1) 31 32 local strlit = T("strlit", P"\"" * (any - vws - S"\"")^0 * P"\"") 33 34 local delimiter = T("delimiter", S"()[]{};,") 35 36 local operator = T("operator", S"<=>:+-*/.&|" + l.word_match{ 37 "thru", "atleast", "of", "cycle", "on", "off", 38 "makepen", "makepath", "penoffset", 39 "char", "substring", 40 41 -- Number operators 42 "angle", "dir", "sind", "sin", "asin", "cosd", "cos", "acos", "tand", "tan", "atan", 43 "floor", "ceiling", "round", "abs", "length", "normalize", "sqrt", "mod", "div", "dotprod", 44 "mexp", "mlog", 45 "normaldeviate", "uniformdeviate", 46 47 -- Boolean opereators 48 "not", "and", "or", "even", "odd", "known", "unknown", 49 "isnumber", "ispair", "ispath", "istransform", "isrgbcolor", "iscolor", "iscmykcolor", "isstring", "isboolean", "ispicture", "ispen", "cyclic", 50 51 -- Transformations 52 "transformed", "rotated", "slanted", "reflectedabout", "shifted", "xshifted", "yshifted", "scaled", "xscaled", "yscaled", "zscaled", "rotatedaround", "rotatedabout", 53 "inverse", 54 55 -- BBox operators 56 "ulcorner", "llcorner", "urcorner", "lrcorner", "center", "bbox", 57 "width", "height", "ascent", "descent", 58 59 -- Path operators 60 "arclength", "arctime", "direction", "directiontime", "directionpoint", "intersectiontimes", "intersectionpoint", "point", "precontrol", "postcontrol", "reverse", "subpath", "subcycle", "cutbefore", "cutafter", "cutcycle", "tensepath", 61 "envelope", "turningnumber", "cw", "ccw", 62 63 -- Pair operators 64 "xpart", "ypart", "xxpart", "xypart", "yxpart", "yypart", "swap", 65 "cyanpart", "magentapart", "yellowpart", "blackpart", 66 "redpart", "greenpart", "bluepart", 67 "greypart", "dashpart", "fontpart", "pathpart", "penpart", "textpart", 68 69 -- Draw options 70 "dashed", "withpen", "withprescript", "withpostscript", "withoutcolor", "withrgbcolor", "withcolor", "withcmykcolor", "withgreyscale", 71 }) 72 73 local suffix = T("suffix", P"#@" + P"@#" + P"@") 74 75 local keyword = T("keyword", l.word_match{ 76 "input", "endinput", "end", "dump", "shipout", "special", 77 "begingroup", "endgroup", 78 "scantokens", "expandafter", "ea", 79 "let", "def", "vardef", "primarydef", "secondarydef", "tertiarydef", "enddef", 80 "outer", "inner", "save", "interim", "delimiters", 81 "show", "showdependencies", "showtoken", "showvariable", "showstats", 82 "errhelp", "errmessage", "message", 83 "batchmode", "nonstopmode", "scrollmode", "errorstopmode", 84 "addto", "also", "contour", "doublepath", "clip", "setbounds", 85 "controls", "tension", "curl", 86 "if", "elseif", "else", "fi", "exitif", "exitunless", 87 "for", "forsuffixes", "forever", "step", "until", "upto", "downto", "endfor", 88 }) 89 90 local constant = T("constant", l.word_match{ 91 "mitered", "rounded", "beveled", "butt", "squared", 92 93 -- Number 94 "eps", "epsilon", "inf", 95 96 -- Pair 97 "left", "right", "up", "down", "origin", 98 99 -- Path 100 "circle", "square", 101 102 -- Transform 103 "id", 104 105 -- String 106 "dquote", "EOF", 107 108 -- Boolean 109 "true", "false", 110 111 -- Picture 112 "nullpicture", 113 114 -- Pen 115 "nullpen", "pencircle", "pensquare", "penrazor", "penspeck", 116 }) 117 118 local type_ = T("type", l.word_match{ 119 "newinternal", 120 121 -- Builtin types 122 "numeric", "pair", "path", "transform", "rgbcolor", "color", 123 "cmykcolor", "string", "boolean", "picture", "pen", 124 125 -- Parameters 126 "text", "expr", "suffix", "primary", "secondary", "tertiary", 127 128 -- r3mp aliases 129 "internal", "number", 130 }) 131 132 local identifier = T("identifier", (alpha + P"_")^1) 133 134 lex:add_rule("whitespace", whitespace) 135 lex:add_rule("comment", comment) 136 lex:add_rule("numlit", numlit) 137 lex:add_rule("strlit", strlit) 138 lex:add_rule("delimiter", delimiter) 139 lex:add_rule("operator", operator) 140 lex:add_rule("suffix", suffix) 141 lex:add_rule("keyword", keyword) 142 lex:add_rule("constant", constant) 143 lex:add_rule("type", type_) 144 lex:add_rule("identifier", identifier) 145 146 return lex