// Parse a primary expression. // // primary-expression: // literal // id-expression // requires-expression // lambda-expression // '(' expression ')' // { Expr_list } Expr& Parser::primary_expression() { switch (lookahead()) { case tk::true_tok: return on_boolean_literal(accept(), true); case tk::false_tok: return on_boolean_literal(accept(), false); case tk::integer_tok: return on_integer_literal(accept()); case tk::identifier_tok: return id_expression(); case tk::requires_tok: return requires_expression(); case tk::lparen_tok: return grouped_expression(); case tk::lbrace_tok: return tuple_expression(); default: break; } error(tokens.location(), "expected primary-expression"); throw Syntax_error(); }
// Parse a declaration. // // declaration: // [specifier-seq] basic-declaration // // basic-declaration: // variable-declaration // function-declaration // type-declaration // concept-declaration Decl& Parser::declaration() { // Parse and cache the specifier sequences. specifier_seq(); switch (lookahead()) { case tk::var_tok: return variable_declaration(); case tk::def_tok: return function_declaration(); case tk::class_tok: return class_declaration(); case tk::concept_tok: lingo_unreachable(); case tk::super_tok: return super_declaration(); default: break; } throw Syntax_error("invalid declaration"); }
// A member is a declaration within a class. // // member-statement: // member-declaration // // member-declaration: // variable-declaration // super-declaration // function-declaration // class-declaration // template-declaration // // TODO: Allow other kinds of statements to support metaprogramming. Stmt& Parser::member_statement() { switch (lookahead()) { // Declaration specifiers. case tk::virtual_tok: case tk::abstract_tok: case tk::static_tok: case tk::inline_tok: case tk::explicit_tok: case tk::implicit_tok: case tk::public_tok: case tk::private_tok: case tk::protected_tok: // Declaration introducers. case tk::var_tok: case tk::super_tok: case tk::def_tok: case tk::class_tok: case tk::template_tok: return declaration_statement(); default: error("expected member-statement"); throw Syntax_error(); } }
// Parse a record declaration. // // record-decl -> 'struct' identifier record-body // // record-body -> '{' field-seq '}' // // field-seq -> field-seq | field-seq field-seq Decl* Parser::record_decl(Specifier spec) { require(struct_kw); Token n = match(identifier_tok); const Type* t = nullptr; // Determine if it is inheriting from a base class if(match_if(colon_tok)){ // We have a base class t = type(); } // record-body and field-seq require(lbrace_tok); Decl_seq fs, ms; while (lookahead() != rbrace_tok) { Specifier spec = specifier_seq(); if (lookahead() == def_kw) { Decl* m = method_decl(spec); ms.push_back(m); } else if(lookahead() == identifier_tok) { Decl* f = field_decl(spec); fs.push_back(f); } else { throw Syntax_error(ts_.location(), "invalid member declaration"); } } match(rbrace_tok); // Need to replace nullptr with base record return on_record(spec, n, fs, ms, t); }
// Parse a template argument. // // template-argument: // type // expression // template-name // // FIXME: The expression must be a constant expression. // // FIXME: In the last instance, the template name can be qualified. Term& Parser::template_argument() { if (Type* t = match_if(&Parser::type)) return *t; if (Expr* e = match_if(&Parser::expression)) return *e; if (Decl* d = match_if(&Parser::template_name)) return *d; throw Syntax_error("expected template-argument"); }
// Parse a leading-name-specifier. This defines the set of // terms that can be nested within a nested-name-specifier. // // nested-name-specifier: // '::' // namespace-name '::' // type-name '::' // decltype-type '::' Decl& Parser::leading_name_specifier() { Decl* scope; if (lookahead() == colon_colon_tok) scope = &on_nested_name_specifier(); else if (lookahead() == decltype_tok) scope = &on_nested_name_specifier(decltype_type()); else if (Decl* n = match_if(&Parser::namespace_name)) scope = &on_nested_name_specifier(*n); else if (Type* t = match_if(&Parser::type_name)) scope = &on_nested_name_specifier(*t); else throw Syntax_error("expected leading-name-specifier"); match(colon_colon_tok); return *scope; }
// Parse a record declaration. // // record-decl -> 'struct' identifier record-body // // record-body -> '{' field-seq '}' // // field-seq -> field-seq | field-seq field-seq Decl* Parser::record_decl(Specifier spec) { require(struct_kw); Token n = match(identifier_tok); // record-body and field-seq require(lbrace_tok); Decl_seq fs, ms; while (lookahead() != rbrace_tok) { Specifier spec = specifier_seq(); if (lookahead() == def_kw) { Decl* m = method_decl(spec); ms.push_back(m); } else if(lookahead() == identifier_tok) { Decl* f = field_decl(spec); fs.push_back(f); } else { throw Syntax_error(ts_.location(), "invalid member declaration"); } } match(rbrace_tok); return on_record(spec, n, fs, ms); }
// Report an error at the current location. void Parser::error(String const& msg) { ++errs_; throw Syntax_error(ts_.location(), msg); }
// Report an error at the current location. void Parser::error(char const* msg) { ++errs_; throw Syntax_error(ts_.location(), msg); }