%{ # include # include "parser.h" parser_clause_list *clauses; parser_clause *interactive_clause; parser_term_list *last; int term_counter = 0; int func_ref_num = 0; char agent[50]; char dec_type; char action_type(); #define BLOCK_SIZE 100 functor **sym_table; int max_sym_size = 0; module_ptr parser_main(char *file_name); struct clause *parse_interactive_input(char *input); void yyerror(char *s); void print_table(); static void free_parser_mem(parser_clause_list *clauses); static void free_parser_clause(parser_clause *ptr); static void free_parser_term(parser_term *ptr); struct clause *convert_clause(parser_clause * cl); void InitilizeSymTable(); void update_type(int functor); int priority_count=0; static int error_flag = 0; %} %start module %union { int ival; char *sval; parser_term *tval; parser_term_list *tlval; parser_clause *cval; parser_clause_list **clval; } %token P_MODULE P_ABDUCIBLE P_RECURSIVE P_VARIABLE P_ATOM %token P_PERIOD P_COMMA P_NUMBER P_SYM_LIST %token P_STRING %token P_FORWARD P_D_FORWARD P_BACKWARD P_DIRECT %type term list_elements cons_term cons_term_list rest_of_list %type predicate_list var_term_list %type clause %type clauses %% module : agent_name decs clauses | '{' clause '}' {interactive_clause = $2;} ; agent_name : P_MODULE '(' P_ATOM ')' P_PERIOD {strcpy(agent, sym_table[$3]->name); } ; decs : /* empty */ | decs declaration ; declaration : dec_type '(' '[' dec_list ']' ')' P_PERIOD ; dec_type : P_ABDUCIBLE {dec_type = 'A';} | P_RECURSIVE {dec_type = 'R';} ; dec_list : /* empty */ | P_ATOM {update_type($1);} | P_ATOM P_COMMA dec_list {update_type($1);} ; clauses : /*empty */ { $$ = &clauses; } | clauses clause { *$1 = (parser_clause_list *)my_alloc(sizeof(parser_clause_list)); (*$1)->next = NULL; (*$1)->ptr = $2; $$ = &(*$1)->next; } ; clause : predicate_list P_FORWARD term P_PERIOD { parser_clause *pclause; pclause = (parser_clause *)my_alloc(sizeof(parser_clause)); pclause->head = $3; pclause->body = $1; pclause->var_counter = $4; pclause->clause_type = FORWARD_CLAUSE; $$ = pclause; } | predicate_list P_D_FORWARD term P_PERIOD { parser_clause *pclause; pclause = (parser_clause *)my_alloc(sizeof(parser_clause)); pclause->head = $3; pclause->body = $1; pclause->var_counter = $4; pclause->clause_type = DIRECT_FORWARD_CLAUSE; $$ = pclause; } | term P_BACKWARD predicate_list P_PERIOD { parser_clause *pclause; pclause = (parser_clause *)my_alloc(sizeof(parser_clause)); pclause->head = $1; pclause->body = $3; pclause->var_counter = $4; pclause->clause_type = BACKWARD_CLAUSE; $$ = pclause; } | term P_DIRECT predicate_list P_PERIOD { parser_clause *pclause; pclause = (parser_clause *)my_alloc(sizeof(parser_clause)); pclause->head = $1; pclause->body = $3; pclause->var_counter = $4; pclause->clause_type = DIRECT_CLAUSE; $$ = pclause; } | term P_PERIOD { parser_clause *pclause; pclause = (parser_clause *)my_alloc(sizeof(parser_clause)); pclause->head = $1; pclause->body = NULL; pclause->var_counter = $2; pclause->clause_type = DIRECT_CLAUSE; $$ = pclause; } ; predicate_list : term { parser_term_list *lterm; /* New predicate list */ lterm = (parser_term_list *)my_alloc(sizeof(parser_term_list)); lterm->next = NULL; lterm->ptr = $1; last = lterm; $$ = lterm; } | predicate_list P_COMMA term { last->next = (parser_term_list *)my_alloc(sizeof(parser_term_list)); last = last->next; last->next = NULL; last->ptr = $3; $$ = $1; } ; term : P_ATOM '(' var_term_list ')' { parser_term * pterm; pterm = (parser_term *)my_alloc(sizeof(parser_term)); pterm->type = NONVAR; pterm->index = $1; pterm->const_string = NULL; pterm->arguments = $3; $$ = pterm; } | P_ATOM { parser_term * pterm; pterm = (parser_term *)my_alloc(sizeof(parser_term)); pterm->type = NONVAR; pterm->index = $1; pterm->const_string = NULL; pterm->arguments = NULL; $$ = pterm; } | P_STRING { parser_term * pterm; char *temp ; pterm = (parser_term *)my_alloc(sizeof(parser_term)); pterm->type = STRING; pterm->index = 0; /* Remove the quatation marks from the string */ temp = $1+1; temp[strlen(temp)-1] = '\0'; pterm->const_string = (char *)my_alloc(strlen(temp)+1); strcpy(pterm->const_string, temp); pterm->arguments = NULL; $$ = pterm; } | '<' '>' { parser_term * pterm; pterm = (parser_term *)my_alloc(sizeof(parser_term)); pterm->type = TUPLE; pterm->index = 0; pterm->arguments = NULL; $$ = pterm; } | '<' var_term_list '>' { parser_term * pterm; pterm = (parser_term *)my_alloc(sizeof(parser_term)); pterm->type = TUPLE; pterm->index = 0; pterm->arguments = $2; $$ = pterm; } | '[' ']' { parser_term * pterm; pterm = (parser_term *)my_alloc(sizeof(parser_term)); pterm->type = NONVAR; pterm->index = EMPTY_LIST; pterm->arguments = NULL; $$ = pterm; } | '[' list_elements ']' { $$ = $2; } | P_NUMBER { parser_term * pterm; pterm = (parser_term *)my_alloc(sizeof(parser_term)); pterm->type = INTEGER; pterm->index = $1; pterm->const_string = NULL; pterm->arguments = NULL; $$ = pterm; } | P_VARIABLE { parser_term * pterm; pterm = (parser_term *)my_alloc(sizeof(parser_term)); pterm->type = VARIABLE; pterm->index = $1; pterm->const_string = NULL; pterm->arguments = NULL; $$ = pterm; } ; var_term_list : term { parser_term_list * t2; /* New var_term list */ t2 = (parser_term_list *)my_alloc(sizeof(parser_term_list)); t2->next = NULL; t2->ptr = $1; $$ = t2; } | var_term_list P_COMMA term { parser_term_list *t1; t1 = $1; while(t1->next != NULL) t1 = t1->next; t1->next = (parser_term_list *)my_alloc(sizeof(parser_term_list)); t1 = t1->next; t1->next = NULL; t1->ptr = $3; $$ = $1; } ; cons_term : term { parser_term * pterm; parser_term_list * t1; pterm = (parser_term *)my_alloc(sizeof(parser_term)); t1 = (parser_term_list *)my_alloc(sizeof(parser_term_list)); t1->next = NULL; t1->ptr = $1; pterm->type = NONVAR; pterm->index = CONS_LIST; pterm->arguments = t1; $$ = pterm; } ; list_elements : cons_term_list rest_of_list { parser_term_list *t1 = ($1)->arguments; /* The last element in the list have only one argument. */ while(t1->next != NULL) t1 = t1->next->ptr->arguments; t1->next = (parser_term_list *)my_alloc(sizeof(parser_term_list)); t1 = t1->next; t1->next = NULL; t1->ptr = $2; $$ = $1; } ; cons_term_list : cons_term { $$ = $1; } | cons_term_list P_COMMA cons_term { parser_term_list *t1 = ($1)->arguments; /* The last element in the list have only one argument. */ while(t1->next != NULL) t1 = t1->next->ptr->arguments; t1->next = (parser_term_list *)my_alloc(sizeof(parser_term_list)); t1 = t1->next; t1->next = NULL; t1->ptr = $3; $$ = $1; } ; rest_of_list : /* Create empty list */ { parser_term * pterm; pterm = (parser_term *)my_alloc(sizeof(parser_term)); pterm->type = NONVAR; pterm->index = EMPTY_LIST; pterm->arguments = NULL; $$ = pterm; } | '|' term { $$ = $2; } ; %% # include "lex.yy.c" /********************************************************/ /* Interactive parser */ /********************************************************/ struct clause *parse_interactive_input(char *input) { FILE *fp; struct clause *cl; char buffer[100]; /* Initilize */ interactive_clause = NULL; if((fp = fopen("temp.term", "w")) == NULL) {printf("Can't create temp file\n" ); exit(1);} fprintf(fp,"%c%s%c\n", '{', input, '}'); fclose(fp); if((fp = fopen("temp.term", "r")) == NULL) {printf("Can't read term file\n" ); exit(1);} /* Direct the input of the lex */ yyin = fp; yyparse(); if(interactive_clause == NULL) { printf("Null clause\n"); cl = NULL; } else { cl = convert_clause(interactive_clause); } fclose(fp); return(cl); } /********************************************************/ /* string_to_term /********************************************************/ struct term *string_to_term(char *input) { FILE *fp; struct clause *cl; /* Initilize */ interactive_clause = NULL; if((fp = fopen("temp.term", "w")) == NULL) {printf("Can't create temp file\n" ); exit(1);} fprintf(fp,"%c%s%c%c\n", '{', input,'.', '}'); fclose(fp); if((fp = fopen("temp.term", "r")) == NULL) {printf("Can't read term file\n" ); exit(1);} /* Direct the input of the lex */ yyin = fp; yyparse(); if(interactive_clause == NULL) { printf("Null clause\n"); cl = NULL; } else { cl = convert_clause(interactive_clause); } fclose(fp); if (cl==NULL) return NULL; else return(cl->head); } /********************************************************/ /* PARSER_MAIN */ /********************************************************/ module_ptr read_module(char *file_name) { module_ptr module = NULL; FILE *fp = fopen(file_name, "r"); /* Initilize */ clauses = NULL; func_ref_num = 0; if (fp == NULL) {printf("Can't find file %s\n",file_name ); return(NULL);} /* Direct the input of the lex */ yyin = fp; /* Create a symbol table. */ if(max_sym_size == 0){ InitilizeSymTable(); } error_flag = 0; yyparse(); if(error_flag) { printf("Error in loading agent program\n"); } else { module = convert_structure(clauses, agent,term_counter,sym_table); } /* Free clauses memory */ if(clauses != NULL) free_parser_mem(clauses); fclose(fp); return(module); } void InitilizeSymTable() { /* read in the automatically generated reserved_word list */ #include "reserved_str.aux" int n=sizeof(reserved_names)/sizeof(char *); int i; int incomplete_table[]={KNOW}; int incomplete_number=sizeof(incomplete_table)/sizeof(int); sym_table = (functor **)my_alloc(BLOCK_SIZE*sizeof(functor *)); max_sym_size += BLOCK_SIZE; for(i=0;itype = 'S'; } for(i=0;itype='I'; } } /********************************************************/ /* FREE MEMORY */ /********************************************************/ static void free_parser_mem(parser_clause_list *clauses) { parser_clause_list *temp; while(clauses != NULL){ free_parser_clause(clauses->ptr); temp = clauses; clauses = clauses->next; free(temp); } } /********************************************************/ /* FREE CLAUSE */ /********************************************************/ static void free_parser_clause(parser_clause *ptr) { parser_term_list *temp = NULL; parser_term_list *args = ptr->body; free_parser_term(ptr->head); while(args != NULL){ free_parser_term(args->ptr); temp = args; args = args->next; free(temp); } } /********************************************************/ /* FREE TERM */ /********************************************************/ static void free_parser_term(parser_term *ptr) { parser_term_list *temp, *args = ptr->arguments; if (ptr->type == STRING) free(ptr->const_string); while(args != NULL){ free_parser_term(args->ptr); temp = args; args = args->next; free(temp); } free(ptr); } /********************************************************/ /* PARSER ERROR */ /********************************************************/ void yyerror(char *s) { printf("\n\nError %s\n", s); error_flag = 1; } /********************************************************/ /* PRINTING RUTINES */ /********************************************************/ void print_table() { int i; /* Print the table */ printf("\n/* \nThe term lookup table \n"); printf("%-5s%-40s%-5s\n", "Num", "Name", "Type", "Priority"); for(i=0; iname,sym_table[i]->type,sym_table[i]->priority); printf("*/\n"); } void print_module(module_ptr module) { int i; printf("\n\nModule name: %s\n", module->name); for(i=0; i< module->clause_counter; i++) print_clause(module->clause_array[i], sym_table); } void print_clause(clause_ptr ptr, functor **sym_table) { int i; print_term(ptr->head,sym_table); if (ptr->body_size!=0) { printf(" :-\n\t"); for(i=0; ibody_size; i++){ print_term(ptr->body[i],sym_table); if(i < ptr->body_size-1) printf(", \n\t"); } } printf(".\n"); } void pt(term_ptr t) { print_term(t,sym_table); printf("\n"); } void print_term(term_ptr ptr, functor **sym_table) { int i; if (ptr==NULL) { printf("Null term\n"); return; } switch(ptr->term_type){ case VARIABLE: printf("v%d", ptr->functor); break; case NONVAR: switch (ptr->functor) { case EMPTY_LIST: printf("[]"); break; case CONS_LIST: print_list(ptr,sym_table); break; default: printf("%s", sym_table[ptr->functor]->name); if(ptr->arity != 0) printf("("); for(i=0; iarity; i++){ print_term(ptr->argument_array[i],sym_table); if(i == ptr->arity-1) printf(")"); else printf(", "); } break; } break; case INTEGER: printf("$%d", ptr->functor); break; case TUPLE: printf("<"); for(i=0; iarity; i++){ print_term(ptr->argument_array[i],sym_table); if(i == ptr->arity-1) printf(">"); else printf(", "); } break; case STRING: printf("\"%s\"", ptr->const_string); break; } } /* ============================================================ | print_list() | |----------------------------------------------------------| | Params : 1)a term representing a list | | 2) symbol_table | | | | Desc : prints the list in Prolog way. . | | | | Returns: Nothing | |==========================================================| */ void print_list(struct term *l, functor **sym_table) { printf("["); while (l->functor==CONS_LIST) { print_term(l->argument_array[0],sym_table); if (t_next(l)->functor==CONS_LIST) printf(","); l=t_next(l); } if (t_empty_list(l)) printf("]"); else { printf("|"); print_term(l,sym_table); printf("]"); } } void update_type(int functor) { sym_table[functor]->type = dec_type; if (dec_type=='A') { sym_table[functor]->priority=priority_count++; } }