home *** CD-ROM | disk | FTP | other *** search
/ cs.rhul.ac.uk / www.cs.rhul.ac.uk.zip / www.cs.rhul.ac.uk / pub / rdp / rdp_cs3470.tar / rdp_supp / scan.c < prev    next >
C/C++ Source or Header  |  1998-05-07  |  5KB  |  176 lines

  1. /*******************************************************************************
  2. *
  3. * RDP release 1.50 by Adrian Johnstone (A.Johnstone@rhbnc.ac.uk) 20 December 1997
  4. *
  5. * scan.c - support routines for the scanner
  6. *
  7. * This file may be freely distributed. Please mail improvements to the author.
  8. *
  9. *******************************************************************************/
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include "graph.h"
  14. #include "memalloc.h"
  15. #include "symbol.h"
  16. #include "set.h"
  17. #include "textio.h"
  18. #include "scan.h"
  19.  
  20. void * scan_table = NULL; 
  21. int scan_case_insensitive = 0; 
  22. int scan_newline_visible = 0; 
  23. int scan_show_skips = 0; 
  24. int scan_symbol_echo = 0; 
  25.  
  26. char * scan_token_names = NULL; 
  27.  
  28. void scan_init(const int case_insensitive, const int newline_visible, const int show_skips, const int symbol_echo, char * token_names)
  29. {
  30.   scan_case_insensitive = case_insensitive; 
  31.   scan_show_skips = show_skips; 
  32.   scan_newline_visible = newline_visible; 
  33.   scan_symbol_echo = symbol_echo; 
  34.   scan_token_names = token_names; 
  35.   
  36.   text_scan_data = mem_malloc(sizeof(scan_data)); 
  37.   
  38.   scan_table = symbol_new_table("scan table", 101, 31, symbol_compare_string, symbol_hash_string, symbol_print_string); 
  39. }
  40.  
  41. void scan_load_keyword(char * id1, const char * id2, const int token, const int extended)
  42. {
  43.   scan_data * d =(scan_data *) symbol_new_symbol(sizeof(scan_data)); 
  44.   
  45.   d->id = text_insert_string(id1); 
  46.   
  47.   
  48.   if (id2 != NULL)            /* If this has a secondary string */
  49.     text_insert_string(id2); 
  50.   
  51.   d->token = token; 
  52.   d->extended = extended; 
  53.   
  54.   symbol_insert_symbol(scan_table, d); 
  55. }
  56.  
  57. void scan_prune_tree(scan_data * this_node)
  58. {
  59.   void * this_edge = graph_get_next_edge(this_node); 
  60.   
  61. /*  text_message(TEXT_INFO, "Node: %s\n", this_node->id); */
  62.   
  63.   /* Look at children. If they are NULL, delete them after bringing their children up to this level */
  64.   while (this_edge != NULL)
  65.   {
  66.     void * temp_edge = this_edge; 
  67.     scan_data * child_node =(scan_data *) graph_get_edge_target(temp_edge); 
  68.     
  69.     scan_prune_tree((scan_data *) graph_get_edge_target(this_edge));  /* do lower levels first */
  70.     this_edge = graph_get_next_edge(this_edge);  /* set up for next edge */
  71.     
  72.     if (* child_node->id == 0) /* Child is epsilon? */
  73.     {
  74.       void * childs_edge = graph_get_next_edge(child_node); 
  75.       
  76.       while (childs_edge != NULL)
  77.       {
  78.         graph_insert_edge(0, graph_get_edge_target(childs_edge), temp_edge); 
  79.         childs_edge = graph_get_next_edge(childs_edge); 
  80.       }
  81.       
  82.       graph_delete_node(child_node); 
  83.       graph_delete_edge(temp_edge); 
  84.     }
  85.   }
  86. }
  87.  
  88. static void scan_skip(set_ * stop) /* scan until a token in stop set appears */
  89. {
  90.   while (!set_includes_element(stop, SCAN_CAST->token))
  91.     scan_();                  /* Don't add tokens to tree when skipping! */
  92.   
  93.   if (scan_show_skips)
  94.     text_message(TEXT_ERROR_ECHO, "Skipping to...\n"); 
  95. }
  96.  
  97. int scan_test(const char * production, const int valid, set_ * stop)
  98. {
  99.   if (valid != SCAN_CAST->token)
  100.   {
  101.     if (stop != NULL)
  102.     {
  103.       if (production != NULL)
  104.         text_message(TEXT_ERROR_ECHO, "In rule \'%s\', scanned ", production); 
  105.       else
  106.         text_message(TEXT_ERROR_ECHO, "Scanned "); 
  107.       set_print_element(SCAN_CAST->token, scan_token_names); 
  108.       text_printf(" whilst expecting "); 
  109.       
  110.       set_print_element(valid, scan_token_names); 
  111.       text_printf("\n"); 
  112.       scan_skip(stop); 
  113.     }
  114.     return 0; 
  115.   }
  116.   else
  117.     return 1; 
  118. }
  119.  
  120. int scan_test_set(const char * production, set_ * valid, set_ * stop)
  121. {
  122.   if (!set_includes_element(valid, SCAN_CAST->token))
  123.   {
  124.     if (stop != NULL)
  125.     {
  126.       if (production != NULL)
  127.         text_message(TEXT_ERROR_ECHO, "In rule \'%s\', scanned ", production); 
  128.       else
  129.         text_message(TEXT_ERROR_ECHO, "Scanned "); 
  130.       set_print_element(SCAN_CAST->token, scan_token_names); 
  131.       text_printf(" whilst expecting %s", set_cardinality(valid)== 1 ? "": "one of "); 
  132.       set_print_set(valid, scan_token_names, 60); 
  133.       text_printf("\n"); 
  134.       scan_skip(stop); 
  135.     }
  136.     return 0; 
  137.   }
  138.   else
  139.     return 1; 
  140. }
  141.  
  142. void scan_vcg_print_node(const void * node)
  143. {
  144.   text_printf("label:\""); 
  145.   
  146.   switch (((scan_data *) node)->token)
  147.   {
  148.     case SCAN_P_IGNORE: 
  149.     case SCAN_P_ID: text_print_C_string(((scan_data *) node)->id); break; 
  150.     case SCAN_P_INTEGER: 
  151.     text_printf("INTEGER: %lu", ((scan_data *) node)->data.i); break; 
  152.     case SCAN_P_REAL: text_printf("REAL: %lf", ((scan_data *) node)->data.r); break; 
  153.     case SCAN_P_STRING: 
  154.     case SCAN_P_STRING_ESC: 
  155.     case SCAN_P_COMMENT: 
  156.     case SCAN_P_COMMENT_VISIBLE: 
  157.     case SCAN_P_COMMENT_NEST: 
  158.     case SCAN_P_COMMENT_NEST_VISIBLE: 
  159.     case SCAN_P_COMMENT_LINE: 
  160.     case SCAN_P_COMMENT_LINE_VISIBLE: text_printf("\\\""); text_print_C_string(((scan_data *) node)->id); text_printf("\\\""); break; 
  161.     case SCAN_P_EOF: text_printf("EOF"); break; 
  162.     case SCAN_P_EOLN: text_printf("EOLN"); break; 
  163.     default: text_printf("\'"); 
  164.     text_print_C_string(((scan_data *) node)->id); 
  165.     text_printf("\'"); 
  166.     break; 
  167.   }
  168.   
  169.   text_printf("\" horizontal_order:%lu", graph_get_atom_number(node)); 
  170.   
  171.   if (((scan_data *) node)->token == SCAN_P_IGNORE) /* make nonterminals round */
  172.     text_printf(" shape:ellipse "); 
  173. }
  174.  
  175. /* End of scan.c */
  176.