stringlit := "\"(\\\\.|[^\"])*\"";

castname := "[A-Z][A-Z]*[0-9][0-9]*";

ident := "[A-Za-z_][A-Za-z_0-9]*";

label := <ident>;

<opt-index> :=
  '[' <expr> ']',
  ;

var := 
  <ident> <opt-index>;

val := 
  '(' <expr> '?' <expr> : <expr> ')',
  '(' <expr> ')',
  <fncall>,
  <var>,
  <hex-constant>,
  <positive-integer>;

opt-monop :=
  '-', '~', '!'
  ;

typed-val :=
  '(' <castname> ')' <opt-monop> <val>,
  <opt-monop> <val>;

binop :=
  '>>', '<<', '+', '*', '/', '-', '&&', '||', '&', '|', '^', '<=', '<', '>=', '>', '!=', '==';

opt-second_operand :=
  <binop> <typed-val>,
  ;

expr :=
  <typed-val> <opt-second_operand>;

fnname := <ident>;

procname := <ident>;

param-list := <expr> <rest-of-param-list>;

rest-of-param-list :=
  ',' <expr> <rest-of-param-list>,
  ;

ss := 
  "//.*", '/**/';

  '{' <ss-list> '}',
  "case" <selector> ':',
  <label> ':',
  <var> '=' <expr> ';',
  <procname> '(' ')' ';',
  <procname> '(' <param-list> ')' ';',
  <procname> '(' <stringlit> ')' ';',
  "if" '(' <expr> ')' <SS>,
  "goto" <label> ';',
  "JUMP" ';',
  ';';

ss-list :=
  <ss> <ss-list>,
  ;

hex-constant := "0x[0-9A-Fa-f][0-9A-Fa-f]*[Uu]?";

positive-integer := "[0-9][0-9]*";

integer :=
  <hex-constant>,
  <positive-integer>;

selector := <integer>;

