# Syntax-correctness parser for Tamsin, written in Tamsin.
# Distributed under a BSD-style license; see LICENSE.
# REQUIRES lib/tamsin_scanner.tamsin
# Note that this does not produce any data as a result beyond "yes, it
# parsed" or "no, there was a syntax error". This exists to provide a
# clean, readable grammar. For actual use, see lib/tamsin_parser.tamsin,
# which parses a Tamsin program to an AST.
# If there is any discrepancy between the language this grammar accepts,
# and the language lib/tamsin_parser.tamsin accepts, lib/tamsin_parser.tamsin
# takes precedence.
# Note that this may contain support for some features which are not in
# the current released or pre-released version.
main = grammar using tamsin_scanner:scanner.
grammar = {"@" & pragma & "."} &
{module | production & "."} & eof & 'ok'.
module = word & "{" & {production & "."} & "}".
production = word & ["(" & term & {"," & term} & ")"
| "[" & expr0 & "]"] & "=" & expr0.
expr0 = expr1 & {("|" | "||") & expr1}.
expr1 = expr2 & {("&" | "&&") & expr2}.
expr2 = expr3 & ["using" & prodref | "@" & texpr].
expr3 = expr4 & [("→" | "->") & variable].
expr4 = expr5 & ["/" & texpr & ["/" & term]].
expr5 = "(" & expr0 & ")"
| "[" & expr0 & "]"
| "{" & expr0 & "}"
| "!" & expr5
| "set" & variable & "=" & texpr
| "return" & texpr
| "fail" & texpr
| "print" & texpr
| terminal
| variable & [("←" | "<-") & texpr]
| sq_string
| prodref & ["(" & texpr & {"," & texpr} & ")"].
texpr = term & {"+" & term}.
term = atom & ["(" & [term & {"," & term}] & ")"]
| "[" & [term & {"," & term}] & ["|" & term] & "]"
| variable.
atom = word | sq_string.
terminal = dq_string
| ("«" | "<<") & texpr & ("»" | ">>").
prodref = modref & ":" & word
| ":" & word
| word.
modref = "$" | word.
pragma = "alias" & word & word & "=" & prodref
| "unalias" & word.
word = $:alnum.
variable = $:upper.
sq_string = $:startswith('\'').
dq_string = $:startswith('"').