57 lines
2.1 KiB
Python
57 lines
2.1 KiB
Python
import gll
|
|
|
|
@gll.parser("expression")
|
|
def expression(string):
|
|
parser = gll.seq(ws, func_call | literal, ws, tag="expression")
|
|
|
|
return parser(string)
|
|
|
|
ws = gll.skipmany(gll.string(" "))
|
|
skipped = lambda pat: gll.skip(gll.string(pat), tag="skip_{}".format(pat))
|
|
variable = gll.regex("\w+", tag="variable_name")
|
|
type_decl = gll.regex("\w+", tag="type")
|
|
comma = gll.skip(gll.regex(r"\s*,\s*"))
|
|
|
|
number = gll.many1(gll.digit(), tag="number")
|
|
string = gll.seq(skipped("\""), gll.regex(r'[^"\\]+'), skipped("\""), tag="string")
|
|
lst = gll.seq(skipped("["), gll.sep_by(comma, expression | variable),
|
|
skipped("]"), tag="list")
|
|
|
|
declaration = gll.seq(skipped("var"), ws, variable, ws, type_decl, tag="declaration")
|
|
|
|
assignment = gll.seq(variable, ws, skipped("="), ws, expression, tag="assignment")
|
|
|
|
return_statement = gll.seq(skipped("return"), ws, expression,
|
|
tag="return")
|
|
|
|
func_call = gll.seq(variable, skipped("("),
|
|
gll.sep_by(comma, expression | variable, tag="arguments"),
|
|
skipped(")"), tag="call")
|
|
|
|
literal = number | string | lst
|
|
|
|
special = gll.seq(ws, return_statement | declaration | assignment, ws)
|
|
|
|
body = gll.seq(skipped("{"), skipped("\n"),
|
|
gll.sep_by(gll.regex(r"\s*\n+\s*"), expression | special, tag="body"),
|
|
gll.opt(skipped("\n")), skipped("}"))
|
|
|
|
argument = gll.seq(variable, ws, type_decl, tag="parameter")
|
|
arguments_list = gll.seq(skipped("("), gll.sep_by(comma, argument),
|
|
skipped(")"), tag="parameters")
|
|
|
|
function = gll.seq(skipped("func"), ws, gll.regex("\w+", tag="function_name"),
|
|
ws, arguments_list, ws, type_decl, ws, body, ws,
|
|
tag="function")
|
|
|
|
package_name = gll.seq(skipped("package"), ws, variable,
|
|
gll.skipmany(gll.string(" ")), skipped("\n"),
|
|
tag="package_name")
|
|
|
|
package = gll.seq(package_name, gll.many(skipped("\n")),
|
|
gll.sep_by(gll.string("\n"), function, tag="package_body"),
|
|
gll.many(skipped("\n")),
|
|
tag="package")
|
|
|
|
parser = gll.all(package)
|