Riddle Grammar

This is the grammar for Riddle, mostly in BNF, except for some atoms (see below).

    <prog> ::= <EOL>? <stat_list>

    <block> ::= <EOL> <indent> <stat_list> <dedent>
                    | <line_stat>

    <stat_list> ::= <stat_list> <stat>
                    | <stat>

    <stat> ::= <block_stat>
                    | <line_stat> <EOL>

    <block_stat> ::= <if_stat>
                    | <while_stat>
                    | <for_stat>

    <line_stat> ::= <return_stat>
                    | <break_stat>
                    | <expr_stat>

    <if_stat> ::= "if" <expr> ":" <block> <EOL> <else_stat>

    <else_stat> ::= "elif" <expr> ":" <block> <EOL> <else_stat>
                    | "else" ":" <block> <EOL> <else_stat>
                    |

    <while_stat> ::= "while" <expr> ":" <block> <EOL>

    <for_stat> ::= "for" <symbol> "in" <expr> ":" <block> <EOL>

    <return_stat> ::= "return" <expr>
                    | "return"

    <break_stat> ::= "break"

    <expr_stat> ::= <expr>

    <expr> ::= <assign_expr>

    <assign_expr> ::= <cond_expr>
                    | <symbol> "=" <assign_expr>

    <cond_expr> ::= <or_expr>
                    | <or_expr> "?" <expr> ":" <cond_expr>

    <or_expr> ::= <and_expr>
                    | <or_expr> "or" <and_expr>

    <and_expr> ::= <bor_expr>
                    | <and_expr> "and" <bor_expr>

    <bor_expr> ::= <xor_expr>
                    | <bor_expr> "|" <xor_expr>

    <xor_expr> ::= <band_expr>
                    | <xor_expr> "^" <band_expr>

    <band_expr> ::= <eq_expr>
                    | <band_expr> "&" <eq_expr>

    <eq_expr> ::= <rel_expr>
                    | <eq_expr> "==" <rel_expr>
                    | <eq_expr> "!=" <rel_expr>

    <rel_expr> ::= <shift_expr>
                    | <rel_expr> "<" <shift_expr>
                    | <rel_expr> ">" <shift_expr>
                    | <rel_expr> "<=" <shift_expr>
                    | <rel_expr> ">=" <shift_expr>

    <shift_expr> ::= <add_expr>
                    | <shift_expr> "<<" <add_expr>
                    | <shift_expr> ">>" <add_expr>

    <add_expr> ::= <mul_expr>
                    | <add_expr> "+" <mul_expr>
                    | <add_expr> "-" <mul_expr>

    <mul_expr> ::= <unary_expr>
                    | <mul_expr> "*" <unary_expr>
                    | <mul_expr> "/" <unary_expr>
                    | <mul_expr> "%" <unary_expr>

    <unary_expr> ::= <postfix_expr>
                    | "-" <unary_expr>
                    | "~" <unary_expr>
                    | "!" <unary_expr>

    <postfix_expr> ::= <primary_expr>
                    | <postfix_expr> "[" <expr> "]"
                    | <postfix_expr> "(" <expr_list> ")"

    <primary_expr> ::= <symbol>
                    | <number>
                    | <string>
                    | "@" <number>
                    | "(" <expr> ")"
                    | "[" <expr_list> "]"
                    | "{" <pair_list> "}"

    <expr_list> ::= <expr_list> "," <expr>
                    | <expr>
                    |

    <pair> ::= <expr> ":" <expr>

    <pair_list> ::= <pair_list> "," <pair>
                    | <pair>
                    |

And for the atoms:

    <symbol> ::= [a-zA-Z_][a-zA-Z0-9_]*

    <number> ::= 0|([1-9][0-9]*)

    <string> ::= "([^"\\]|[\\]["\\/bfnrt])*"

    <indent> ::= think of Python

    <dedent> ::= keep thinking of Python