コード例 #1
0
ファイル: parser.c プロジェクト: joycetoh8/cs61c-fo
AST *build_ast (lexer *lex) {
    /* TODO: Implement me. */
    /* Hint: switch statements are pretty cool, and they work 
     *       brilliantly with enums. */
    if (lex) {
        AST *ast = safe_malloc(sizeof(AST));
        token_type ast_type;
        char *ast_val;
        read_token(lex);
        if (peek_type(lex) == token_CLOSE_PAREN) {
            num_paren--;
            if (num_paren < 0) {
                fatal_error("Extra close parenthesis");
            } else {
                return NULL;
            }
        } else if (peek_type(lex) == token_END) {
            if (num_paren != 0) {
                fatal_error("Uneven number of parenthesis");
            } else {
                return NULL;
            }
        } else if (peek_type(lex) == token_OPEN_PAREN) {
            AST *struct_num; // for when we get a node_STRUCT
            num_paren++;
            read_token(lex);
            ast_type = peek_type(lex);
            ast_val = peek_value(lex);
            if (ast_type == token_CLOSE_PAREN) {
                fatal_error("Empty pair of parenthesis");
            } else if (ast_type == token_NAME) { //any variable name that comes after ( will be a function call
                ast->type = node_CALL;
            } else if (ast_type == token_KEYWORD) { // if it's a keyword, use smap
                if (!strcmp(ast_val,"None")) {
                    ast->type = node_INT;
                    ast_val = "0";
                } else {
                    ast->type = lookup_keyword_enum(ast_val);
                    if (ast->type == node_STRUCT) {
                        struct_num = safe_malloc(sizeof(AST));
                        struct_num->type = node_STRING;
                        struct_num->children = NULL;
                        struct_num->last_child = NULL;
                        struct_num->val = safe_malloc(8*sizeof(char));
                        sprintf(struct_num->val,"struct%d",num_structs);
                        num_structs++;
                    }
                }
            } else if (ast_type == token_INT || ast_type == token_STRING) {
                fatal_error("INT/STRING lone in parenthesis");
            } else if (ast_type == token_OPEN_PAREN) {
                fatal_error("Two consecutive open parenthesis");
            } else if (ast_type == token_END) {
                fatal_error("Abrupt end after open parenthesis");
            }
           
            ast->val = safe_malloc((strlen(ast_val) + 1) * sizeof(char));
            strcpy(ast->val, ast_val);
            ast->children = safe_malloc(sizeof(AST_lst));
            AST_lst *children = ast->children;
            // somewhere here fit the struct_num child in!!
            if (ast->type == node_STRUCT) {
                ast->last_child = children;
                children->val = struct_num;
                children->next = safe_malloc(sizeof(AST_lst));
                children = children->next;
            }
            AST *temp = build_ast(lex);
            if (temp == NULL && ast->type != node_STRUCT) {
                ast->children = NULL;
                ast->last_child = NULL;
            } else {
                while (temp != NULL) {
                    ast->last_child = children;
                    children->val = temp;
                    children->next = safe_malloc(sizeof(AST_lst));
                    children = children->next;
                    temp = build_ast(lex);
                }
                (ast->last_child)->next = NULL;
            }
            free(children);// free next of last child for which we malloced space earlier, thinking there existed a next.
            if (ast->type == node_FUNCTION) {
                ((ast->children)->val)->type = node_VAR;
                smap_put(num_args,((ast->children)->val)->val,AST_lst_len(((ast->children)->val)->children));
            }
        } else {
            ast_type = peek_type(lex);
            ast_val = peek_value(lex);
            if (ast_type == token_NAME) {
                ast->type = node_VAR;
            } else if (ast_type == token_KEYWORD) {
                if (!strcmp(ast_val,"None")) {
                    ast->type = node_INT;
                    ast_val = "0";
                } else {
                    ast->type = lookup_keyword_enum(ast_val);
                }
            }
            ast->val = safe_malloc((strlen(ast_val) + 1) * sizeof(char));
            strcpy(ast->val, ast_val);
            ast->children = NULL;
            ast->last_child = NULL;
        }
        switch (ast_type) {
            case token_INT:
                ast->type = node_INT;
                break;
            case token_STRING:
                ast->type = node_STRING;
                break;
        }
        return ast;
    } 
    return NULL;
}
コード例 #2
0
ファイル: text-composable.c プロジェクト: aral/libot
void text_op_transform2(text_op *result, text_op *op, text_op *other, bool isLefthand) {
  init_op(result);
  
  if (op->components == NULL && op->content.type == NONE) {
    return;
  }
  
  op_iter iter = {};
  
  text_op_component *other_components = other->components;
  size_t num_other_components;
  
  text_op_component inline_components[2];
  if (other_components == NULL) {
    other_components = inline_components;
    if (other->content.type == NONE) {
      num_other_components = 0;
    } else if (other->skip == 0) {
      num_other_components = 1;
      inline_components[0] = other->content;
    } else {
      num_other_components = 2;
      inline_components[0].type = SKIP;
      inline_components[0].num = other->skip;
      inline_components[1] = other->content;
    }
  } else {
    num_other_components = other->num_components;
  }
  
  for (int i = 0; i < num_other_components; i++) {
    if (peek_type(op, iter) == NONE) {
      break;
    }
    
    switch (other_components[i].type) {
      case SKIP: {
        size_t num = other_components[i].num;
        
        while (num > 0) {
          text_op_component c = take(op, &iter, num, INSERT);
          if (c.type == NONE) {
            break;
          }
          append(result, c);
          if (c.type != INSERT) {
            num -= c.num;
          }
        }
        break;
      }
      case INSERT: {
        // If isLeftHand and there's an insert next in the current op, the insert should go first.
        if (isLefthand && peek_type(op, iter) == INSERT) {
          // The left insert goes first.
          append(result, take(op, &iter, SIZE_MAX, NONE));
        }
        if (peek_type(op, iter) == NONE) {
          break;
        }
        text_op_component skip = {SKIP};
        skip.num = str_num_chars(&other_components[i].str);
        append(result, skip);
        break;
      }
      case DELETE: {
        size_t num = other_components[i].num;
        
        while (num > 0) {
          text_op_component c = take(op, &iter, num, INSERT);
          
          switch (c.type) {
            case NONE:
              num = 0;
              break;
            case SKIP:
              num -= c.num;
              break;
            case INSERT:
              append(result, c);
              break;
            case DELETE:
              // The delete is unnecessary now.
              num -= c.num;
              break;
          }
        }
        break;
      }
      default:
        assert(0);
    }
  }
  
  while (iter.idx < (op->components ? op->num_components : 2)) {
    // The op doesn't have skips at the end. Just copy everything.
    append(result, take(op, &iter, SIZE_MAX, NONE));
  }
  
  // Trim any trailing skips from the result.
  if (result->components) {
    while (result->num_components && result->components[result->num_components - 1].type == SKIP) {
      result->num_components--;
    }
  }
}