Ejemplo n.º 1
0
builder_t* builder_create(const char* description)
{
  if(description == NULL)
    return NULL;

  source_t* source = source_open_string(description);
  symtab_t* symtab = symtab_new();

  ast_t* ast = build_ast(source, symtab);

  if(ast == NULL)
  {
    // Error, tidy up
    source_close(source);
    symtab_free(symtab);
    return NULL;
  }

  // Success, create builder
  builder_t* builder = POOL_ALLOC(builder_t);

  builder->sources = NULL;
  builder->defs = symtab;
  builder->dummy_root = ast_blank(TK_TEST);

  ast_add(builder->dummy_root, ast);
  add_source(builder, source);

  return builder;
}
Ejemplo n.º 2
0
void build_ast(node *root){

  if(root==NULL)
    return;

  if(strcmp(root->str_type,"FuncDefinition")==0)
    go_to_funcbody(root);

  build_ast(root->brother);
}
Ejemplo n.º 3
0
static ast_t* builder_add_ast(builder_t* builder, const char* description)
{
  assert(builder != NULL);
  assert(description != NULL);

  source_t* source = source_open_string(description);
  ast_t* ast = build_ast(source, builder->defs);

  if(ast == NULL)
  {
    // Error, tidy up
    source_close(source);
    return NULL;
  }

  // Success, add new source to builder
  add_source(builder, source);

  return ast;
}
Ejemplo n.º 4
0
int
parse(char *file)
{
    token *tokens[MAX_TOKEN_NUM];
    ast *syntax_tree;

    int token_count = tokenise(file, tokens);
    if (tokens == NULL) {
        fprintf(stderr, "Couldn't read file: %s\n", file);
        return -1;
    }

    show_tokens(tokens, token_count);

    build_ast(tokens, syntax_tree);
    if (syntax_tree == NULL) {
        fprintf(stderr, "Couldn't parse file: %s\n", file);
        return -1;
    }

    pretty_print_ast(syntax_tree);

    return 0;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
//main function - call with the name of the AST input file
int main(int argc, char **argv) 
{
	//generate the array of quads (okay we have a limit of 10,000 - we really don't think people
	//in C48 will get beyond this using our compiler - consider it a "compiler limit"
	quads = calloc(10000, sizeof(Quad *));
	
	//CODE FROM THC's ast.c
	if (argc != 2) {
		fprintf(stderr, "Usage: %s input_file\n", argv[0]);
		return -1;
	}
	
	ast_node root;
	
	printf("Building AST\n");
	
	root = build_ast(argv[1]); /* build an abstract syntax tree */
	
	printf("Printing AST\n");
	
	print_ast(root, 0);		      /* and print it out */
	
	printf("Creating Symbol Table\n");
	
	//OUR CODE AGAIN
	//create symbol table
	symtab = CreateSymbolTable();
	//now we call CG of the root node
	
	InsertIntoSymbolTable(symtab, "dog");
	
	printf("Calling CG on root node\n");
	
	CG(root);
	
	//print all of our quads for debug purposes
	int i = 0;
	//char a1[5];
	//char a2[5];
	//char a3[5];
	
	printf("Entering Debug Printing While Loop - we have %d quads and they are:\n", currentQuad);
	
	FILE *qfile;
	qfile = fopen("quadsout.txt","w");
	
	while(quads[i] != NULL)
	{
		char* a1 = malloc(sizeof(char) * 15);
		char* a2 = malloc(sizeof(char) * 15);
		char* a3 = malloc(sizeof(char) * 15);
		printf("Printing quad %d", i);
		//printf("entered while\n");
		switch (quads[i]->addr1.kind) 
		{
			case Empty:
				a1 = " - ";
				break;
			case IntConst:
				sprintf(a1,"%d",quads[i]->addr1.contents.val);
				break;
			case DouConst:
				sprintf(a1,"%f",quads[i]->addr1.contents.dval);
				break;
			case String:
				//printf("%s", quads[i]->addr1.contents.name);
				a1 = quads[i]->addr1.contents.name;
				//printf("%s", a1);
				break;
			default:
				break;
		}
		
		switch (quads[i]->addr2.kind) 
		{
			case Empty:
				a2 = " - ";
				break;
			case IntConst:
				sprintf(a2,"%d",quads[i]->addr2.contents.val);
				break;
			case DouConst:
				sprintf(a2,"%f",quads[i]->addr2.contents.dval);
				break;
			case String:
				//printf("%s", quads[i]->addr2.contents.name);
				a2 = quads[i]->addr2.contents.name;
				break;
			default:
				break;
		}
		
		switch (quads[i]->addr3.kind) 
		{
			case Empty:
				a3 = " - ";
				break;
			case IntConst:
				sprintf(a3,"%d",quads[i]->addr3.contents.val);
				break;
			case DouConst:
				sprintf(a3,"%f",quads[i]->addr3.contents.dval);
				break;
			case String:
				//printf("%s", quads[i]->addr3.contents.name);
				a3 = quads[i]->addr3.contents.name;
				break;
			default:
				break;
		}
		
		//printf("Finished switches, printing quad details\n");
		//printf("%s",a1);
		//printf("%s",a2);
		//printf("%s",a3);
		printf("(%s,%s,%s,%s)\n",namesOfOps[quads[i]->op],a1,a2,a3);
		fprintf(qfile, "(%s,%s,%s,%s)\n",namesOfOps[quads[i]->op],a1,a2,a3);
		i++;
	}
	fclose(qfile);
	
	/*
	EnterScope(symtab);
	EnterScope(symtab);
	char *c = malloc(sizeof(char) *5);
	c = "a";
	printf("before segfault?\n");
	SymNode *sn = LookupInSymbolTable(symtab, c);
	printf("%d the offset of a is\n", GetOffsetAttr(sn));
	*/
	
	if(DOASSEMBLY)
	{
		//File for final assembly output
		FILE *file;
		file = fopen("tm48code.txt","w");
		
		//Send over to the assembly generator, the quads array and symbol table
		AssemblyGen(quads, file, symtab);
		
		
		fclose(file);
	}
	
	return 0;
}