raku.peg 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. # A Raku program conssts of statements, separated by end of expression.
  2. # End of expression is a period or a newline not escaped by a preceding \
  3. PROGRAM ← STATEMENTS
  4. STATEMENTS ← (STATEMENT EOX)+
  5. # A statement is a command, a block or a call, optionallly followed by comment, or a comment
  6. STATEMENT ← (COMMENT / COMMAND COMMENT? / BLOCK COMMENT? / CALL COMMENT?)
  7. # A comment starts with #, comment remark or rem
  8. ~COMMENT ← LONG_COMMENT / LINE_COMMENT
  9. # Reuse the string macro to absorb a long comment
  10. LONG_COMMENT ← RAWSM("#{", "}#")
  11. LINE_COMMENT ← ("#" / "comment" / "remark" / "rem") (!([\r\n]+).)*
  12. # A Commans starts with a word which is the verb, and is followed by optional arguments
  13. COMMAND ← VERB ARGUMENTS?
  14. ~BLOCK_KEYWORD ← < ( "do" / "sub" / "block") > WHITESPACE
  15. ~END_KEYWORD ← < ( "so" / "end" / "done" ) > WHITESPACE
  16. ~CALL_KEYWORD ← < ( "be" / "run" / "call" ) > WHITESPACE
  17. HAVING_KEYWORD ← < ( "having" / "given" ) > WHITESPACE
  18. BLOCK ← BLOCK_KEYWORD BODY END_KEYWORD / "{" BODY "}"
  19. CALL ← CALL_KEYWORD BODY END_KEYWORD / "(" BODY ")"
  20. BODY ← OPERATION / (EOX? STATEMENTS? STATEMENT?)
  21. TARGET ← ARGSEP? (EXPRESSION / BLOCK / CALL)
  22. ARGUMENTS ← TARGET ARGUMENT*
  23. ARGSEP ← ',' / ((PREPOSITION / ARTICLE)+) /
  24. ((HAVING_KEYWORD ARTICLE? WORD ARTICLE?))
  25. PREPOSITION ← < ( "else" / "otherwise" /
  26. "aboard" / "about" / "above" / "across" / "after" / "against" /
  27. "alongside"/ "along" / "amidst" / "amidst" / "among" / "around" /
  28. "as" / "at" / "atop" / "before" / "behind"/ "below" /
  29. "beneath" / "besides" / "beside" / "between" / "beyond"/ "but" /
  30. "by" / "circa" / "despite" / "down" / "during"/ "except" /
  31. "for" / "from" / "inside" / "into" / "in" / "less" /
  32. "like" / "near" / "nothwithstanding" / "off" / "onto" /
  33. "on" / "opposite" / "outside" / "out" / "over" / "since" /
  34. "than" / "through" / "thru" / "towards" / "throughout" / "to" /
  35. "underneath"/ "under" / "unlike" / "until" / "upon" / "upside" /
  36. "up" / "versus" / "via" / "within" / "without" / "with" ) > WHITESPACE
  37. ~ARTICLE ← <("a" / "an" / "the")> WHITESPACE
  38. ARGUMENT ← ARGSEP EXPRESSION / ARGSEP? BLOCK / ARGSEP? CALL
  39. EXPRESSION ← ARRAY / STRING / NUMBER / SPECIALS / OPERATION / NAME
  40. OPERATION ← UNARY_OPERATION / BIN_OPERATION
  41. OPERAND ← UNOPER? (ARRAY/ STRING / NUMBER / SPECIALS / NAME / BLOCK / CALL )
  42. BIN_OPERATION ← (OPERAND (BINOPER OPERAND)+)
  43. UNARY_OPERATION ← (UNOPER OPERAND)
  44. KWUNOPER ← "not" / "negate" / "complement"
  45. KWBINOPER ← "greater_or_equal" / "lesser_or_equal" /
  46. "plus" / "minus" / "times" / "divide" / "of" / "'s" / "'" /
  47. "and" / "or" / "equals" / "equal" / "differs" / "isn't" /
  48. "is" / "aint" / "greater" / "lesser" / "compare" /
  49. "xor" / "binand" / "binor" / "rshift" / "lshift"
  50. BINOPER ← < [-+/*] / "<-" / "->" /
  51. "&" / "|" / "&&"/ "||" / ":" / "==" / "!=" / "<=>" / "<<" / ">>" / ">=" / "<=" / ">" / "<" / "^" /
  52. KWBINOPER >
  53. UNOPER ← < [-!~] / KWUNOPER >
  54. CONJUNCTION ← < ( "and" / "or" ) > WHITESPACE
  55. ~ARRAY_KEYWORD ← < ( "list" / "array") > WHITESPACE
  56. ARRAY ← ("[" ACONTENTS? "]") / (ARRAY_KEYWORD ACONTENTS? END_KEYWORD)
  57. ARRAY_SEP ← (CONJUNCTION / ",")
  58. ACONTENTS ← (TARGET ARRAY_SEP)* TARGET ARRAY_SEP?
  59. SPECIALS ← "true" / "false" / "nil" / "nothing" / "me" / "my" /
  60. "parent" / "this" / "it" / "its"
  61. # Strings
  62. STRING ← ESCSTR / RAWSTR
  63. # Raw string macro
  64. RAWSM(O,C) ← O < (!(C).)* > C
  65. # Escaped string macro.
  66. ESCSM(O,C) ← O < (!(C)STRCHAR)* > C
  67. ESCSTR ← ESCSM("`", "`") / ESCSM('"', '"')
  68. RAWSTR ← RAWSM('<<', '>>') / RAWSM('«', '»') / RAWSM('‹', '›') / RAWSM('“', '”')
  69. STRESC1 ← "\\" [nrtfv\'\\"\[\]\\]
  70. STRESC2 ← "\\" [0-3] [0-7] [0-7]
  71. STRESC3 ← "\\" [0-7] [0-7]*
  72. STRESC4 ← "\\x" [0-9a-fA-F] [0-9a-fA-F]?
  73. STRESC5 ← "\\u" [0-9a-fA-F]+
  74. STRNOESC ← (!('\\\\').)
  75. STRCHAR ← STRESC1 / STRESC2 / STRESC3 / STRESC4 / STRESC5 / STRNOESC
  76. NUMBER ← DECIMAL / INTEGER
  77. DECIMAL ← < [-]?[0-9]+[.][0-9]+ >
  78. INTEGER ← < [-]?[0-9]+ >
  79. KEYWORD ← BLOCK_KEYWORD / END_KEYWORD / CALL_KEYWORD / HAVING_KEYWORD /
  80. PREPOSITION / ARTICLE / SPECIALS / KWUNOPER /
  81. KWBINOPER
  82. NAME ← ARTICLE? WORD+
  83. VERB ← WORD
  84. WORD ← !KEYWORD < [a-zA-Z_][a-zA-Z0-9_]* >
  85. ESC_EOX ← ([ \t]* "\\" ( "\r\n" / "\r" / "\n"))
  86. ~EOX ← (!ESC_EOX)([ \t]*[\r\n.]+[ \t]*)+
  87. ~WHITESPACE ← < ESC_EOX / [ \t]* >
  88. %whitespace ← WHITESPACE
  89. %word ← [a-zA-Z_][a-zA-Z0-9_]*
  90. # ---
  91. # Expression parsing option
  92. # %expr = BINOPER # Rule to apply 'precedence climbing method' to
  93. # %binop = L && || and or
  94. # %binop = L == equals equal is
  95. # %binop = L + - plus minus
  96. # %binop = L * / times divide
  97. # %binop = L of 's <- -> '