aboutsummaryrefslogtreecommitdiff
path: root/nomsu.1.peg
diff options
context:
space:
mode:
Diffstat (limited to 'nomsu.1.peg')
-rw-r--r--nomsu.1.peg155
1 files changed, 155 insertions, 0 deletions
diff --git a/nomsu.1.peg b/nomsu.1.peg
new file mode 100644
index 0000000..1551b6d
--- /dev/null
+++ b/nomsu.1.peg
@@ -0,0 +1,155 @@
+-- Nomsu version 2
+file (FileChunks):
+ {:curr_indent: ' '* :}
+ comment? blank_lines?
+ (chunk (nl_nodent chunk_delimeter nl_nodent chunk)*)?
+ blank_lines?
+ %ws* (!! .+ -> "Parse error" !!)?
+
+nodent: =curr_indent !(" ")
+indent: =curr_indent " "
+blank_lines: %nl ((nodent comment / %ws*) %nl)*
+eol: %ws* eol_comment? (!. / &%nl)
+
+nl_nodent: blank_lines nodent
+nl_indent: blank_lines {:curr_indent: indent :} (comment nl_nodent)?
+
+comment:
+ "#" (({} {~ [^%nl]* ((%nl (!indent %ws* %nl)*) (indent -> '') [^%nl]*)* ~} %userdata) => add_comment)
+eol_comment:
+ "#" (({} {[^%nl]*} %userdata) => add_comment)
+
+chunk: block / action / expression
+chunk_delimeter: ("~")^+3 eol
+
+inline_block (Block):
+ inline_statement (%ws* ";" %ws* inline_statement)+
+block (Block):
+ statement (nl_nodent statement)+
+
+statement: (action / expression) (eol / (!! [^%nl]+ -> "Unexpected character while parsing line" !!))
+inline_statement: (inline_action / inline_expression)
+
+noindex_inline_expression:
+ 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*)*
+ (")"
+ / (!! eol -> 'Line ended without finding a closing )-parenthesis' !!)
+ / (!! [^%nl]+ -> 'Unexpected character while parsing subexpression' !!)
+ )
+ )
+inline_expression: index_chain / noindex_inline_expression
+indented_expression:
+ indented_text / indented_nomsu / indented_list / indented_dict / ({|
+ ("(..)")? nl_indent
+ (block / action / expression) (nl_nodent comment)*
+ (eol / (!! [^%nl]+ -> "Unexpected character while parsing indented expression" !!))
+ |} -> unpack)
+expression:
+ inline_expression
+ / (":" %ws*
+ (inline_block / inline_action / inline_expression / (!! '' -> "Missing expression after the ':'" !!)))
+ / indented_expression
+
+inline_nomsu (EscapedNomsu): "\" inline_expression
+indented_nomsu (EscapedNomsu):
+ "\" (
+ noindex_inline_expression
+ / (":" %ws*
+ (inline_block / inline_action / inline_expression) (!! '' -> "Missing expression after the '\:'" !!))
+ / indented_expression)
+
+index_chain (IndexChain):
+ noindex_inline_expression ("." (text_word / noindex_inline_expression))+
+
+-- Actions need either at least 1 word, or at least 2 tokens
+inline_action (Action):
+ !chunk_delimeter
+ ( (inline_expression (%ws* (inline_expression / word))+)
+ / (word (%ws* (inline_expression / word))*))
+ (%ws* ":" %ws* (inline_block / inline_action / inline_expression
+ / (!! '' -> "Missing expression after the ':'" !!)))?
+action (Action):
+ !chunk_delimeter
+ ( (expression ((nl_nodent "..")? %ws* (expression / word))+)
+ / (word ((nl_nodent "..")? %ws* (expression / word))*))
+
+word: !number { %operator_char+ / %ident_char+ }
+
+text_word (Text): word
+
+inline_text (Text):
+ !('".."' eol)
+ '"'
+ ({~ (('\"' -> '"') / ('\\' -> '\') / %escaped_char / [^%nl\"])+ ~}
+ / inline_text_interpolation)*
+ ('"'
+ / (!! eol -> 'Line ended before finding a closing double quotation mark' !!)
+ / (!! [^%nl]+ -> 'Unexpected character while parsing Text' !!))
+inline_text_interpolation:
+ "\" (
+ variable / inline_list / inline_dict / inline_text
+ / ("("
+ %ws* (inline_block / inline_action / inline_expression) %ws*
+ (%ws* ',' %ws* (inline_block / inline_action / inline_expression) %ws*)*
+ (")"
+ / (!! eol -> 'Line ended without finding a closing )-parenthesis' !!)
+ / (!! [^%nl]+ -> 'Unexpected character while parsing Text interpolation' !!)))
+ )
+
+indented_text (Text):
+ '".."' eol %nl {:curr_indent: indent :}
+ (indented_plain_text / text_interpolation / {~ blank_lines (=curr_indent -> "") ~})*
+ (!! [^%nl]+ -> "Unexpected character while parsing Text" !!)?
+indented_plain_text (Text):
+ {~ (("\\" -> "\") / (("\" blank_lines =curr_indent "..") -> "") / (!text_interpolation "\") / [^%nl\]+)+
+ (blank_lines (=curr_indent -> ""))* ~}
+text_interpolation:
+ inline_text_interpolation / ("\" indented_expression blank_lines =curr_indent "..")
+
+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): "%" {(%ident_char+ ((!"'" %operator_char+) / %ident_char+)*)?}
+
+inline_list (List):
+ !('[..]')
+ "[" %ws*
+ (inline_list_item (%ws* ',' %ws* inline_list_item)* (%ws* ',')?)? %ws*
+ ("]" / (","? (
+ (!! eol -> "Line ended before finding a closing ]-bracket" !!)
+ /(!! [^%nl]+ -> "Unexpected character while parsing List" !!)
+ )))
+indented_list (List):
+ "[..]" eol nl_indent
+ list_line (nl_nodent list_line)* (nl_nodent comment)*
+ (","? (!! [^%nl]+ -> "Unexpected character while parsing List" !!))?
+list_line:
+ (inline_list_item %ws* "," %ws*)+ eol
+ / (inline_list_item %ws* "," %ws*)* (action / expression) eol
+inline_list_item: inline_block / inline_action / inline_expression
+
+inline_dict (Dict):
+ !('{..}')
+ "{" %ws*
+ (inline_dict_entry (%ws* ',' %ws* inline_dict_entry)*)? %ws*
+ ("}" / (","? (
+ (!! eol -> "Line ended before finding a closing }-brace" !!)
+ / (!! [^%nl]* -> "Unexpected character while parsing Dictionary" !!)
+ )))
+indented_dict (Dict):
+ "{..}" eol nl_indent
+ dict_line (nl_nodent dict_line)* (nl_nodent comment)*
+ (","? (!! [^%nl]+ -> "Unexpected character while parsing Dictionary" !!))?
+dict_line:
+ (inline_dict_entry %ws* "," %ws*)+ eol
+ / (inline_dict_entry %ws* "," %ws*)* dict_entry eol
+dict_entry(DictEntry):
+ dict_key (%ws* ":" %ws* (action / expression))?
+inline_dict_entry(DictEntry):
+ dict_key (%ws* ":" %ws* (inline_block / inline_action / inline_expression)?)?
+dict_key:
+ text_word / inline_expression