void free_symbol(symbol *r){ /* free_symbol() - frees memory used by the passed symbol and all others after it */ if (r->next != NULL){ free_symbol(r->next); } free(r); }
/** * This function builds and returns an automaton for pattern * matching of the rule's context. */ Fst2Automaton* make_locate_automaton(elRule* rule,language_t* language) { Fst2Automaton* res=new_Fst2Automaton(NULL,-1); res->automaton=clone(rule->contexts[0].left,dup_symbol); /* We concatenate the left and right contexts */ elag_concat(language,res->automaton,rule->contexts[0].right); /* Then we add loops with ignorable POS on each state */ for (int i=0;i<language->POSs->size;i++) { POS_t* PoS=(POS_t*)language->POSs->value[i]; if (PoS->ignorable) { /* If we have a POS that can be ignored, we add a transition tagged * by this symbol to each state */ for (int q=1;q<res->automaton->number_of_states;q++) { symbol_t* s=new_symbol_POS(PoS,-1); add_outgoing_transition(res->automaton->states[q],s,q); free_symbol(s); } } } return res; }
int main(int argc, char *argv[]){ // 1. Initialization int c; symbol *root; root=init_symbol(ROOT_NODE); root->frequency=NON_EXISTENT; root->parent=root; // 1.a. init: file pointers FILE *inputfile; FILE *outputfile; inputfile=NULL; outputfile=NULL; if (argc >=2) inputfile = fopen(argv[1],"r"); if (argc >=3) outputfile = fopen(argv[2],"w"); if (inputfile == NULL) { fprintf(stderr, "Can't open input file. \n"); exit(1); } if (outputfile == NULL) { outputfile=stdout; } // 2. count the frequency of each character in inputfile while((c=fgetc(inputfile))!=EOF){ update_frequency(root,c); } update_frequency(root,-1); // 3. Make the huffman tree while(count_parentless_nodes(root) > 1){ symbol *node1,*node2, *newnode; node1 = get_rarest_parentless_node(root); node1->parent=node1; //temporarily node2 = get_rarest_parentless_node(root); node2->parent=node2; //temporarily newnode = new_node(node1, node2); insert_symbol(root,newnode); } // 4. Output symbol mappings for(c=-1;c<256;c++){ char *encodingstring; encodingstring=get_encoding(root,c); int freq=get_frequency(root,c); if (freq > 0){ /*if (c <=127 && c>=32 ) fprintf(outputfile,"%c\t%d\t%s\n", c, freq, encodingstring); else */ fprintf(outputfile,"%d\t%d\t%s\n", c, freq, encodingstring); } free(encodingstring); } fprintf(outputfile,"\n"); // 5. Output encoding of inputfile rewind(inputfile); while((c=fgetc(inputfile))!=EOF){ char *encodingstring; encodingstring=get_encoding(root,c); fprintf(outputfile, "%s", encodingstring); free(encodingstring); } char *encodingstring; encodingstring=get_encoding(root,EOF); fprintf(outputfile, "%s", encodingstring); free(encodingstring); fprintf(outputfile,"\n"); free_symbol(root); // 6. Close file pointers fclose(inputfile); fclose(outputfile); }
static void expand_macro (symbol *sym) { struct obstack arguments; /* Alternate obstack if argc_stack is busy. */ unsigned argv_base; /* Size of argv_stack on entry. */ bool use_argc_stack = true; /* Whether argc_stack is safe. */ token_data **argv; int argc; struct obstack *expansion; const char *expanded; bool traced; int my_call_id; /* Report errors at the location where the open parenthesis (if any) was found, but after expansion, restore global state back to the location of the close parenthesis. This is safe since we guarantee that macro expansion does not alter the state of current_file/current_line (dnl, include, and sinclude are special cased in the input engine to ensure this fact). */ const char *loc_open_file = current_file; int loc_open_line = current_line; const char *loc_close_file; int loc_close_line; SYMBOL_PENDING_EXPANSIONS (sym)++; expansion_level++; if (nesting_limit > 0 && expansion_level > nesting_limit) M4ERROR ((EXIT_FAILURE, 0, "recursion limit of %d exceeded, use -L<N> to change it", nesting_limit)); macro_call_id++; my_call_id = macro_call_id; traced = (debug_level & DEBUG_TRACE_ALL) || SYMBOL_TRACED (sym); argv_base = obstack_object_size (&argv_stack); if (obstack_object_size (&argc_stack) > 0) { /* We cannot use argc_stack if this is a nested invocation, and an outer invocation has an unfinished argument being collected. */ obstack_init (&arguments); use_argc_stack = false; } if (traced && (debug_level & DEBUG_TRACE_CALL)) trace_prepre (SYMBOL_NAME (sym), my_call_id); collect_arguments (sym, &argv_stack, use_argc_stack ? &argc_stack : &arguments); argc = ((obstack_object_size (&argv_stack) - argv_base) / sizeof (token_data *)); argv = (token_data **) ((char *) obstack_base (&argv_stack) + argv_base); loc_close_file = current_file; loc_close_line = current_line; current_file = loc_open_file; current_line = loc_open_line; if (traced) trace_pre (SYMBOL_NAME (sym), my_call_id, argc, argv); expansion = push_string_init (); call_macro (sym, argc, argv, expansion); expanded = push_string_finish (); if (traced) trace_post (SYMBOL_NAME (sym), my_call_id, argc, expanded); current_file = loc_close_file; current_line = loc_close_line; --expansion_level; --SYMBOL_PENDING_EXPANSIONS (sym); if (SYMBOL_DELETED (sym)) free_symbol (sym); if (use_argc_stack) obstack_free (&argc_stack, argv[0]); else obstack_free (&arguments, NULL); obstack_blank (&argv_stack, -argc * sizeof (token_data *)); }