diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2018-07-15 19:41:22 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2018-07-15 19:43:28 -0700 |
| commit | be06fc096aa28358914bd6a76b4ea380a04b8873 (patch) | |
| tree | 1f6c300bc8fbeb6cd84008124fca1e43f5513616 /nomsu.1.peg | |
| parent | 8a44869c4a548692a19afe5258e2540f7d351c8a (diff) | |
Major changes to how versioning and parsing work. This should be a
better path going forward to handling upgrades. Old syntax files will
stick around for compatibility purposes. Old syntax can be parsed into
valid syntax trees via the old syntax (.peg) files, and then old syntax
trees should be valid and can be upgraded via the normal code path. This
change has lots of improvements to Nomsu codegen too.
Diffstat (limited to 'nomsu.1.peg')
| -rw-r--r-- | nomsu.1.peg | 155 |
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 |
