Skip to content

Instantly share code, notes, and snippets.

@leafo
Created January 27, 2015 00:00
Show Gist options
  • Save leafo/b44f39860c7aa64e9327 to your computer and use it in GitHub Desktop.
Save leafo/b44f39860c7aa64e9327 to your computer and use it in GitHub Desktop.
start <- block space ! .
word <- [a-zA-Z_] [a-zA-Z_0-9] *
empty_line <- space & stop
string_interpolation <- "#{" ( &{ start("interpolation") } exp space "}" &{ accept("interpolation") } / &{ reject("interpolation") } )
while <- &{ start("while") } space "while" [^a-zA-Z_0-9] exp space ( space "do" [^a-zA-Z_0-9] ( &{ start() } statement &{ accept() } / &{ reject() } ) / break body ) &{ accept("while") } / &{ reject("while") }
body <- & ( < space > &{ advance_indent(yytext) } ) ( &{ start() } ( line ( break line ) * &{ pop_indent() } / &{ pop_indent() } &{ 0 } ) &{ accept() } / &{ reject() } )
unbounded_table <- &{ start("table") } ( &{ start() } key_value_list &{ accept() } / &{ reject() } ) &{ accept("table") } / &{ reject("table") }
line <- < space > &{ check_indent(yytext) } statement / empty_line
table_value <- key_value / &{ start() } exp &{ accept() } / &{ reject() }
space <- [ \t] *
block <- &{ start() } line ( break line ) * &{ accept() } / &{ reject() }
key_value <- table_self_assign / space table_assign
word_list <- < word > &{ push_string(yytext) } ( space "," < word > &{ push_string(yytext) } ) *
import_name <- space "\\" ( &{ start("colon_stub") } < word > &{ push_string(yytext) } &{ accept("colon_stub") } / &{ reject("colon_stub") } ) / < word > &{ push_string(yytext) }
import_names <- import_name ( space "," import_name ) *
chain_dot <- &{ start("dot") } "." < word > &{ push_string(yytext) } &{ accept("dot") } / &{ reject("dot") }
comprehension_loop <- &{ start() } ( comprehension_foreach / comprehension_for ) &{ accept() } / &{ reject() }
comprehension_for <- space "for" [^a-zA-Z_0-9] ( &{ start("for") } < word > &{ push_string(yytext) } space "=" for_range &{ accept("for") } / &{ reject("for") } )
class_lines <- &{ start() } class_line ( ( space break ) + class_line ) * &{ accept() } / &{ reject() }
fn_arg <- space ( &{ start() } < word > &{ push_string(yytext) } ( space "=" exp ) ? &{ accept() } / &{ reject() } )
import <- space "import" [^a-zA-Z_0-9] ( &{ start("import") } ( &{ start() } import_names &{ accept() } / &{ reject() } ) space "from" [^a-zA-Z_0-9] exp &{ accept("import") } / &{ reject("import") } )
class_line <- &{ start("props") } key_value_list &{ accept("props") } / &{ reject("props") } / &{ start("stm") } ( statement / exp ) &{ accept("stm") } / &{ reject("stm") }
exp_list <- exp ( space "," exp ) *
stop <- break / ! .
class_decl <- space "class" [^a-zA-Z_0-9] space ( &{ start("class") } < word > &{ push_string(yytext) } ( class_extends / &{ push_string("") } ) space class_block &{ accept("class") } / &{ reject("class") } )
array_comprehension <- space "[" ( &{ start("comprehension") } exp comprehension_loop space "]" &{ accept("comprehension") } / &{ reject("comprehension") } )
fn_args_inner <- space "(" ( fn_arg ( space "," fn_arg ) * ) ? space ")"
fn_lit <- &{ start("fndef") } fn_args ( &{ start() } "" &{ accept() } / &{ reject() } ) space "->" &{ push_string("slim") } ( space ( &{ start() } statement &{ accept() } / &{ reject() } / break body ) / &{ start() } "" &{ accept() } / &{ reject() } ) &{ accept("fndef") } / &{ reject("fndef") }
chain_peek <- & ( word ( some_space [a-zA-Z_] / "." ) )
number <- < [0-9] + > &{ push_simple("number", yytext) }
table_lit_line <- space break ( < space > &{ push_indent(yytext) } ( table_value_list &{ pop_indent() } / &{ pop_indent() } &{ 0 } ) / space )
class_extends <- space "extends" [^a-zA-Z_0-9] space exp
exp <- &{ start("exp") } value ( op value ) * &{ accept("exp"), flatten_last() } / &{ reject("exp") }
chain_call_parens <- "(" ( &{ start() } exp_list ? &{ accept() } / &{ reject() } ) space ")"
chain_call_open <- some_space ! ( ( "class" / "do" / "for" / "if" / "import" / "then" / "while" ) [^a-zA-Z_0-9] ) ( &{ start() } exp_list &{ accept() } / &{ reject() } )
string_double <- space '"' &{ push_string("\"") } ( string_interpolation / < ( ! '"' ! "#{" ( '\\\"' / . ) ) + > &{ push_string(yytext) } ) * '"'
some_space <- [ \t] +
string <- &{ start("string") } ( string_double / string_single ) &{ accept("string") } / &{ reject("string") }
op <- space < [-+] > &{ push_string(yytext) }
string_single <- space "'" &{ push_string("'") } < ( ! "'" ( "\\\'" / . ) ) * > &{ push_string(yytext) } "'"
chain_call <- &{ start("call") } ( chain_call_open / chain_call_parens ) &{ accept("call") } / &{ reject("call") }
class_block <- ( space break ) + & ( < space > &{ advance_indent(yytext) } ) ( class_lines &{ pop_indent() } / &{ pop_indent() } &{ 0 } )
chain <- &{ start("chain") } ! ( ( "class" / "do" / "for" / "if" / "import" / "then" / "while" ) [^a-zA-Z_0-9] ) ref ( chain_dot / chain_call ) + &{ accept("chain") } / &{ reject("chain") }
key_value_list <- key_value ( space "," key_value ) *
comprehension_foreach <- space "for" [^a-zA-Z_0-9] space ( &{ start("foreach") } ( &{ start() } word_list &{ accept() } / &{ reject() } ) space "in" [^a-zA-Z_0-9] exp &{ accept("foreach") } / &{ reject("foreach") } )
table_value_list <- table_value ( space "," table_value ) *
table_lit <- &{ start("table") } space "{" ( &{ start() } ( table_value_list ( space "," ) ? ) ? table_lit_line * &{ accept() } / &{ reject() } ) space "}" &{ accept("table") } / &{ reject("table") }
fn_lit_peek <- & ( space [-(] )
fn_args <- &{ start() } fn_args_inner ? &{ accept() } / &{ reject() }
table_self_assign <- space ":" ! some_space ( &{ start() } ( &{ start("key_literal") } & ( < word > &{ push_string(yytext) } ) &{ accept("key_literal") } / &{ reject("key_literal") } ) < word > &{ push_simple("ref", yytext) } &{ accept() } / &{ reject() } )
table_assign <- &{ start() } < word > &{ push_simple("key_literal", yytext) } ":" exp &{ accept() } / &{ reject() }
if <- &{ start("if") } space "if" [^a-zA-Z_0-9] exp space ( space "then" [^a-zA-Z_0-9] ( &{ start() } statement &{ accept() } / &{ reject() } ) / break body ) &{ accept("if") } / &{ reject("if") }
break <- "\n"
statement <- ( if / for / while / assign / exp ) space & stop
assign <- &{ start("assign") } ( &{ start() } ref_list &{ accept() } / &{ reject() } ) space "=" ( &{ start() } exp_list &{ accept() } / &{ reject() } ) &{ accept("assign") } / &{ reject("assign") }
ref_list <- ref ( space "," ref ) *
for_range <- &{ start() } exp space "," exp ( space "," exp ) ? &{ accept() } / &{ reject() }
ref <- < word > &{ push_simple("ref", yytext) }
for <- &{ start("for") } space "for" [^a-zA-Z_0-9] space < word > &{ push_string(yytext) } space "=" for_range space ( space "do" [^a-zA-Z_0-9] ( &{ start() } statement &{ accept() } / &{ reject() } ) / break body ) &{ accept("for") } / &{ reject("for") }
value <- space ( import / class_decl / array_comprehension / string / table_lit / fn_lit / unbounded_table / chain / number / ref )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment