98 lines
3.6 KiB
Plaintext
98 lines
3.6 KiB
Plaintext
file (File):
|
|
{| shebang?
|
|
(ignored_line %nl)*
|
|
statement (nodent statement)*
|
|
(%nl ignored_line)*
|
|
(!. / (("" -> "Parse error") => error)?) |}
|
|
|
|
shebang: "#!" [^%nl]* %nl
|
|
|
|
statement: functioncall / expression
|
|
|
|
indented_block (Block):
|
|
{| indent
|
|
statement (nodent statement)*
|
|
(dedent / (("" -> "Error while parsing block") => error))
|
|
|}
|
|
|
|
inline_nomsu (Nomsu): "\" inline_expression
|
|
indented_nomsu (Nomsu): "\" expression
|
|
|
|
inline_expression:
|
|
number / variable / inline_text / inline_list / inline_dict / inline_nomsu
|
|
/ ("(" %ws* (inline_functioncall / inline_expression) %ws* ")")
|
|
indented_expression:
|
|
indented_text / indented_nomsu / indented_list / indented_dict / indented_block
|
|
expression:
|
|
inline_expression / (":" %ws* (inline_functioncall / inline_expression)) / indented_expression
|
|
|
|
-- Function calls need at least one word in them
|
|
inline_functioncall (FunctionCall):
|
|
{| (inline_expression %ws*)* word (%ws* (inline_expression / word))*
|
|
(%ws* ":" %ws* (inline_functioncall / inline_expression))?|}
|
|
functioncall (FunctionCall):
|
|
{| (expression (dotdot / %ws*))* word ((dotdot / %ws*) (expression / word))* |}
|
|
|
|
word (Word): { %operator / (!number plain_word) }
|
|
|
|
inline_text (Text):
|
|
!('".."')
|
|
'"' {|
|
|
({~ (('\"' -> '"') / ('\\' -> '\') / ('\..' -> '..') / %escaped_char / [^%nl\"])+ ~}
|
|
/ text_interpolation)*
|
|
|} '"'
|
|
indented_text (Text):
|
|
'".."' %ws* line_comment? %nl %gt_nodent? {|
|
|
({~
|
|
(("\\" -> "\") / (("\" eol %nl %gt_nodent "..") -> "")
|
|
/ (%nl+ {~ %gt_nodent -> "" ~}) / [^%nl\])+
|
|
~} / text_interpolation)*
|
|
|} ((!.) / (&(%nl+ !%gt_nodent)) / (("" -> "Error while parsing Text") => error))
|
|
text_interpolation:
|
|
"\" (variable / inline_list / inline_dict / inline_text / ("(" %ws* (inline_functioncall / inline_expression) %ws* ")"))
|
|
|
|
number (Number): (("-"? (([0-9]+ "." [0-9]+) / ("." [0-9]+) / ([0-9]+)))-> tonumber)
|
|
|
|
-- Variables can be nameless (i.e. just %) and can't contain operators like apostrophe
|
|
-- which is a hack to allow %'s to parse as "%" and "' s" separately
|
|
variable (Var): "%" { plain_word? }
|
|
|
|
inline_list (List):
|
|
!('[..]')
|
|
"[" %ws* {| (inline_list_item (comma inline_list_item)* comma?)? |} %ws* "]"
|
|
indented_list (List):
|
|
"[..]" indent {|
|
|
list_line (nodent list_line)*
|
|
|}
|
|
(dedent / (("" -> "Error while parsing list") => error))
|
|
list_line:
|
|
((functioncall / expression) !comma)
|
|
/ (inline_list_item (comma list_line?)?)
|
|
inline_list_item: inline_functioncall / inline_expression
|
|
|
|
inline_dict (Dict):
|
|
!('{..}')
|
|
"{" %ws* {| (inline_dict_item (comma inline_dict_item)* comma?)? |} %ws* "}"
|
|
indented_dict (Dict):
|
|
"{..}" indent {|
|
|
dict_line (nodent dict_line)*
|
|
|}
|
|
(dedent / (("" -> "Error while parsing dict") => error))
|
|
dict_line:
|
|
({| {:dict_key: inline_expression / word :} %ws* ":" %ws* {:dict_value: functioncall / expression :} |} !comma)
|
|
/ (inline_dict_item (comma dict_line?)?)
|
|
inline_dict_item:
|
|
{| {:dict_key: inline_expression / word :} %ws* ":" %ws* {:dict_value: inline_functioncall / inline_expression :} |}
|
|
|
|
block_comment(Comment): "#.." { [^%nl]* (%nl %gt_nodent [^%nl]*)* }
|
|
line_comment(Comment): "#" { [^%nl]* }
|
|
|
|
eol: %ws* line_comment? (!. / &%nl)
|
|
ignored_line: (%nodent (block_comment / line_comment)) / (%ws* (!. / &%nl))
|
|
indent: eol (%nl ignored_line)* %nl %indent ((block_comment/line_comment) (%nl ignored_line)* nodent)?
|
|
nodent: eol (%nl ignored_line)* %nl %nodent
|
|
dedent: eol (%nl ignored_line)* (((!.) &%dedent) / (&(%nl %dedent)))
|
|
comma: %ws* "," %ws*
|
|
dotdot: nodent ".." %ws*
|
|
plain_word: ([a-zA-Z0-9_] / %utf8_char)+
|