示例#1
0
// Parse a variable declaration.
//
//    variable-decl -> 'var' identifier object-type initializer-clause
//
//    initializer-clause -> ';' | '=' 'trivial' ';' | '=' expr ';'
Decl*
Parser::variable_decl(Specifier spec)
{
  require(var_kw);
  Token n = match(identifier_tok);

  // object-type
  match(colon_tok);
  Type const* t = type();

  // default initialization (var x : T;)
  if (match_if(semicolon_tok))
    return on_variable(spec, n, t);

  // value initialization (var x : T = e;)
  match(equal_tok);
  if (match_if(trivial_kw)) {
    match(semicolon_tok);
    return on_variable(spec, n, t, trivial_kw);
  }

  Expr* e = expr();
  match(semicolon_tok);
  return on_variable(spec, n, t, e);
}
示例#2
0
// Parse a relational expression.
//
//    relational-expression:
//      shift-expression:
//      relational-expression '<' shift-expression
//      relational-expression '>' shift-expression
//      relational-expression '<=' shift-expression
//      relational-expression '>=' shift-expression
//      relational-expression '<=>' shift-expression
Expr&
Parser::relational_expression()
{
  Expr* e1 = &shift_expression();
  while (true) {
    if (Token tok = match_if(tk::lt_tok)) {
      Expr& e2 = shift_expression();
      e1 = &on_lt_expression(tok, *e1, e2);
    } else if (Token tok = match_if(tk::gt_tok)) {
      Expr& e2 = shift_expression();
      e1 = &on_gt_expression(tok, *e1, e2);
    } else if (Token tok = match_if(tk::lt_eq_tok)) {
      Expr& e2 = shift_expression();
      e1 = &on_le_expression(tok, *e1, e2);
    } else if (Token tok = match_if(tk::gt_eq_tok)) {
      Expr& e2 = shift_expression();
      e1 = &on_ge_expression(tok, *e1, e2);
    } else if (Token tok = match_if(tk::lt_eq_gt_tok)) {
      Expr& e2 = shift_expression();
      e1 = &on_cmp_expression(tok, *e1, e2);
    } else {
      break;
    }
  }
  return *e1;
}
示例#3
0
// Parse a function declaration.
//
//    function-decl -> 'def' identifier parameter-clause return-type ';'
//                   | 'def' identifier parameter-clause return-type function-definition
//    parameter-clause -> '(' [parameter-list] ')'
//
//    parameter-list -> parameter-decl | parameter-decl ',' parameter-list
//
//    return-type -> '->' type
//
//    function-definition -> block-stmt
//
// A function declaration may not have a definition.
Decl*
Parser::function_decl(Specifier spec)
{
  require(def_kw);
  Token n = match(identifier_tok);

  // parameter-clause
  Decl_seq parms;
  match(lparen_tok);
  while (lookahead() != rparen_tok) {
    Decl* p = parameter_decl();
    parms.push_back(p);

    if (match_if(comma_tok))
      continue;
    else
      break;
  }
  match(rparen_tok);

  // return-type
  match(arrow_tok);
  Type const* t = type();

  // function declaration
  if (match_if(semicolon_tok))
    return on_function(spec, n, parms, t);

  // function-definition.
  Stmt* s = block_stmt();

  return on_function(spec, n, parms, t, s);
}
示例#4
0
// Parse a class definition.
//
//    class-declaration:
//      'class' identifier [':']            class-body
//      'class' identifier [':' type]       class-body
//      'class' identifier [':' extension]  class-body
//
// NOTE: The parser currently allows the omission of the ':' because it
// looks weird when the kind is not given explicitly omitted.
//
// TODO: We could use '=' notation in bodies to create new derived types.
Decl&
Parser::class_declaration()
{

  Match_token_pred end_kind(*this, lbrace_tok);

  require(class_tok);
  Name& name = identifier();

  // Match the metatype.
  Type* kind;
  if (match_if(colon_tok)) {
    if (match_if(extension_tok))
      return extension_declaration(name, &cxt.get_type_type());
    if (next_token_is(lbrace_tok))
      kind = &cxt.get_type_type();
    else
      kind = &unparsed_type(end_kind);
  } else {
    kind = &cxt.get_type_type();
  }

  // Point of declaration.
  Decl& decl = start_class_declaration(name, *kind);
  Enter_scope scope(cxt, cxt.saved_scope(decl));

  // Match the class body.
  Def& def = class_body();
  
  return finish_class_definition(decl, def);
};
示例#5
0
文件: parser.cpp 项目: Jenny-fa/lingo
// Parse a unary epxression. A unary expressions is one
// that begins with an operator and is followed by a
// unary expression.
//
//    unary-expression ::=
//        primary-expression
//      | unary-operator unary-expression.
Expr const*
Parser::unary()
{
  if (Token tok = match_if(plus_tok))
    return on_unary(tok, unary());
  if (Token tok = match_if(minus_tok))
    return on_unary(tok, unary());
  return primary();
}
示例#6
0
// 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");
}
示例#7
0
// Parse a nested-name specifier.
//
//    nested-name-specifier:
//      leading-name-specifier
//      nested-name-specifier identifier '::'
//      nested-name-specifier simple-template-id '::'
//
// Here, the identifier and simple-template-id must be either
// namespaces or types. In dependent contexts, those could also
// be members of an unknown specialization.
Decl&
Parser::nested_name_specifier()
{
  Decl* scope = &leading_name_specifier();
  while (true) {
    if (Token id = match_if(identifier_tok))
      scope = &on_nested_name_specifier(*scope, id);
    else if (Name* id = match_if(&Parser::simple_template_id))
      scope = &on_nested_name_specifier(*scope, *id);
    else
      break;
  }
  return *scope;
}
示例#8
0
文件: parser.cpp 项目: Jenny-fa/lingo
// Parse an additive expression.
//
//    additive-expression ::=
//        multiplicative-expression
//      | additive-expression additive-operator multiplicative-expression
Expr const*
Parser::additive()
{
  Expr const* e = multiplicative();
  while (true) {
    if (Token tok = match_if(plus_tok))
      e = on_binary(tok, e, multiplicative());
    else if (Token tok = match_if(minus_tok))
      e = on_binary(tok, e, multiplicative());
    else
      break;
  }
  return e;
}
示例#9
0
文件: parser.cpp 项目: Jenny-fa/lingo
// Parse a multiplicative expression.
//
//    multiplicative-expression ::=
//        unary-expression
//      | multiplicative-expression multiplicative-operator unary-expression
Expr const*
Parser::multiplicative()
{
  Expr const* e = unary();
  while (true) {
    if (Token tok = match_if(star_tok))
      e = on_binary(tok, e, unary());
    else if (Token tok = match_if(slash_tok))
      e = on_binary(tok, e, unary());
    else if (Token tok = match_if(percent_tok))
      e = on_binary(tok, e, unary());
    else
      break;
  }
  return e;
}
示例#10
0
// NOTE ADD LAMDBA PARSER HERE
Expr*
Parser::lambda_expr()
{
  require(bslash_tok);

  //Match the identifier inserted earlier
  Token n = match(identifier_tok);
  // parameter-clause
  Decl_seq parms;
  match(lparen_tok);
  while (lookahead() != rparen_tok)
  {

    Decl* p = parameter_decl();

    parms.push_back(p);
    if (match_if(comma_tok))
    {
      continue;
    }
    else
      break;
  }
  match(rparen_tok);

  // return-type
  match(arrow_tok);
  Type const* t = type();
  // must be function-definition
  Stmt* s = block_stmt();

  //return a lambda expression
  return on_lambda(n, parms, t, s);
}
示例#11
0
// Parse a type template parameter.
//
//    type-template-parameter:
//        typename [identifier] ['='' type]
//
// Note that the point of declaration for a template parameter is
// past the full definition (after the default argument, if present).
Decl&
Parser::type_template_parameter()
{
  match(tk::typename_tok);

  // Get the optional identifier. Create a placeholder
  // if no name is given.
  Name* n;
  if (Token id = match_if(tk::identifier_tok))
    n = &on_simple_id(id);
  else
    n = &build.get_id();

  // Parse the default argument.
  Type* t = nullptr;
  if (lookahead() == tk::eq_tok)
    t = &type();

  // Point of declaration.
  Decl* d;
  if (t)
    d = &on_type_template_parameter(*n, *t);
  else
    d = &on_type_template_parameter(*n);
  return *d;
}
示例#12
0
// Parse a method declaration.
//
//
//    method-decl -> 'def' identifier parameter-clause return-type function-definition
//
// Note that methods must be declared inside
// the class.
//
// TODO: Support out-of-class definitions?
//
// TODO: Support specifiers to modify the "this"
// parameter. Maybe before the return type? Maybe
// as part of the specifiers?
//
// TODO:
//
//    struct R {
//      const def f() -> void { }   // Why not...
Decl*
Parser::method_decl(Specifier spec)
{
  require(def_kw);
  Token n = match(identifier_tok);

  //check for a this_kw
  //do stuff
  //return on_ctor <- reference on_method

  // parameter-clause
  Decl_seq parms;
  match(lparen_tok);
  while (lookahead() != rparen_tok) {
    Decl* p = parameter_decl();
    parms.push_back(p);

    if (match_if(comma_tok))
      continue;
    else
      break;
  }
  match(rparen_tok);

  // return-type
  match(arrow_tok);
  Type const* t = type();

  // function-definition.
  Stmt* s = block_stmt();

  return on_method(spec, n, parms, t, s);
}
示例#13
0
// Parse a unary expression.
//
//    unary-expr -> '+' unary-expr
//                | '-' unary-expr
//                | '!' unary-expr
//                | postfix-expr
Expr*
Parser::unary_expr()
{
  if (match_if(plus_tok)) {
    Expr* e = unary_expr();
    return on_pos(e);
  } else if (match_if(minus_tok)) {
    Expr* e = unary_expr();
    return on_neg(e);
  } else if (match_if(not_tok)) {
    Expr* e = unary_expr();
    return on_not(e);
  } else {
    return postfix_expr();
  }
}
示例#14
0
文件: parser.cpp 项目: cjb129/beekar
// 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);
}
示例#15
0
// Parse a sequence of declaration specifiers.
//
//    specifier-seq -> specifier | specifier-seq specifier
Specifier
Parser::specifier_seq()
{
  Specifier spec = no_spec;
  while (true) {
    if (match_if(foreign_kw))
      spec |= foreign_spec;
    else if (match_if(abstract_kw))
      spec |= abstract_spec;
    else if (match_if(virtual_kw))
      spec |= virtual_spec;
    else
      break;
  }
  return spec;
}
示例#16
0
// Parse a variable declaration.
//
//    variable-declaration:
//      'var' identifier ':' [template-header] type ';'
//      'var' identifier ':' [template-header] type '=' initializer ';'
//      'var' identifier ':' '=' initializer ';'
//
// TODO: Are there other forms of variable declaration?
Decl&
Parser::variable_declaration()
{
  // Helper functions.
  Match_any_token_pred end_type(*this, tk::eq_tok, tk::semicolon_tok);
  Match_token_pred     end_init(*this, tk::semicolon_tok);

  require(tk::var_tok);
  Name& name = identifier();
  match(tk::colon_tok);

  // Match the ":=" form.
  // if (match_if(tk::eq_tok)) {
  //   Type& type = cxt.get_auto_type(object_type);
  //   Expr& init = unparsed_expression(end_init);
  //   match(tk::semicolon_tok);
  //   return on_variable_declaration(name, type, init);
  // }

  // Match the type.
  Type& type = unparsed_type(end_type);

  // Match the "name : type =" form.
  if (match_if(tk::eq_tok)) {
    Expr& init = unparsed_expression(end_init);
    match(tk::semicolon_tok);
    return on_variable_declaration(name, type, init);
  }

  // Otherwise, match the "name : type ;" form.
  match(tk::semicolon_tok);
  return on_variable_declaration(name, type);
}
示例#17
0
// 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;
}
示例#18
0
// Parse an equality expression.
//
//    equality-expr -> equality-expr '<' ordering-expr
//                   | equality-expr '>' ordering-expr
//                   | equality-expr '<=' ordering-expr
//                   | equality-expr '>=' ordering-expr
//                   | ordering-expr
Expr*
Parser::equality_expr()
{
  Expr* e1 = ordering_expr();
  while (true) {
    if (match_if(eq_tok)) {
      Expr* e2 = ordering_expr();
      e1 = on_eq(e1, e2);
    } else if (match_if(ne_tok)) {
      Expr* e2 = ordering_expr();
      e1 = on_ne(e1, e2);
    } else {
      break;
    }
  }
  return e1;
}
示例#19
0
// Parse an additive expression.
//
//    additive-expr -> additive-expr '*' multiplicative-expr
//                   | additive-expr '/' multiplicative-expr
//                   | multiplicative-expr
Expr*
Parser::additive_expr()
{
  Expr* e1 = multiplicative_expr();
  while (true) {
    if (match_if(plus_tok)) {
      Expr* e2 = multiplicative_expr();
      e1 = on_add(e1, e2);
    } else if (match_if(minus_tok)) {
      Expr* e2 = multiplicative_expr();
      e1 = on_sub(e1, e2);
    } else {
      break;
    }
  }
  return e1;
}
示例#20
0
// Parse an additive expression.
//
//    additive-expression:
//      multiplicative-expression:
//      additive-expression '+' multiplicative-expression
//      additive-expression '-' multiplicative-expression
Expr&
Parser::additive_expression()
{
  Expr* e1 = &multiplicative_expression();
  while (true) {
    if (Token tok = match_if(tk::plus_tok)) {
      Expr& e2 = multiplicative_expression();
      e1 = &on_add_expression(tok, *e1, e2);
    } else if (Token tok = match_if(tk::minus_tok)) {
      Expr& e2 = unary_expression();
      e1 = &on_sub_expression(tok, *e1, e2);
    } else {
      break;
    }
  }
  return *e1;
}
示例#21
0
// Parse a shift expression.
//
//    shift-expression:
//      additive_expression:
//      shift-expression '<<' additive_expression
//      shift-expression '>>' additive_expression
//
Expr&
Parser::shift_expression()
{
  Expr* e1 = &additive_expression();
  while (true) {
    if (Token tok = match_if(tk::lt_lt_tok)) {
      Expr& e2 = additive_expression();
      e1 = &on_lsh_expression(tok, *e1, e2);
    } else if (Token tok = match_if(tk::gt_gt_tok)) {
      Expr& e2 = additive_expression();
      e1 = &on_rsh_expression(tok, *e1, e2);
    } else {
      break;
    }
  }
  return *e1;
}
示例#22
0
// Parse an equality expression.
//
//    equality-expression:
//      relational-expression:
//      equality-expression '==' relational-expression
//      equality-expression '!=' relational-expression
Expr&
Parser::equality_expression()
{
  Expr* e1 = &relational_expression();
  while (true) {
    if (Token tok = match_if(tk::eq_eq_tok)) {
      Expr& e2 = relational_expression();
      e1 = &on_eq_expression(tok, *e1, e2);
    } else if (Token tok = match_if(tk::bang_eq_tok)) {
      Expr& e2 = relational_expression();
      e1 = &on_ne_expression(tok, *e1, e2);
    } else {
      break;
    }
  }
  return *e1;
}
示例#23
0
// Parse a qualified type.
//
//    unary-type:
//      postfix-type
//      '*' unary-type 
//      'const' unary-type
//      'volatile' unary-type
Type&
Parser::unary_type()
{
  if (match_if(const_tok)) {
    Type& t = unary_type();
    return on_const_type(t);
  }
  if (match_if(volatile_tok)) {
    Type& t = unary_type();
    return on_volatile_type(t);
  }
  if (match_if(star_tok)) {
    Type& t = unary_type();
    return on_pointer_type(t);
  }
  return postfix_type();
}
示例#24
0
// Parse a suffix type specifier.
//
//    suffix-type:
//      prefix-type ['...']
Type&
Parser::suffix_type()
{
  Type& t = prefix_type();
  if (match_if(ellipsis_tok))
    return on_pack_type(t);
  return t;
}
示例#25
0
// Parse a type name.
//
//    type-name:
//      class-name
//      union-name
//      enum-name
//      type-alias
//
// Note that all of these names are either identifiers or
// simple-template-ids. Match syntactically and differentiate
// semantically.
Type&
Parser::type_name()
{
  if (Name* n = match_if(&Parser::simple_template_id))
    return on_type_name(*n);
  Token id = match(identifier_tok);
  return on_type_name(id);
}
示例#26
0
文件: parser.cpp 项目: Jenny-fa/lingo
// arrow-type: base-type '->' arrow_type
//             type
Type const*
Parser::arrow_type()
{
    Type const* t = primary_type();
    if (match_if(arrow_tok))
        t = on_arrow_type(t, arrow_type());
    return t;
}
示例#27
0
// Parse a type-alias.
//
//    type-alias:
//      identifier
//      template-id
Type&
Parser::type_alias()
{
  if (Name* n = match_if(&Parser::template_id))
    return on_type_alias(*n);
  Token id = match(identifier_tok);
  return on_type_alias(id);
}
示例#28
0
// Parse a namespace-alias.
//
//    namespace-alias:
//      identifier
//      template-id
Decl&
Parser::namespace_alias()
{
  if (Name* n = match_if(&Parser::template_id))
    return on_namespace_alias(*n);
  Token id = match(identifier_tok);
  return on_namespace_alias(id);
}
示例#29
0
// Parse a type list.
//
//    type-list:
//      type
//      type-list ',' type
Type_list
Parser::type_list()
{
  Type_list types;
  types.push_back(type());
  while (match_if(comma_tok))
    types.push_back(type());
  return types;
}
示例#30
0
// Parse a template parameter list.
//
//    template-parameter-list:
//      template-parameter
//      template-parameter-list ',' template-parameter
Decl_list
Parser::template_parameter_list()
{
  Decl_list ds;
  do {
    Decl& d = template_parameter();
    ds.push_back(d);
  } while (match_if(tk::comma_tok));
  return ds;
}