// Parse a unary type specifier. // // unary-type: // unary-type // '&' unary-type // // FIXME: Rvalue references have not been implemented. Do we actually // need them, or can we get by with parameter passing types. // // NOTE: The parameter passing types (in, out, etc.) do not apply to // cv-qualified types, but can apply to pointers (presumably). It would // be nice if we could make the grammar reflect this, but it means // making lots of weird branches. Type& Parser::prefix_type() { switch (lookahead()) { case amp_tok: { accept(); Type& t = unary_type(); return on_reference_type(t); } default: break; } return unary_type(); }
// Parse a postfix type. // // postfix-type -> primary_type // postfix-type '&' // postfix-type '[]' // | postfix-type '[' expr ']' // // TODO: Allow prefix type expressions. These should // bind more tightly than postfix type expressoins. // // TODO: Suffix notation will require parens for grouping. // For example, a reference to an array would be: // // ref (T[N]) // // We would need to handle function types carefully. Type const* Parser::postfix_type() { Type const* t = primary_type(); while (true) { // reference-type if (match_if(amp_tok)) t = on_reference_type(t); // array-types else if (match_if(lbrack_tok)) { if (match_if(rbrack_tok)) return on_block_type(t); Expr* e = expr(); match(rbrack_tok); t = on_array_type(t, e); } // No postfix operators else break; } return t; }