Exemplo n.º 1
0
// Parse a primary expression.
//
//    primary-expr -> literal | identifier | '(' expr ')'
//
//    literal -> integer-literal
//             | boolean-literal
//             | character-literal
//             | string-literal
Expr*
Parser::primary_expr()
{
  // identifier
  if (Token tok = match_if(identifier_tok))
    return on_id(tok);

  // boolean-literal
  if (Token tok = match_if(boolean_tok))
    return on_bool(tok);

  // integer-literal
  if (Token tok = match_if(integer_tok))
    return on_int(tok);

  // character-literal
  if (Token tok = match_if(character_tok))
    return on_char(tok);

  // string-literal
  if (Token tok = match_if(string_tok))
    return on_str(tok);

  // paren-expr
  if (match_if(lparen_tok)) {
    Expr* e = expr();
    match(rparen_tok);
    return e;
  }

  // FIXME: Is this definitely an error? Or can we
  // actually return nullptr and continue?
  error("expected primary expression");
}
Exemplo n.º 2
0
// Parse a postfix expression.
//
//    postfix-expression -> postfix-expression '(' argument-list ')'
//                        | postfix-expression '[' expression ']'
//                        | postfix-expression . identifier
//                        | primary-expression
Expr*
Parser::postfix_expr()
{
  Expr* e1 = primary_expr();
  while (true) {
    // dot-expr
    if (match_if(dot_tok)) {
      Token tok = match(identifier_tok);
      Expr* e2 = on_id(tok);
      e1 = on_dot(e1, e2);
    }

    // call-expr
    else if (match_if(lparen_tok)) {
      Expr_seq args;
      while (lookahead() != rparen_tok) {
        args.push_back(expr());
        if (match_if(comma_tok))
          continue;
        else
          break;
      }
      match(rparen_tok);
      e1 = on_call(e1, args);
    }

    // index-expr
    else if (match_if(lbrack_tok)) {
      Expr* e2 = expr();
      match(rbrack_tok);
      e1 = on_index(e1, e2);
    }

    // anything else
    else {
      break;
    }
  }
  return e1;
}
Exemplo n.º 3
0
Expr const*
Parser::id()
{
  Token tok = require(identifier_tok);
  return on_id(tok);
}