#!/usr/bin/env janet (def to-ast "A custom markdown flavored grammar" ~{ :end-of-line (* (? "\r") "\n") :single-line-comment (cmt (<- (* (+ "//" "#") (some (if-not :end-of-line 1)))),|[:single-line-comment (string/join $&)]) :multi-line-comment (cmt (<- (* "/*" (some (if-not "*/" 1)) "*/")),|[:multi-line-comment (string/join $&)]) :comment (+ :single-line-comment :multi-line-comment) :string (cmt (<- (* "\"" (some (if-not "\"" 1)) "\"")),|[:string (string/join $&)]) :name-non-digit (+ :a "_") :name (some (+ :name-non-digit (range "\x80\xFF"))) :variable (cmt (<- (* "$" :name)),|[:variable (string/join $&)]) :scalar-type (+ "bool" "float" "int" "string") :base-type (+ "array" "callable" "iterable" :scalar-type) :return-type (cmt (<- (+ :base-type "void")),|[:return-type $0]) :keyword (cmt (<- (+ "abstract" "and" "array" "as" "break" "callable" "case" "catch" "class" "clone" "const" "continue" "declare" "default" "die" "do" "echo" "else" "elseif" "empty" "enddeclare" "endfor" "endforeach" "endif" "endswitch" "endwhile" "eval" "exit" "extends" "final" "finally" "for" "foreach" "function" "fn" "global" "goto" "if" "implements" "include" "include_once" "instanceof" "insteadof" "interface" "isset" "list" "namespace" "new" "or" "print" "private" "protected" "public" "require" "require_once" "return" "static" "switch" "throw" "trait" "try" "unset" "use" "var" "while" "xor" "yield" "yield from")),|[:keyword $0]) :other (cmt (<- (if-not :comment 1)),|[:other (string/join $&)]) :main (some (+ :comment :string :variable :return-type :keyword :other))})