Appendix C. Pike BNF

 program              ::=   definition+
 definition           ::=   import | inheritance | function_declaration | function_definition | variables | constant | class_def
 import               ::=   modifiers+ "import" ( constant_identifier | string ) ";" 
 inheritance          ::=   modifiers+ "inherit" program_specifier ( ":" identifier )? ";" 
 function_declaration ::=   modifiers+ type identifier "(" ( arguments | prot_arguments )? ")" ";"
 function_definition  ::=   modifiers+ type identifier "(" arguments? ")" block 
 variables            ::=   modifiers+ type variable_names ";"
 variable_names       ::=   variable_name ( "," variable_name )*
 variable_name        ::=   identifier ( "=" expression2 )?
 constant             ::=   modifiers+ "constant" constant_names ";" 
 constant_names       ::=   constant_name ( "," constant_name )*
 constant_name        ::=   identifier "=" expression2
 class_def            ::=   modifiers+ class ";"?

 class                ::=   "class" identifier? ( "(" arguments ")" )? "{" program "}"
 modifiers            ::=   ( "extern" | "final" | "inline" | "local" | "nomask" | "optional" | "private" |
                              "protected" | "public" | "static" | "variant" )
 block                ::=   "{" statement* "}"
 statement            ::=   expression ";" | cond | while | do_while | for | switch | return | block | foreach | ";" 
 cond                 ::=   "if" statement ( "else" statement )?
 while                ::=   "while" "(" expression ")" statement
 do_while             ::=   "do" statement "while" "(" expression ")" ";" 
 for                  ::=   "for" "(" expression? ";" expression? ";" expression? ")" statement
 switch               ::=   "switch" "(" expression ")" block
 case_block           ::=   "{" ( case | default | statement | break | continue )* "}"
 case                 ::=   "case" expression [ ".." expression ] ":"
 default              ::=   "default" ":"

 foreach              ::=   "foreach" "(" expression "," expression6 ")" statement

 break                ::=   "break" ";"
 continue             ::=   "continue" ";"
 expression           ::=   expression2 ( "," expression2 )*
 expression2          ::=   ( lvalue ( "=" | "+=" | "*=" | "/=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "%=" ) )* expression3
 expression3          ::=   expression4 '?' expression3 ":" expression3 
 expression4          ::=   ( expression5 ( "||" | "&&" | "|" | "^" | "&" | "==" | "!=" | ">" | "<" | ">=" | "<=" | "<<" |
                            ">>" | "+" | "*" | "/" | "%" ) )* expression5
 expression5          ::=   expression6 | "(" type ")" expression5 | "--" expression6 | "++" expression6 | expression6 "--" |
                            expression6 "++" | "~" expression5 | "-" expression5 
 expression6          ::=   string | int | float | catch | gauge | typeof | sscanf | lambda | class | constant_identifier | call |
                            index | mapping | multiset | array | parenthesis | arrow 
 int                  ::=   "-"? ( number | "'" character "'" )
 number               ::=   "-"? ( ["1" - "9"] digit* | hex_number | bin_number | oct_number )
 hex_number           ::=   "0" ( "x" | "X" ) ( digits | ["a" - "f"] | ["A" - "F"] )+
 bin_number           ::=   "0" ( "b" | "B" ) ( "1" | "0" )+
 oct_number           ::=   "0" ["0" - "7"]*
 float                ::=   "-"? digit+ "." digit+ ( ( "e" | "E" ) "-"? digit+ )?
 catch                ::=   "catch" ( "(" expression ")" | block )
 gauge                ::=   "gauge" ( "(" expression ")" | block )
 sscanf               ::=   "sscanf" "(" expression2 "," expression2 ( "," lvalue )* ")" 
 lvalue               ::=   expression6 | type identifier | "[" ( lvalue ( "," lvalue )* ","? )? "]"
 lambda               ::=   "lambda" "(" arguments? ")" block
 constant_identifier  ::=   "."? identifier ( "." identifier )*
 call                 ::=   expression6 "(" expression_list ")" 
 index                ::=   expression6 "[" ( expression | ".." expression | expression ".." | expresion ".." expresion ) "]"
 array                ::=   "({" expression_list "})"
 multiset             ::=   "(<" expression_list ">)"
 mapping              ::=   "([" ( expression ":" expression ( "," expression ":" expression )* ","? )? "])"
 arrow                ::=   expression6 "->" identifier
 parenthesis          ::=   "(" expression ")"
 expression_list      ::=   ( splice_expression ( "," splice_expression )* ","? )?
 splice_expression    ::=   "@"? expression2
 type                 ::=   int_type | "string" | "float" | "program" | object_type | program_specifier |
                            mapping_type | array_type | multiset_type | function [ function_type ]
 int_type             ::=   "int" ( "(" ( digit+ | ".." digit+ | digit+ ".." | digit+ ".." digit+ ) ")" )?
 object_type          ::=   "object" ( "(" program_specifier ")" )?
 mapping_type         ::=   "mapping" ( "(" type ":" type ")" )?
 array_type           ::=   "array" ( "(" type ")" )?
 multiset_type        ::=   "multiset" ( "(" type ")" )?
 function_type        ::=   "function"  ( "(" type ( "," type )* "..."? ":" type ")" )?
 arguments            ::=   ( argument ( "," argument )* varargs? | varargs ) ","?
 argument             ::=   type identifier
 varargs              ::=   type "..." identifier
 prot_arguments       ::=   ( type ( "," type )* ( type "..." )? | ( type "..." ) ) ","?
 program_specifier    ::=   string_constant | constant_identifier
 string               ::=   ( 0x22 string_literal* 0x22 )+
 string_literal       ::=   [0x0000 - 0xffff] | "\" [0x00 - 0xff] | "\" number
 identifier           ::=   letter { letter | digit } | "`+" | "`/" | "`%" | "`*" | "`&" | "`|" | "`^" | "`~" |
                            "`<" | "`<<" | "`<=" | "`>" | "`>>" | "`>=" | "`==" | "`!=" | "`!" | "`()" | "`-" |
                            "`->" | "`->=" | "`[]" | "`[]="
 letter               ::=   ["a"-"z"] | ["A"-"Z"] | "_"
 digit                ::=   ["0"-"9"]