dlg_p.g
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:16k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*  This is the parser for the dlg
  2.  *  This is a part of the Purdue Compiler Construction Tool Set
  3.  *
  4.  * SOFTWARE RIGHTS
  5.  *
  6.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  7.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  8.  * company may do whatever they wish with source code distributed with
  9.  * PCCTS or the code generated by PCCTS, including the incorporation of
  10.  * PCCTS, or its output, into commerical software.
  11.  *
  12.  * We encourage users to develop software with PCCTS.  However, we do ask
  13.  * that credit is given to us for developing PCCTS.  By "credit",
  14.  * we mean that if you incorporate our source code into one of your
  15.  * programs (commercial product, research project, or otherwise) that you
  16.  * acknowledge this fact somewhere in the documentation, research report,
  17.  * etc...  If you like PCCTS and have developed a nice tool with the
  18.  * output, please mention that you developed it using PCCTS.  In
  19.  * addition, we ask that this header remain intact in our source code.
  20.  * As long as these guidelines are kept, we expect to continue enhancing
  21.  * this system and expect to make other tools available as they are
  22.  * completed.
  23.  *
  24.  * DLG 1.33
  25.  * Will Cohen
  26.  * With mods by Terence Parr; AHPCRC, University of Minnesota
  27.  * 1989-1995
  28.  */
  29. #header <<
  30. #include <ctype.h>
  31. #include "dlg.h"
  32. #ifdef MEMCHK
  33. #include "trax.h"
  34. #endif
  35. >>
  36. <<
  37. int action_no = 0;    /* keep track of actions outputed */
  38. int nfa_allocated = 0; /* keeps track of number of nfa nodes */
  39. nfa_node **nfa_array = NULL;/* root of binary tree that stores nfa array */
  40. nfa_node nfa_model_node;   /* model to initialize new nodes */
  41. set used_chars;    /* used to label trans. arcs */
  42. set used_classes;    /* classes or chars used to label trans. arcs */
  43. set normal_chars;    /* mask to get rid elements that aren't used
  44.       in set */
  45. int flag_paren = FALSE;
  46. int flag_brace = FALSE;
  47. int mode_counter = 0;  /* keep track of number of %%names */
  48. >>
  49. #lexaction <<
  50. int func_action; /* should actions be turned into functions?*/
  51. int lex_mode_counter = 0; /* keeps track of the number of %%names */
  52. /* MR1     */
  53. /* MR1  11-Apr-97 Provide mechanism for inserting code into DLG class */
  54. /* MR1 via <<%%lexmember...>>     */
  55. /* MR1     */
  56. int lexMember = 0; /* <<%%lexmemeber ...>>     MR1 */
  57. int lexAction = 0; /* <<%%lexaction ...>> MR1 */
  58. int parserClass = 0; /* <<%%parserclass ...>>        MR1 */
  59. int lexPrefix = 0; /* <<%%lexprefix ...>> MR1 */
  60. char theClassName[100];      /* MR11 */
  61. char *pClassName=theClassName;  /* MR11 */
  62. int firstLexMember=1;              /* MR1 */
  63. #ifdef __USE_PROTOS
  64. void  xxputc(int c) { /* MR1 */
  65. #else
  66. void xxputc(c) /* MR1 */
  67.   int c; /* MR1 */
  68. { /* MR1 */
  69. #endif
  70.   if (parserClass) { /* MR1 */
  71.     *pClassName++=c; /* MR1 */
  72.     *pClassName=0; /* MR1 */
  73.   } else if (lexMember || lexPrefix) { /* MR1 */
  74.     if (class_stream != NULL) fputc(c,class_stream); /* MR1 */
  75.   } else { /* MR1 */
  76.     fputc(c,OUT); /* MR1 */
  77.   }; /* MR1 */
  78. }   /* MR1 */
  79. #ifdef __USE_PROTOS
  80. void xxprintf(char *format,char *string) { /* MR1 */
  81. #else
  82. void xxprintf(format,string)  /* MR1 */
  83.   char *format; /* MR1 */
  84.   char *string; /* MR1 */
  85. { /* MR1 */
  86. #endif
  87.   if (lexMember || lexPrefix || parserClass) { /* MR1 */
  88.     if (class_stream != NULL) /* MR1 */
  89.  fprintf(class_stream,format,string); /* MR1 */
  90.   } else { /* MR1 */
  91.     fprintf(OUT,format,string); /* MR1 */
  92.   }; /* MR1 */
  93. }   /* MR1 */
  94. >>
  95. #token "[rt ]+" << zzskip(); >> /* Ignore white */
  96. #token "n" << zzline++; zzskip(); DAWDLE; >> /* Track Line # */
  97. #token L_EOF "@"
  98. #token PER_PER "%%"
  99. #token NAME_PER_PER "%%[a-zA-Z_][a-zA-Z0-9_]*"
  100. << p_mode_def(&zzlextext[2],lex_mode_counter++); >>
  101. #token LEXMEMBER "<<%%lexmember" /* MR1 */
  102. <<lexMember=1; /* MR1 */
  103.           if (firstLexMember != 0) { /* MR1 */
  104.             firstLexMember=0; /* MR1 */
  105.             p_class_def1(); /* MR1 */
  106.   }; /* MR1 */
  107.           zzmode(ACT); /* MR1 */
  108.                 >> /* MR1 */
  109. #token LEXACTION "<<%%lexaction" /* MR1 */
  110. <<lexAction=1;zzmode(ACT);>> /* MR1 */
  111. #token PARSERCLASS "<<%%parserclass" /* MR1 */
  112. <<parserClass=1; /* MR1 */
  113.   zzmode(ACT); /* MR1 */
  114. >> /* MR1 */
  115. #token LEXPREFIX "<<%%lexprefix" /* MR1 */
  116. <<lexPrefix=1;zzmode(ACT);>> /* MR1 */
  117. #token ACTION "<<"
  118. << if (func_action)
  119. fprintf(OUT,"n%s %sact%d()n{ ",
  120. gen_cpp?"ANTLRTokenType":"static void",
  121. gen_cpp?ClassName("::"):"", ++action_no);
  122.    zzmode(ACT); zzskip();
  123. >>
  124. #token GREAT_GREAT ">>"
  125. #token L_BRACE "{"
  126. #token R_BRACE "}"
  127. #token L_PAR "("
  128. #token R_PAR ")"
  129. #token L_BRACK "["
  130. #token R_BRACK "]"
  131. #token ZERO_MORE "*"
  132. #token ONE_MORE "+"
  133. #token OR "|"
  134. #token RANGE "-"
  135. #token NOT "~"
  136. #token OCTAL_VALUE "\0[0-7]*"
  137. << {int t; sscanf(&zzlextext[1],"%o",&t); zzlextext[0] = t;}>>
  138. #token HEX_VALUE   "\0[Xx][0-9a-fA-F]+"
  139. << {int t; sscanf(&zzlextext[3],"%x",&t); zzlextext[0] = t;}>>
  140. #token DEC_VALUE   "\[1-9][0-9]*"
  141. << {int t; sscanf(&zzlextext[1],"%d",&t); zzlextext[0] = t;}>>
  142. #token TAB "\t" << zzlextext[0] = 't';>>
  143. #token NL "\n" << zzlextext[0] = 'n';>>
  144. #token CR "\r" << zzlextext[0] = 'r';>>
  145. #token BS "\b" << zzlextext[0] = 'b';>>
  146. /* MR1 */
  147. /* MR1 10-Apr-97 MR1 Allow #token regular expressions to cross lines */
  148. /* MR1 */
  149. #token CONTINUATION "\ n" << zzline++; zzskip();>> /* MR1 */
  150. /* NOTE: this takes ANYTHING after the  */
  151. #token LIT "\~[tnrb]" << zzlextext[0] = zzlextext[1];>>
  152. /* NOTE: this takes ANYTHING that doesn't match the other tokens */
  153. #token REGCHAR "~[\]"
  154. grammar :   << p_head(); p_class_hdr(); func_action = FALSE;>>
  155.  ( {LEXACTION | LEXMEMBER | LEXPREFIX | PARSERCLASS } ACTION)* /* MR1 */
  156.     <<if ( gen_cpp ) p_includes();>>
  157.     start_states
  158.     << func_action = FALSE; p_tables(); p_tail(); >>
  159.     (ACTION)* "@"
  160. << if (firstLexMember != 0) p_class_def1(); >>  /* MR1 */
  161. ;
  162. start_states : ( PER_PER do_conversion
  163.   | NAME_PER_PER do_conversion (NAME_PER_PER do_conversion)*)
  164.     PER_PER
  165. ;
  166. do_conversion : <<new_automaton_mode(); func_action = TRUE;>>
  167. rule_list
  168. <<
  169. dfa_class_nop[mode_counter] =
  170. relabel($1.l,comp_level);
  171. if (comp_level)
  172. p_shift_table(mode_counter);
  173. dfa_basep[mode_counter] = dfa_allocated+1;
  174. make_dfa_model_node(dfa_class_nop[mode_counter]);
  175. nfa_to_dfa($1.l);
  176. ++mode_counter;
  177.      func_action = FALSE;
  178. #ifdef HASH_STAT
  179. fprint_hash_stats(stderr);
  180. #endif
  181. >>
  182. ;
  183. rule_list : rule <<$$.l=$1.l; $$.r=$1.r;>>
  184. (rule
  185. <<{nfa_node *t1;
  186.    t1 = new_nfa_node();
  187.    (t1)->trans[0]=$$.l;
  188.    (t1)->trans[1]=$1.l;
  189.    /* all accept nodes "dead ends" */
  190.    $$.l=t1; $$.r=NULL;
  191.    }
  192. >>
  193. )*
  194. | /* empty */
  195. <<$$.l = new_nfa_node(); $$.r = NULL;
  196.    warning("no regular expressions", zzline);
  197. >>
  198. ;
  199. rule : reg_expr ACTION
  200. <<$$.l=$1.l; $$.r=$1.r; ($1.r)->accept=action_no;>>
  201. | ACTION
  202. <<$$.l = NULL; $$.r = NULL;
  203.   error("no expression for action  ", zzline);
  204. >>
  205. ;
  206. reg_expr : and_expr <<$$.l=$1.l; $$.r=$1.r;>>
  207. (OR and_expr
  208. <<{nfa_node *t1, *t2;
  209.    t1 = new_nfa_node(); t2 = new_nfa_node();
  210.    (t1)->trans[0]=$$.l;
  211.    (t1)->trans[1]=$2.l;
  212.    ($$.r)->trans[1]=t2;
  213.    ($2.r)->trans[1]=t2;
  214.    $$.l=t1; $$.r=t2;
  215.   }
  216. >>
  217. )*
  218. ;
  219. and_expr : repeat_expr <<$$.l=$1.l; $$.r=$1.r;>>
  220. (repeat_expr <<($$.r)->trans[1]=$1.l; $$.r=$1.r;>>)*
  221. ;
  222. repeat_expr : expr <<$$.l=$1.l; $$.r=$1.r;>>
  223. { ZERO_MORE
  224. <<{ nfa_node *t1,*t2;
  225. ($$.r)->trans[0] = $$.l;
  226. t1 = new_nfa_node(); t2 = new_nfa_node();
  227. t1->trans[0]=$$.l;
  228. t1->trans[1]=t2;
  229. ($$.r)->trans[1]=t2;
  230. $$.l=t1;$$.r=t2;
  231.   }
  232. >>
  233. | ONE_MORE
  234. <<($$.r)->trans[0] = $$.l;>>
  235. }
  236. | ZERO_MORE
  237. << error("no expression for *", zzline);>>
  238. | ONE_MORE
  239. << error("no expression for +", zzline);>>
  240. ;
  241. expr : << $$.l = new_nfa_node(); $$.r = new_nfa_node(); >>
  242.   L_BRACK atom_list R_BRACK
  243. <<
  244. ($$.l)->trans[0] = $$.r;
  245. ($$.l)->label = set_dup($2.label);
  246. set_orin(&used_chars,($$.l)->label);
  247. >>
  248. | NOT L_BRACK atom_list R_BRACK
  249. <<
  250. ($$.l)->trans[0] = $$.r;
  251. ($$.l)->label = set_dif(normal_chars,$3.label);
  252. set_orin(&used_chars,($$.l)->label);
  253. >>
  254. | L_PAR reg_expr R_PAR
  255. <<
  256. ($$.l)->trans[0] = $2.l;
  257. ($2.r)->trans[1] = $$.r;
  258. >>
  259. | L_BRACE reg_expr R_BRACE
  260. <<
  261. ($$.l)->trans[0] = $2.l;
  262. ($$.l)->trans[1] = $$.r;
  263. ($2.r)->trans[1] = $$.r;
  264. >>
  265. | atom
  266. <<
  267. ($$.l)->trans[0] = $$.r;
  268. ($$.l)->label = set_dup($1.label);
  269. set_orin(&used_chars,($$.l)->label);
  270. >>
  271. ;
  272. atom_list : << set_free($$.label); >>
  273. (near_atom <<set_orin(&($$.label),$1.label);>>)*
  274. ;
  275. near_atom : << register int i;
  276.      register int i_prime;
  277.   >>
  278.   anychar
  279. <<$$.letter=$1.letter; $$.label=set_of($1.letter);
  280. i_prime = $1.letter + MIN_CHAR;
  281. if (case_insensitive && islower(i_prime))
  282. set_orel(toupper(i_prime)-MIN_CHAR,
  283. &($$.label));
  284. if (case_insensitive && isupper(i_prime))
  285.   set_orel(tolower(i_prime)-MIN_CHAR,
  286. &($$.label));
  287. >>
  288. { RANGE anychar
  289. << if (case_insensitive){
  290. i_prime = $$.letter+MIN_CHAR;
  291. $$.letter = (islower(i_prime) ?
  292. toupper(i_prime) : i_prime)-MIN_CHAR;
  293. i_prime = $2.letter+MIN_CHAR;
  294. $2.letter = (islower(i_prime) ?
  295. toupper(i_prime) : i_prime)-MIN_CHAR;
  296.    }
  297.    /* check to see if range okay */
  298.    if ($$.letter > $2.letter){
  299.   error("invalid range  ", zzline);
  300.    }
  301.    for (i=$$.letter; i<= (int)$2.letter; ++i){
  302. set_orel(i,&($$.label));
  303. i_prime = i+MIN_CHAR;
  304. if (case_insensitive && islower(i_prime))
  305. set_orel(toupper(i_prime)-MIN_CHAR,
  306. &($$.label));
  307. if (case_insensitive && isupper(i_prime))
  308.   set_orel(tolower(i_prime)-MIN_CHAR,
  309. &($$.label));
  310. }
  311. >>
  312. }
  313. ;
  314. atom : << register int i_prime;>>
  315.   anychar
  316.   <<$$.label = set_of($1.letter);
  317.     i_prime = $1.letter + MIN_CHAR;
  318.     if (case_insensitive && islower(i_prime))
  319. set_orel(toupper(i_prime)-MIN_CHAR,
  320. &($$.label));
  321.     if (case_insensitive && isupper(i_prime))
  322.   set_orel(tolower(i_prime)-MIN_CHAR,
  323. &($$.label));
  324.   >>
  325. ;
  326. anychar : REGCHAR <<$$.letter = $1.letter - MIN_CHAR;>>
  327. | OCTAL_VALUE <<$$.letter = $1.letter - MIN_CHAR;>>
  328. | HEX_VALUE <<$$.letter = $1.letter - MIN_CHAR;>>
  329. | DEC_VALUE <<$$.letter = $1.letter - MIN_CHAR;>>
  330. | TAB <<$$.letter = $1.letter - MIN_CHAR;>>
  331. | NL <<$$.letter = $1.letter - MIN_CHAR;>>
  332. | CR <<$$.letter = $1.letter - MIN_CHAR;>>
  333. | BS <<$$.letter = $1.letter - MIN_CHAR;>>
  334. | LIT <<$$.letter = $1.letter - MIN_CHAR;>>
  335. /* NOTE: LEX_EOF is ALWAYS shifted to 0 = MIN_CHAR - MIN_CHAR*/
  336. | L_EOF <<$$.letter = 0;>>
  337. ;
  338. <</* empty action */>>
  339. #lexclass ACT
  340. #token "@" << error("unterminated action", zzline); zzmode(START); >>
  341. #token ACTION ">>"
  342. << if (func_action) fprintf(OUT,"}nn");
  343.    zzmode(START);
  344. /* MR1     */
  345. /* MR1  11-Apr-97 Provide mechanism for inserting code into DLG class */
  346. /* MR1 via <<%%lexmember ...>>     */
  347. /* MR1 This is a consequence of not saving actions         */
  348. /* MR1     */
  349. /* MR1 */    parserClass=0;
  350. /* MR1 */    lexPrefix=0;
  351. /* MR1 */    lexAction=0;
  352. /* MR1 */    lexMember=0;
  353. >>
  354. #token ">" << xxputc(zzlextext[0]); zzskip(); >> /* MR1 */
  355. #token "\>" << xxputc('>'); zzskip(); >> /* MR1 */
  356. #token "\" << xxputc('\'); zzskip(); >> /* MR1 */
  357. #token "n" << xxputc(zzlextext[0]); ++zzline; zzskip(); >> /* MR1 */
  358. #token "/*" << zzmode(ACTION_COMMENTS); /* MR1 */
  359.    xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
  360. >> /* MR1 */
  361. #token "//" << zzmode(ACTION_CPP_COMMENTS); /* MR1 */
  362.    xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
  363. >> /* MR1 */
  364. #token "~[]" << xxputc(zzlextext[0]); zzskip(); >> /* MR1 */
  365. /* MR1 */
  366. #lexclass ACTION_COMMENTS /* MR1 */
  367. #token "*/" << zzmode(ACT); /* MR1 */
  368.    xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
  369. >> /* MR1 */
  370. #token "[nr]" << zzline++; xxputc(zzlextext[0]); zzskip();>> /* MR1 */
  371. #token "~[]" << xxputc(zzlextext[0]); zzskip();>> /* MR1 */
  372. /* MR1 */
  373. #lexclass ACTION_CPP_COMMENTS /* MR1 */
  374. #token "[nr]" << zzmode(ACT); zzline++; /* MR1 */
  375.    xxprintf("%s", &(zzlextext[0])); zzskip(); /* MR1 */
  376. >> /* MR1 */
  377. #token "~[]" << xxputc(zzlextext[0]); zzskip();>> /* MR1 */
  378. <<
  379. /* adds a new nfa to the binary tree and returns a pointer to it */
  380. nfa_node *new_nfa_node()
  381. {
  382. register nfa_node *t;
  383. static int nfa_size=0; /* elements nfa_array[] can hold */
  384. ++nfa_allocated;
  385. if (nfa_size<=nfa_allocated){
  386. /* need to redo array */
  387. if (!nfa_array){
  388. /* need some to do inital allocation */
  389. nfa_size=nfa_allocated+NFA_MIN;
  390. nfa_array=(nfa_node **) malloc(sizeof(nfa_node*)*
  391. nfa_size);
  392. }else{
  393. /* need more space */
  394. nfa_size=2*(nfa_allocated+1);
  395. nfa_array=(nfa_node **) realloc(nfa_array,
  396. sizeof(nfa_node*)*nfa_size);
  397. }
  398. }
  399. /* fill out entry in array */
  400. t = (nfa_node*) malloc(sizeof(nfa_node));
  401. nfa_array[nfa_allocated] = t;
  402. *t = nfa_model_node;
  403. t->node_no = nfa_allocated;
  404. return t;
  405. }
  406. /* initialize the model node used to fill in newly made nfa_nodes */
  407. void
  408. make_nfa_model_node()
  409. {
  410. nfa_model_node.node_no = -1; /* impossible value for real nfa node */
  411. nfa_model_node.nfa_set = 0;
  412. nfa_model_node.accept = 0;   /* error state default*/
  413. nfa_model_node.trans[0] = NULL;
  414. nfa_model_node.trans[1] = NULL;
  415. nfa_model_node.label = empty;
  416. }
  417. >>
  418. <<
  419. #ifdef DEBUG
  420. /* print out the pointer value and the node_number */
  421. fprint_dfa_pair(f, p)
  422. FILE *f;
  423. nfa_node *p;
  424. {
  425. if (p){
  426. fprintf(f, "%x (%d)", p, p->node_no);
  427. }else{
  428. fprintf(f, "(nil)");
  429. }
  430. }
  431. /* print out interest information on a set */
  432. fprint_set(f,s)
  433. FILE *f;
  434. set s;
  435. {
  436. unsigned int *x;
  437. fprintf(f, "n = %d,", s.n);
  438. if (s.setword){
  439. fprintf(f, "setword = %x,   ", s.setword);
  440. /* print out all the elements in the set */
  441. x = set_pdq(s);
  442. while (*x!=nil){
  443. fprintf(f, "%d ", *x);
  444. ++x;
  445. }
  446. }else{
  447. fprintf(f, "setword = (nil)");
  448. }
  449. }
  450. /* code to be able to dump out the nfas
  451. return 0 if okay dump
  452. return 1 if screwed up
  453.  */
  454. int dump_nfas(first_node, last_node)
  455. int first_node;
  456. int last_node;
  457. {
  458. register int i;
  459. nfa_node *t;
  460. for (i=first_node; i<=last_node; ++i){
  461. t = NFA(i);
  462. if (!t) break;
  463. fprintf(stderr, "nfa_node %d {n", t->node_no);
  464. fprintf(stderr, "ntnfa_set = %dn", t->nfa_set);
  465. fprintf(stderr, "tacceptt=t%dn", t->accept);
  466. fprintf(stderr, "ttranst=t(");
  467. fprint_dfa_pair(stderr, t->trans[0]);
  468. fprintf(stderr, ",");
  469. fprint_dfa_pair(stderr, t->trans[1]);
  470. fprintf(stderr, ")n");
  471. fprintf(stderr, "tlabelt=t{ ");
  472. fprint_set(stderr, t->label);
  473. fprintf(stderr, "t}n");
  474. fprintf(stderr, "}nn");
  475. }
  476. return 0;
  477. }
  478. #endif
  479. >>
  480. <<
  481. /* DLG-specific syntax error message generator
  482.  * (define USER_ZZSYN when compiling so don't get 2 definitions)
  483.  */
  484. void
  485. #ifdef __USE_PROTOS
  486. zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok, int k, char *bad_text)
  487. #else
  488. zzsyn(text, tok, egroup, eset, etok, k, bad_text)
  489. char *text, *egroup, *bad_text;
  490. int tok;
  491. int etok;
  492. int k;
  493. SetWordType *eset;
  494. #endif
  495. {
  496. fprintf(stderr, ErrHdr, file_str[0]!=NULL?file_str[0]:"stdin", zzline);
  497. fprintf(stderr, " syntax error at "%s"", (tok==zzEOF_TOKEN)?"EOF":text);
  498. if ( !etok && !eset ) {fprintf(stderr, "n"); return;}
  499. if ( k==1 ) fprintf(stderr, " missing");
  500. else
  501. {
  502. fprintf(stderr, "; "%s" not", bad_text);
  503. if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");
  504. }
  505. if ( zzset_deg(eset)>0 ) zzedecode(eset);
  506. else fprintf(stderr, " %s", zztokens[etok]);
  507. if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup);
  508. fprintf(stderr, "n");
  509. }
  510. >>