aboutsummaryrefslogtreecommitdiff
path: root/nomsu.1.peg
diff options
context:
space:
mode:
Diffstat (limited to 'nomsu.1.peg')
-rw-r--r--nomsu.1.peg163
1 files changed, 95 insertions, 68 deletions
diff --git a/nomsu.1.peg b/nomsu.1.peg
index 10a7715..5d881b3 100644
--- a/nomsu.1.peg
+++ b/nomsu.1.peg
@@ -1,65 +1,87 @@
--- Nomsu version 2
+-- Nomsu version 1
file (FileChunks):
{:curr_indent: ' '* :}
- ("#!" (!"nomsu" [^%nl])* "nomsu" %ws+ "-V" %ws* {:version: [0-9.]+ :} [^%nl]*)?
+ ("#!" (!"nomsu" [^%nl])* "nomsu" ws+ "-V" ws* {:version: [0-9.]+ :} [^%nl]*)?
comment? blank_lines?
(chunk (nl_nodent chunk_delimeter nl_nodent chunk)*)?
blank_lines?
- %ws* (!! .+ -> "Parse error" !!)?
+ {:curr_indent: %nil :}
+ !.
-nodent: =curr_indent !(" ")
+nodent: (unexpected_indent [^%nl]* / =curr_indent)
indent: =curr_indent " "
-blank_lines: %nl ((nodent comment / %ws*) %nl)*
-eol: %ws* eol_comment? (!. / &%nl)
+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 -> '') [^%nl]*)* ~} %userdata) => add_comment)
-eol_comment:
- "#" (({} {[^%nl]*} %userdata) => add_comment)
+nl_indent: blank_lines {:curr_indent: indent :} (comment nl_nodent)*
+
+comment (Comment):
+ "#" {~ [^%nl]* (%nl+ (indent -> '') [^%nl]*)* ~}
+eol_comment (Comment):
+ "#" {[^%nl]*}
+
+unexpected_code: ws* _unexpected_code
+_unexpected_code (Error):
+ {:error: {~ [^%nl]+ -> "Couldn't parse this code" ~} :}
+unexpected_indent (Error):
+ {:error: {~ (=curr_indent ws+) -> "Messed up indentation" ~} :}
+ {:hint: {~ '' -> 'Either make sure this line is aligned with the one above it, or make sure the previous line ends with something that uses indentation, like ":" or "(..)"' ~} :}
+missing_paren_err (Error):
+ {:error: {~ eol -> 'Line ended without finding a closing )-parenthesis' ~} :}
+ {:hint: {~ '' -> 'Put a ")" here' ~} :}
+missing_quote_err (Error):
+ {:error: {~ eol -> 'Line ended before finding a closing double quotation mark' ~} :}
+ {:hint: {~ "" -> "Put a quotation mark here" ~} :}
+missing_bracket_error (Error):
+ {:error: {~ eol -> "Line ended before finding a closing ]-bracket" ~} :}
+ {:hint: {~ '' -> 'Put a "]" here' ~} :}
+missing_brace_error (Error):
+ {:error: {~ eol -> "Line ended before finding a closing }-brace" ~} :}
+ {:hint: {~ '' -> 'Put a "}" here' ~} :}
+missing_block_expr_error (Error):
+ {:error: '' -> "Missing expression after the ':'" :}
chunk: block / action / expression
chunk_delimeter: ("~")^+3 eol
inline_block (Block):
- inline_statement (%ws* ";" %ws* inline_statement)+
+ inline_statement (ws* ";" ws* inline_statement)+
block (Block):
statement (nl_nodent statement)+
+ (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
+ {:curr_indent: %nil :}
-statement: (action / expression) (eol / (!! [^%nl]+ -> "Unexpected character while parsing line" !!))
+statement: (action / expression) (eol / unexpected_code)
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' !!)
- )
+ ws* (inline_block / inline_action / inline_expression) ws*
+ (ws* ',' ws* (inline_block / inline_action / inline_expression) ws*)*
+ (")" / missing_paren_err / unexpected_code)
)
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" !!))
+ (block / action / expression) (eol / unexpected_code)
+ (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
+ {:curr_indent: %nil :}
|} -> unpack)
expression:
inline_expression
- / (":" %ws*
- (inline_block / inline_action / inline_expression / (!! '' -> "Missing expression after the ':'" !!)))
+ / (":" ws*
+ (inline_block / inline_action / inline_expression / missing_block_expr_error))
/ indented_expression
inline_nomsu (EscapedNomsu): "\" inline_expression
indented_nomsu (EscapedNomsu):
"\" (
noindex_inline_expression
- / (":" %ws*
- (inline_block / inline_action / inline_expression) (!! '' -> "Missing expression after the '\:'" !!))
+ / (":" ws*
+ (inline_block / inline_action / inline_expression / missing_block_expr_error))
/ indented_expression)
index_chain (IndexChain):
@@ -68,42 +90,39 @@ index_chain (IndexChain):
-- 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 ':'" !!)))?
+ ( (inline_expression (ws* (inline_expression / word))+)
+ / (word (ws* (inline_expression / word))*))
+ (ws* ":" ws* (inline_block / inline_action / inline_expression
+ / missing_block_expr_error))?
action (Action):
!chunk_delimeter
- ( (expression ((nl_nodent "..")? %ws* (expression / word))+)
- / (word ((nl_nodent "..")? %ws* (expression / word))*))
+ ( (expression ((nl_nodent "..")? ws* (expression / word))+)
+ / (word ((nl_nodent "..")? ws* (expression / word))*))
-word: !number { %operator_char+ / %ident_char+ }
+word: !number { operator_char+ / ident_char+ }
text_word (Text): word
inline_text (Text):
- !('".."' eol)
+ !(indented_text)
'"'
- ({~ (('\"' -> '"') / ('\\' -> '\') / %escaped_char / [^%nl\"])+ ~}
+ ({~ (('\"' -> '"') / ('\\' -> '\') / escaped_char / [^%nl\"])+ ~}
/ inline_text_interpolation)*
- ('"'
- / (!! eol -> 'Line ended before finding a closing double quotation mark' !!)
- / (!! [^%nl]+ -> 'Unexpected character while parsing Text' !!))
+ ('"' / missing_quote_err / unexpected_code)
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' !!)))
+ ws* (inline_block / inline_action / inline_expression) ws*
+ (ws* ',' ws* (inline_block / inline_action / inline_expression) ws*)*
+ (")" / missing_paren_err / unexpected_code))
)
indented_text (Text):
- '".."' eol %nl {%nl*} {:curr_indent: indent :}
+ '".."' eol %nl {%nl+}? {:curr_indent: indent :}
(indented_plain_text / text_interpolation / {~ %nl+ (=curr_indent -> "") ~})*
- (!! [^%nl]+ -> "Unexpected character while parsing Text" !!)?
+ unexpected_code?
+ {:curr_indent: %nil :}
indented_plain_text (Text):
{~ (("\\" -> "\") / (("\" blank_lines =curr_indent "..") -> "") / (!text_interpolation "\") / [^%nl\]+)+
(%nl+ (=curr_indent -> ""))* ~}
@@ -114,43 +133,51 @@ number (Number): (("-"? (([0-9]+ "." [0-9]+) / ("." [0-9]+) / ([0-9]+)))-> tonum
-- 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+)*)?}
+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" !!)
- )))
+ "[" ws*
+ (inline_list_item (ws* ',' ws* inline_list_item)* (ws* ',')?)? ws*
+ ("]" / (","? (missing_bracket_error / unexpected_code)))
indented_list (List):
"[..]" eol nl_indent
- list_line (nl_nodent list_line)* (nl_nodent comment)*
- (","? (!! [^%nl]+ -> "Unexpected character while parsing List" !!))?
+ list_line (nl_nodent list_line)*
+ (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
+ (","? unexpected_code)?
list_line:
- (inline_list_item %ws* "," %ws*)+ eol
- / (inline_list_item %ws* "," %ws*)* (action / expression) eol
+ (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" !!)
- )))
+ "{" ws*
+ (inline_dict_entry (ws* ',' ws* inline_dict_entry)*)? ws*
+ ("}" / (","? (missing_brace_error / unexpected_code)))
indented_dict (Dict):
"{..}" eol nl_indent
- dict_line (nl_nodent dict_line)* (nl_nodent comment)*
- (","? (!! [^%nl]+ -> "Unexpected character while parsing Dictionary" !!))?
+ dict_line (nl_nodent dict_line)*
+ (%nl (ws* %nl)* nodent (comment / eol / unexpected_code))*
+ (","? unexpected_code)?
dict_line:
- (inline_dict_entry %ws* "," %ws*)+ eol
- / (inline_dict_entry %ws* "," %ws*)* dict_entry eol
+ (inline_dict_entry ws* "," ws*)+ eol
+ / (inline_dict_entry ws* "," ws*)* dict_entry eol
dict_entry(DictEntry):
- dict_key (%ws* ":" %ws* (action / expression))?
+ dict_key (ws* ":" ws* (action / expression))?
inline_dict_entry(DictEntry):
- dict_key (%ws* ":" %ws* (inline_block / inline_action / inline_expression)?)?
+ dict_key (ws* ":" ws* (inline_block / inline_action / inline_expression)?)?
dict_key:
text_word / inline_expression
+
+operator_char: ['`~!@$^&*+=|<>?/-]
+ident_char: [a-zA-Z0-9_] / %utf8_char
+ws: [ %tab]
+
+escaped_char:
+ ("\"->'') (
+ (([xX]->'') ((({[0-9a-fA-F]^2} %number_16) -> tonumber) -> tochar))
+ / ((([0-9] [0-9]^-2) -> tonumber) -> tochar)
+ / ("a"->ascii_7) / ("b"->ascii_8) / ("t"->ascii_9) / ("n"->ascii_10)
+ / ("v"->ascii_11) / ("f"->ascii_12) / ("r"->ascii_13)
+ )