nomsu/nomsu.peg

161 lines
6.6 KiB
Plaintext
Raw Normal View History

2018-06-23 00:57:31 -07:00
-- Nomsu version 1
file:
(ignored_line %nl)*
2018-06-18 15:44:29 -07:00
(file_chunks / block / action / expression)?
(%nl ignored_line)*
(!. / (({} (.* -> "Parse error") %userdata) => error))
2017-12-30 14:31:07 -08:00
2018-06-18 15:44:29 -07:00
file_chunks (FileChunks):
{| (block/action/expression) (nodent chunk_delimeter nodent (block/action/expression))+ |}
chunk_delimeter: "~~~" (("~")*)
inline_block (Block):
{| inline_statement (%ws* ";" %ws* inline_statement)+ |}
block (Block):
2018-06-18 15:44:29 -07:00
{| statement (nodent !("~") (statement / (({} ([^%nl]* -> "Unexpected character while parsing block line") %userdata) => error)))+ |}
2017-12-30 14:31:07 -08:00
2018-05-30 13:07:08 -07:00
statement: (action / expression) (eol / (({} ([^%nl]* -> "Unexpected character while parsing line") %userdata) => error))
2018-05-26 13:09:20 -07:00
inline_statement: inline_action / inline_expression
2018-04-06 16:45:51 -07:00
noindex_inline_expression:
2018-01-11 01:09:26 -08:00
number / variable / inline_text / inline_list / inline_dict / inline_nomsu
/ ( "("
%ws* (inline_block / inline_action / inline_expression) %ws*
(%ws* ',' %ws* (inline_block / inline_action / inline_expression) %ws*)*
2018-05-03 16:30:55 -07:00
(")"
2018-05-30 13:07:08 -07:00
/ (({} ((!. / &%nl) -> 'Line ended without finding a closing )-parenthesis') %userdata) => error)
/ (({} ([^%nl]* -> 'Unexpected character while parsing subexpression') %userdata) => error)
2018-05-03 16:30:55 -07:00
)
)
2018-04-06 16:45:51 -07:00
inline_expression:
index_chain / noindex_inline_expression
indented_expression:
indented_text / indented_nomsu / indented_list / indented_dict
/ ("(..)"? indent
2018-05-03 16:30:55 -07:00
(block / action / expression)
2018-05-30 13:07:08 -07:00
(dedent / (({} (non_dedent_error -> "Unexpected character while parsing indented expression") %userdata) => error))
)
expression:
2018-05-30 13:07:08 -07:00
inline_expression
/ (":" %ws* ((inline_block / inline_action / inline_expression) eol
/ (({} (eol -> "Missing expression after the ':'") %userdata) => error)))
/ indented_expression
2017-12-30 14:31:07 -08:00
inline_nomsu (EscapedNomsu): "\" {| inline_expression |}
2018-05-26 13:09:20 -07:00
indented_nomsu (EscapedNomsu):
2018-05-30 13:07:08 -07:00
"\" {|
noindex_inline_expression
/ (":" %ws* ((inline_block / inline_action / inline_expression) eol
/ (({} (eol -> "Missing expression after the ':'") %userdata) => error)))
/ indented_expression |}
2018-05-26 13:09:20 -07:00
index_chain (IndexChain):
{| noindex_inline_expression ("." (text_word / noindex_inline_expression))+ |}
2018-05-26 13:09:20 -07:00
-- Actions need either at least 1 word, or at least 2 tokens
inline_action (Action):
2018-06-18 15:44:29 -07:00
!chunk_delimeter
{|
( (inline_expression (%ws* (inline_expression / word))+)
/ (word (%ws* (inline_expression / word))*))
2018-05-30 13:07:08 -07:00
(%ws* ":" %ws* (inline_block / inline_action / inline_expression
/ (({} ('' -> "Missing expression after the ':'") %userdata) => error)))?
|}
action (Action):
2018-06-18 15:44:29 -07:00
!chunk_delimeter
{|
(expression ((nodent "..")? %ws* (expression / word))+)
/ (word ((nodent "..")? %ws* (expression / word))*)
|}
2017-12-30 14:31:07 -08:00
word: !number { %operator_char+ / %ident_char+ }
2017-12-30 14:31:07 -08:00
2018-05-30 12:06:44 -07:00
text_word (Text): {| word |}
2018-01-11 01:09:26 -08:00
inline_text (Text):
!('".."' eol)
'"' {|
({~ (('\"' -> '"') / ('\\' -> '\') / %escaped_char / [^%nl\"])+ ~}
/ inline_text_interpolation)*
2018-05-30 13:07:08 -07:00
|} ('"' / (
(({} (eol->'Line ended before finding a closing double quotation mark') %userdata) => error)
/(({} ([^%nl]*->'Unexpected character while parsing Text') %userdata) => error)
))
2018-05-03 16:30:55 -07:00
-- Have to use "%indent" instead of "indent" etc. to avoid messing up text lines that start with "#"
2018-01-11 01:09:26 -08:00
indented_text (Text):
'".."' eol %nl {|
{~ (%nl*) (%indent -> "") ~}
({~
(("\\" -> "\") / (("\" nodent "..") -> "")/ (%nl+ {~ %nodent -> "" ~}) / [^%nl\] / (!text_interpolation "\"))+
2018-01-11 01:09:26 -08:00
~} / text_interpolation)*
2018-05-30 13:07:08 -07:00
|} (((!.) %dedent) / (&(%nl %dedent)) / (({} (non_dedent_error -> "Unexpected character while parsing Text") %userdata) => error))
inline_text_interpolation:
"\" (
variable / inline_list / inline_dict / inline_text
2018-05-03 16:30:55 -07:00
/ ("("
%ws* (inline_block / inline_action / inline_expression) %ws*
(%ws* ',' %ws* (inline_block / inline_action / inline_expression) %ws*)*
2018-05-03 16:30:55 -07:00
(")"
2018-05-30 13:07:08 -07:00
/ (({} (&%nl -> 'Line ended without finding a closing )-parenthesis') %userdata) => error)
/ (({} ([^%nl]* -> 'Unexpected character while parsing Text interpolation') %userdata) => error))
2018-05-03 16:30:55 -07:00
)
)
text_interpolation:
inline_text_interpolation /
("\" indented_expression nodent "..")
2017-12-30 14:31:07 -08:00
number (Number): {| (("-"? (([0-9]+ "." [0-9]+) / ("." [0-9]+) / ([0-9]+)))-> tonumber) |}
2017-12-30 14:31:07 -08:00
-- 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): "%" {| {(%ident_char+ ((!"'" %operator_char+) / %ident_char+)*)?} |}
2017-12-30 14:31:07 -08:00
inline_list (List):
!('[..]')
2018-05-30 13:07:08 -07:00
"[" %ws*
{| (inline_list_item (%ws* ',' %ws* inline_list_item)* (%ws* ',')?)? |} %ws*
2018-05-30 13:07:08 -07:00
("]" / (","? (
(({} (eol->"Line ended before finding a closing ]-bracket") %userdata) => error)
/(({} ([^%nl]*->"Unexpected character while parsing List") %userdata) => error)
)))
2017-12-30 14:31:07 -08:00
indented_list (List):
2018-05-16 18:12:56 -07:00
"[..]" indent
{| list_line (nodent list_line)* |}
2018-05-30 13:07:08 -07:00
(dedent / ((","? {} (non_dedent_error -> "Unexpected character while parsing List") %userdata) => error))
2017-12-30 14:31:07 -08:00
list_line:
((action / expression) !(%ws* ','))
/ (inline_list_item ((%ws* ',' %ws*) list_line?)?)
inline_list_item: inline_block / inline_action / inline_expression
2017-12-30 14:31:07 -08:00
inline_dict (Dict):
!('{..}')
2018-05-30 13:07:08 -07:00
"{" %ws*
{| (inline_dict_entry (%ws* ',' %ws* inline_dict_entry)*)? |} %ws*
2018-05-30 13:07:08 -07:00
("}" / (","? (
(({} (%ws* eol->"Line ended before finding a closing }-brace") %userdata) => error)
/ (({} ([^%nl]*->"Unexpected character while parsing Dictionary") %userdata) => error)
)))
indented_dict (Dict):
2018-05-16 18:12:56 -07:00
"{..}" indent
{| dict_line (nodent dict_line)* |}
2018-05-30 13:07:08 -07:00
(dedent / ((","? {} (non_dedent_error -> "Unexpected character while parsing Dictionary") %userdata) => error))
dict_line:
(dict_entry !(%ws* ',')) / (inline_dict_entry (%ws* ',' %ws dict_line?)?)
dict_entry(DictEntry):
2018-05-30 13:07:08 -07:00
{| dict_key (%ws* ":" %ws* (action / expression))? |}
inline_dict_entry(DictEntry):
2018-05-30 13:07:08 -07:00
{| dict_key (%ws* ":" %ws* (inline_block / inline_action / inline_expression)?)? |}
2018-04-11 20:05:12 -07:00
dict_key:
text_word / inline_expression
comment: "#" [^%nl]* (%nl+ %indent [^%nl]* (%nl+ %nodent [^%nl]*)* %dedent)?
eol_comment: "#" [^%nl]*
2017-12-30 14:31:07 -08:00
eol: %ws* eol_comment? (!. / &%nl)
ignored_line: (%nodent comment) / (%ws* (!. / &%nl))
indent: eol (%nl ignored_line)* %nl %indent (comment (%nl ignored_line)* nodent)?
nodent: eol (%nl ignored_line)* %nl %nodent
dedent: eol (%nl ignored_line)* (((!.) %dedent) / (&(%nl %dedent)))
2018-05-03 16:30:55 -07:00
non_dedent_error: (!dedent .)* eol (%nl ignored_line)* (!. / &%nl)