Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: third_party/sqlite/src/tool/lemon.c

Issue 949043002: Add //third_party/sqlite to dirs_to_snapshot, remove net_sql.patch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/sqlite/src/tool/getlock.c ('k') | third_party/sqlite/src/tool/logest.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ** This file contains all sources (including headers) to the LEMON 2 ** This file contains all sources (including headers) to the LEMON
3 ** LALR(1) parser generator. The sources have been combined into a 3 ** LALR(1) parser generator. The sources have been combined into a
4 ** single file to make it easy to include LEMON in the source tree 4 ** single file to make it easy to include LEMON in the source tree
5 ** and Makefile of another program. 5 ** and Makefile of another program.
6 ** 6 **
7 ** The author of this program disclaims copyright. 7 ** The author of this program disclaims copyright.
8 */ 8 */
9 #include <stdio.h> 9 #include <stdio.h>
10 #include <stdarg.h> 10 #include <stdarg.h>
11 #include <string.h> 11 #include <string.h>
12 #include <ctype.h> 12 #include <ctype.h>
13 #include <stdlib.h> 13 #include <stdlib.h>
14 #include <assert.h> 14 #include <assert.h>
15 15
16 #ifndef __WIN32__ 16 #ifndef __WIN32__
17 # if defined(_WIN32) || defined(WIN32) 17 # if defined(_WIN32) || defined(WIN32)
18 #» define __WIN32__ 18 # define __WIN32__
19 # endif 19 # endif
20 #endif 20 #endif
21 21
22 #ifdef __WIN32__ 22 #ifdef __WIN32__
23 #ifdef __cplusplus 23 #ifdef __cplusplus
24 extern "C" { 24 extern "C" {
25 #endif 25 #endif
26 extern int access(const char *path, int mode); 26 extern int access(const char *path, int mode);
27 #ifdef __cplusplus 27 #ifdef __cplusplus
28 } 28 }
29 #endif 29 #endif
30 #else 30 #else
31 #include <unistd.h> 31 #include <unistd.h>
32 #endif 32 #endif
33 33
34 /* #define PRIVATE static */ 34 /* #define PRIVATE static */
35 #define PRIVATE 35 #define PRIVATE
36 36
37 #ifdef TEST 37 #ifdef TEST
38 #define MAXRHS 5 /* Set low to exercise exception code */ 38 #define MAXRHS 5 /* Set low to exercise exception code */
39 #else 39 #else
40 #define MAXRHS 1000 40 #define MAXRHS 1000
41 #endif 41 #endif
42 42
43 static int showPrecedenceConflict = 0; 43 static int showPrecedenceConflict = 0;
44 static const char **made_files = NULL;
45 static int made_files_count = 0;
46 static int successful_exit = 0;
47 static void LemonAtExit(void)
48 {
49 /* if we failed, delete (most) files we made, to unconfuse build tools. */
50 int i;
51 for (i = 0; i < made_files_count; i++) {
52 if (!successful_exit) {
53 remove(made_files[i]);
54 }
55 }
56 free(made_files);
57 made_files_count = 0;
58 made_files = NULL;
59 }
60
61 static char *msort(char*,char**,int(*)(const char*,const char*)); 44 static char *msort(char*,char**,int(*)(const char*,const char*));
62 45
63 /* 46 /*
64 ** Compilers are getting increasingly pedantic about type conversions 47 ** Compilers are getting increasingly pedantic about type conversions
65 ** as C evolves ever closer to Ada.... To work around the latest problems 48 ** as C evolves ever closer to Ada.... To work around the latest problems
66 ** we have to define the following variant of strlen(). 49 ** we have to define the following variant of strlen().
67 */ 50 */
68 #define lemonStrlen(X) ((int)strlen(X)) 51 #define lemonStrlen(X) ((int)strlen(X))
69 52
53 /*
54 ** Compilers are starting to complain about the use of sprintf() and strcpy(),
55 ** saying they are unsafe. So we define our own versions of those routines too.
56 **
57 ** There are three routines here: lemon_sprintf(), lemon_vsprintf(), and
58 ** lemon_addtext(). The first two are replacements for sprintf() and vsprintf() .
59 ** The third is a helper routine for vsnprintf() that adds texts to the end of a
60 ** buffer, making sure the buffer is always zero-terminated.
61 **
62 ** The string formatter is a minimal subset of stdlib sprintf() supporting only
63 ** a few simply conversions:
64 **
65 ** %d
66 ** %s
67 ** %.*s
68 **
69 */
70 static void lemon_addtext(
71 char *zBuf, /* The buffer to which text is added */
72 int *pnUsed, /* Slots of the buffer used so far */
73 const char *zIn, /* Text to add */
74 int nIn, /* Bytes of text to add. -1 to use strlen() */
75 int iWidth /* Field width. Negative to left justify */
76 ){
77 if( nIn<0 ) for(nIn=0; zIn[nIn]; nIn++){}
78 while( iWidth>nIn ){ zBuf[(*pnUsed)++] = ' '; iWidth--; }
79 if( nIn==0 ) return;
80 memcpy(&zBuf[*pnUsed], zIn, nIn);
81 *pnUsed += nIn;
82 while( (-iWidth)>nIn ){ zBuf[(*pnUsed)++] = ' '; iWidth++; }
83 zBuf[*pnUsed] = 0;
84 }
85 static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){
86 int i, j, k, c;
87 int nUsed = 0;
88 const char *z;
89 char zTemp[50];
90 str[0] = 0;
91 for(i=j=0; (c = zFormat[i])!=0; i++){
92 if( c=='%' ){
93 int iWidth = 0;
94 lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0);
95 c = zFormat[++i];
96 if( isdigit(c) || (c=='-' && isdigit(zFormat[i+1])) ){
97 if( c=='-' ) i++;
98 while( isdigit(zFormat[i]) ) iWidth = iWidth*10 + zFormat[i++] - '0';
99 if( c=='-' ) iWidth = -iWidth;
100 c = zFormat[i];
101 }
102 if( c=='d' ){
103 int v = va_arg(ap, int);
104 if( v<0 ){
105 lemon_addtext(str, &nUsed, "-", 1, iWidth);
106 v = -v;
107 }else if( v==0 ){
108 lemon_addtext(str, &nUsed, "0", 1, iWidth);
109 }
110 k = 0;
111 while( v>0 ){
112 k++;
113 zTemp[sizeof(zTemp)-k] = (v%10) + '0';
114 v /= 10;
115 }
116 lemon_addtext(str, &nUsed, &zTemp[sizeof(zTemp)-k], k, iWidth);
117 }else if( c=='s' ){
118 z = va_arg(ap, const char*);
119 lemon_addtext(str, &nUsed, z, -1, iWidth);
120 }else if( c=='.' && memcmp(&zFormat[i], ".*s", 3)==0 ){
121 i += 2;
122 k = va_arg(ap, int);
123 z = va_arg(ap, const char*);
124 lemon_addtext(str, &nUsed, z, k, iWidth);
125 }else if( c=='%' ){
126 lemon_addtext(str, &nUsed, "%", 1, 0);
127 }else{
128 fprintf(stderr, "illegal format\n");
129 exit(1);
130 }
131 j = i+1;
132 }
133 }
134 lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0);
135 return nUsed;
136 }
137 static int lemon_sprintf(char *str, const char *format, ...){
138 va_list ap;
139 int rc;
140 va_start(ap, format);
141 rc = lemon_vsprintf(str, format, ap);
142 va_end(ap);
143 return rc;
144 }
145 static void lemon_strcpy(char *dest, const char *src){
146 while( (*(dest++) = *(src++))!=0 ){}
147 }
148 static void lemon_strcat(char *dest, const char *src){
149 while( *dest ) dest++;
150 lemon_strcpy(dest, src);
151 }
152
153
70 /* a few forward declarations... */ 154 /* a few forward declarations... */
71 struct rule; 155 struct rule;
72 struct lemon; 156 struct lemon;
73 struct action; 157 struct action;
74 158
75 static struct action *Action_new(void); 159 static struct action *Action_new(void);
76 static struct action *Action_sort(struct action *); 160 static struct action *Action_sort(struct action *);
77 161
78 /********** From the file "build.h" ************************************/ 162 /********** From the file "build.h" ************************************/
79 void FindRulePrecedences(); 163 void FindRulePrecedences();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 void ReportOutput(struct lemon *); 211 void ReportOutput(struct lemon *);
128 void ReportTable(struct lemon *, int); 212 void ReportTable(struct lemon *, int);
129 void ReportHeader(struct lemon *); 213 void ReportHeader(struct lemon *);
130 void CompressTables(struct lemon *); 214 void CompressTables(struct lemon *);
131 void ResortStates(struct lemon *); 215 void ResortStates(struct lemon *);
132 216
133 /********** From the file "set.h" ****************************************/ 217 /********** From the file "set.h" ****************************************/
134 void SetSize(int); /* All sets will be of size N */ 218 void SetSize(int); /* All sets will be of size N */
135 char *SetNew(void); /* A new set for element 0..N */ 219 char *SetNew(void); /* A new set for element 0..N */
136 void SetFree(char*); /* Deallocate a set */ 220 void SetFree(char*); /* Deallocate a set */
137
138 char *SetNew(void); /* A new set for element 0..N */
139 int SetAdd(char*,int); /* Add element to a set */ 221 int SetAdd(char*,int); /* Add element to a set */
140 int SetUnion(char *,char *); /* A <- A U B, thru element N */ 222 int SetUnion(char *,char *); /* A <- A U B, thru element N */
141 #define SetFind(X,Y) (X[Y]) /* True if Y is in set X */ 223 #define SetFind(X,Y) (X[Y]) /* True if Y is in set X */
142 224
143 /********** From the file "struct.h" *************************************/ 225 /********** From the file "struct.h" *************************************/
144 /* 226 /*
145 ** Principal data structures for the LEMON parser generator. 227 ** Principal data structures for the LEMON parser generator.
146 */ 228 */
147 229
148 typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean; 230 typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean;
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 struct symbol *sp = rp->rhs[i]; 747 struct symbol *sp = rp->rhs[i];
666 if( sp->type==MULTITERMINAL ){ 748 if( sp->type==MULTITERMINAL ){
667 for(j=0; j<sp->nsubsym; j++){ 749 for(j=0; j<sp->nsubsym; j++){
668 if( sp->subsym[j]->prec>=0 ){ 750 if( sp->subsym[j]->prec>=0 ){
669 rp->precsym = sp->subsym[j]; 751 rp->precsym = sp->subsym[j];
670 break; 752 break;
671 } 753 }
672 } 754 }
673 }else if( sp->prec>=0 ){ 755 }else if( sp->prec>=0 ){
674 rp->precsym = rp->rhs[i]; 756 rp->precsym = rp->rhs[i];
675 » } 757 }
676 } 758 }
677 } 759 }
678 } 760 }
679 return; 761 return;
680 } 762 }
681 763
682 /* Find all nonterminals which will generate the empty string. 764 /* Find all nonterminals which will generate the empty string.
683 ** Then go back and compute the first sets of every nonterminal. 765 ** Then go back and compute the first sets of every nonterminal.
684 ** The first set is the set of all terminal symbols which can begin 766 ** The first set is the set of all terminal symbols which can begin
685 ** a string generated by that nonterminal. 767 ** a string generated by that nonterminal.
(...skipping 10 matching lines...) Expand all
696 for(i=lemp->nterminal; i<lemp->nsymbol; i++){ 778 for(i=lemp->nterminal; i<lemp->nsymbol; i++){
697 lemp->symbols[i]->firstset = SetNew(); 779 lemp->symbols[i]->firstset = SetNew();
698 } 780 }
699 781
700 /* First compute all lambdas */ 782 /* First compute all lambdas */
701 do{ 783 do{
702 progress = 0; 784 progress = 0;
703 for(rp=lemp->rule; rp; rp=rp->next){ 785 for(rp=lemp->rule; rp; rp=rp->next){
704 if( rp->lhs->lambda ) continue; 786 if( rp->lhs->lambda ) continue;
705 for(i=0; i<rp->nrhs; i++){ 787 for(i=0; i<rp->nrhs; i++){
706 struct symbol *sp = rp->rhs[i]; 788 struct symbol *sp = rp->rhs[i];
707 if( sp->type!=TERMINAL || sp->lambda==LEMON_FALSE ) break; 789 assert( sp->type==NONTERMINAL || sp->lambda==LEMON_FALSE );
790 if( sp->lambda==LEMON_FALSE ) break;
708 } 791 }
709 if( i==rp->nrhs ){ 792 if( i==rp->nrhs ){
710 rp->lhs->lambda = LEMON_TRUE; 793 rp->lhs->lambda = LEMON_TRUE;
711 progress = 1; 794 progress = 1;
712 } 795 }
713 } 796 }
714 }while( progress ); 797 }while( progress );
715 798
716 /* Now compute all first sets */ 799 /* Now compute all first sets */
717 do{ 800 do{
718 struct symbol *s1, *s2; 801 struct symbol *s1, *s2;
719 progress = 0; 802 progress = 0;
720 for(rp=lemp->rule; rp; rp=rp->next){ 803 for(rp=lemp->rule; rp; rp=rp->next){
721 s1 = rp->lhs; 804 s1 = rp->lhs;
722 for(i=0; i<rp->nrhs; i++){ 805 for(i=0; i<rp->nrhs; i++){
723 s2 = rp->rhs[i]; 806 s2 = rp->rhs[i];
724 if( s2->type==TERMINAL ){ 807 if( s2->type==TERMINAL ){
725 progress += SetAdd(s1->firstset,s2->index); 808 progress += SetAdd(s1->firstset,s2->index);
726 break; 809 break;
727 }else if( s2->type==MULTITERMINAL ){ 810 }else if( s2->type==MULTITERMINAL ){
728 for(j=0; j<s2->nsubsym; j++){ 811 for(j=0; j<s2->nsubsym; j++){
729 progress += SetAdd(s1->firstset,s2->subsym[j]->index); 812 progress += SetAdd(s1->firstset,s2->subsym[j]->index);
730 } 813 }
731 break; 814 break;
732 » }else if( s1==s2 ){ 815 }else if( s1==s2 ){
733 if( s1->lambda==LEMON_FALSE ) break; 816 if( s1->lambda==LEMON_FALSE ) break;
734 » }else{ 817 }else{
735 progress += SetUnion(s1->firstset,s2->firstset); 818 progress += SetUnion(s1->firstset,s2->firstset);
736 if( s2->lambda==LEMON_FALSE ) break; 819 if( s2->lambda==LEMON_FALSE ) break;
737 » } 820 }
738 } 821 }
739 } 822 }
740 }while( progress ); 823 }while( progress );
741 return; 824 return;
742 } 825 }
743 826
744 /* Compute all LR(0) states for the grammar. Links 827 /* Compute all LR(0) states for the grammar. Links
745 ** are added to between some states so that the LR(1) follow sets 828 ** are added to between some states so that the LR(1) follow sets
746 ** can be computed later. 829 ** can be computed later.
747 */ 830 */
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 do{ 1053 do{
971 progress = 0; 1054 progress = 0;
972 for(i=0; i<lemp->nstate; i++){ 1055 for(i=0; i<lemp->nstate; i++){
973 for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){ 1056 for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){
974 if( cfp->status==COMPLETE ) continue; 1057 if( cfp->status==COMPLETE ) continue;
975 for(plp=cfp->fplp; plp; plp=plp->next){ 1058 for(plp=cfp->fplp; plp; plp=plp->next){
976 change = SetUnion(plp->cfp->fws,cfp->fws); 1059 change = SetUnion(plp->cfp->fws,cfp->fws);
977 if( change ){ 1060 if( change ){
978 plp->cfp->status = INCOMPLETE; 1061 plp->cfp->status = INCOMPLETE;
979 progress = 1; 1062 progress = 1;
980 » } 1063 }
981 » } 1064 }
982 cfp->status = COMPLETE; 1065 cfp->status = COMPLETE;
983 } 1066 }
984 } 1067 }
985 }while( progress ); 1068 }while( progress );
986 } 1069 }
987 1070
988 static int resolve_conflict(struct action *,struct action *, struct symbol *); 1071 static int resolve_conflict(struct action *,struct action *);
989 1072
990 /* Compute the reduce actions, and resolve conflicts. 1073 /* Compute the reduce actions, and resolve conflicts.
991 */ 1074 */
992 void FindActions(struct lemon *lemp) 1075 void FindActions(struct lemon *lemp)
993 { 1076 {
994 int i,j; 1077 int i,j;
995 struct config *cfp; 1078 struct config *cfp;
996 struct state *stp; 1079 struct state *stp;
997 struct symbol *sp; 1080 struct symbol *sp;
998 struct rule *rp; 1081 struct rule *rp;
999 1082
1000 /* Add all of the reduce actions 1083 /* Add all of the reduce actions
1001 ** A reduce action is added for each element of the followset of 1084 ** A reduce action is added for each element of the followset of
1002 ** a configuration which has its dot at the extreme right. 1085 ** a configuration which has its dot at the extreme right.
1003 */ 1086 */
1004 for(i=0; i<lemp->nstate; i++){ /* Loop over all states */ 1087 for(i=0; i<lemp->nstate; i++){ /* Loop over all states */
1005 stp = lemp->sorted[i]; 1088 stp = lemp->sorted[i];
1006 for(cfp=stp->cfp; cfp; cfp=cfp->next){ /* Loop over all configurations */ 1089 for(cfp=stp->cfp; cfp; cfp=cfp->next){ /* Loop over all configurations */
1007 if( cfp->rp->nrhs==cfp->dot ){ /* Is dot at extreme right? */ 1090 if( cfp->rp->nrhs==cfp->dot ){ /* Is dot at extreme right? */
1008 for(j=0; j<lemp->nterminal; j++){ 1091 for(j=0; j<lemp->nterminal; j++){
1009 if( SetFind(cfp->fws,j) ){ 1092 if( SetFind(cfp->fws,j) ){
1010 /* Add a reduce action to the state "stp" which will reduce by the 1093 /* Add a reduce action to the state "stp" which will reduce by the
1011 ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */ 1094 ** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */
1012 Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp); 1095 Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp);
1013 } 1096 }
1014 » } 1097 }
1015 } 1098 }
1016 } 1099 }
1017 } 1100 }
1018 1101
1019 /* Add the accepting token */ 1102 /* Add the accepting token */
1020 if( lemp->start ){ 1103 if( lemp->start ){
1021 sp = Symbol_find(lemp->start); 1104 sp = Symbol_find(lemp->start);
1022 if( sp==0 ) sp = lemp->rule->lhs; 1105 if( sp==0 ) sp = lemp->rule->lhs;
1023 }else{ 1106 }else{
1024 sp = lemp->rule->lhs; 1107 sp = lemp->rule->lhs;
1025 } 1108 }
1026 /* Add to the first state (which is always the starting state of the 1109 /* Add to the first state (which is always the starting state of the
1027 ** finite state machine) an action to ACCEPT if the lookahead is the 1110 ** finite state machine) an action to ACCEPT if the lookahead is the
1028 ** start nonterminal. */ 1111 ** start nonterminal. */
1029 Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0); 1112 Action_add(&lemp->sorted[0]->ap,ACCEPT,sp,0);
1030 1113
1031 /* Resolve conflicts */ 1114 /* Resolve conflicts */
1032 for(i=0; i<lemp->nstate; i++){ 1115 for(i=0; i<lemp->nstate; i++){
1033 struct action *ap, *nap; 1116 struct action *ap, *nap;
1034 struct state *stp; 1117 struct state *stp;
1035 stp = lemp->sorted[i]; 1118 stp = lemp->sorted[i];
1036 /* assert( stp->ap ); */ 1119 /* assert( stp->ap ); */
1037 stp->ap = Action_sort(stp->ap); 1120 stp->ap = Action_sort(stp->ap);
1038 for(ap=stp->ap; ap && ap->next; ap=ap->next){ 1121 for(ap=stp->ap; ap && ap->next; ap=ap->next){
1039 for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){ 1122 for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){
1040 /* The two actions "ap" and "nap" have the same lookahead. 1123 /* The two actions "ap" and "nap" have the same lookahead.
1041 ** Figure out which one should be used */ 1124 ** Figure out which one should be used */
1042 lemp->nconflict += resolve_conflict(ap,nap,lemp->errsym); 1125 lemp->nconflict += resolve_conflict(ap,nap);
1043 } 1126 }
1044 } 1127 }
1045 } 1128 }
1046 1129
1047 /* Report an error for each rule that can never be reduced. */ 1130 /* Report an error for each rule that can never be reduced. */
1048 for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = LEMON_FALSE; 1131 for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = LEMON_FALSE;
1049 for(i=0; i<lemp->nstate; i++){ 1132 for(i=0; i<lemp->nstate; i++){
1050 struct action *ap; 1133 struct action *ap;
1051 for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ 1134 for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){
1052 if( ap->type==REDUCE ) ap->x.rp->canReduce = LEMON_TRUE; 1135 if( ap->type==REDUCE ) ap->x.rp->canReduce = LEMON_TRUE;
(...skipping 14 matching lines...) Expand all
1067 ** is on an error rule. In that case, take the action which 1150 ** is on an error rule. In that case, take the action which
1068 ** is not associated with the error rule. If neither or both 1151 ** is not associated with the error rule. If neither or both
1069 ** actions are associated with an error rule, then try to 1152 ** actions are associated with an error rule, then try to
1070 ** use precedence to resolve the conflict. 1153 ** use precedence to resolve the conflict.
1071 ** 1154 **
1072 ** If either action is a SHIFT, then it must be apx. This 1155 ** If either action is a SHIFT, then it must be apx. This
1073 ** function won't work if apx->type==REDUCE and apy->type==SHIFT. 1156 ** function won't work if apx->type==REDUCE and apy->type==SHIFT.
1074 */ 1157 */
1075 static int resolve_conflict( 1158 static int resolve_conflict(
1076 struct action *apx, 1159 struct action *apx,
1077 struct action *apy, 1160 struct action *apy
1078 struct symbol *errsym /* The error symbol (if defined. NULL otherwise) */
1079 ){ 1161 ){
1080 struct symbol *spx, *spy; 1162 struct symbol *spx, *spy;
1081 int errcnt = 0; 1163 int errcnt = 0;
1082 assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */ 1164 assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */
1083 if( apx->type==SHIFT && apy->type==SHIFT ){ 1165 if( apx->type==SHIFT && apy->type==SHIFT ){
1084 apy->type = SSCONFLICT; 1166 apy->type = SSCONFLICT;
1085 errcnt++; 1167 errcnt++;
1086 } 1168 }
1087 if( apx->type==SHIFT && apy->type==REDUCE ){ 1169 if( apx->type==SHIFT && apy->type==REDUCE ){
1088 spx = apx->sp; 1170 spx = apx->sp;
1089 spy = apy->x.rp->precsym; 1171 spy = apy->x.rp->precsym;
1090 if( spy==0 || spx->prec<0 || spy->prec<0 ){ 1172 if( spy==0 || spx->prec<0 || spy->prec<0 ){
1091 /* Not enough precedence information. */ 1173 /* Not enough precedence information. */
1092 apy->type = SRCONFLICT; 1174 apy->type = SRCONFLICT;
1093 errcnt++; 1175 errcnt++;
1094 }else if( spx->prec>spy->prec ){ /* higher precedence wins */ 1176 }else if( spx->prec>spy->prec ){ /* higher precedence wins */
1095 apy->type = RD_RESOLVED; 1177 apy->type = RD_RESOLVED;
1096 }else if( spx->prec<spy->prec ){ 1178 }else if( spx->prec<spy->prec ){
1097 apx->type = SH_RESOLVED; 1179 apx->type = SH_RESOLVED;
1098 }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use operator */ 1180 }else if( spx->prec==spy->prec && spx->assoc==RIGHT ){ /* Use operator */
1099 apy->type = RD_RESOLVED; /* associativity */ 1181 apy->type = RD_RESOLVED; /* associativity */
1100 }else if( spx->prec==spy->prec && spx->assoc==LEFT ){ /* to break tie */ 1182 }else if( spx->prec==spy->prec && spx->assoc==LEFT ){ /* to break tie */
1101 apx->type = SH_RESOLVED; 1183 apx->type = SH_RESOLVED;
1102 }else{ 1184 }else{
1103 assert( spx->prec==spy->prec && spx->assoc==NONE ); 1185 assert( spx->prec==spy->prec && spx->assoc==NONE );
1104 apy->type = SRCONFLICT; 1186 apx->type = ERROR;
1105 errcnt++;
1106 } 1187 }
1107 }else if( apx->type==REDUCE && apy->type==REDUCE ){ 1188 }else if( apx->type==REDUCE && apy->type==REDUCE ){
1108 spx = apx->x.rp->precsym; 1189 spx = apx->x.rp->precsym;
1109 spy = apy->x.rp->precsym; 1190 spy = apy->x.rp->precsym;
1110 if( spx==0 || spy==0 || spx->prec<0 || 1191 if( spx==0 || spy==0 || spx->prec<0 ||
1111 spy->prec<0 || spx->prec==spy->prec ){ 1192 spy->prec<0 || spx->prec==spy->prec ){
1112 apy->type = RRCONFLICT; 1193 apy->type = RRCONFLICT;
1113 errcnt++; 1194 errcnt++;
1114 }else if( spx->prec>spy->prec ){ 1195 }else if( spx->prec>spy->prec ){
1115 apy->type = RD_RESOLVED; 1196 apy->type = RD_RESOLVED;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1274 xsp = rp->rhs[i]; 1355 xsp = rp->rhs[i];
1275 if( xsp->type==TERMINAL ){ 1356 if( xsp->type==TERMINAL ){
1276 SetAdd(newcfp->fws,xsp->index); 1357 SetAdd(newcfp->fws,xsp->index);
1277 break; 1358 break;
1278 }else if( xsp->type==MULTITERMINAL ){ 1359 }else if( xsp->type==MULTITERMINAL ){
1279 int k; 1360 int k;
1280 for(k=0; k<xsp->nsubsym; k++){ 1361 for(k=0; k<xsp->nsubsym; k++){
1281 SetAdd(newcfp->fws, xsp->subsym[k]->index); 1362 SetAdd(newcfp->fws, xsp->subsym[k]->index);
1282 } 1363 }
1283 break; 1364 break;
1284 » }else{ 1365 }else{
1285 SetUnion(newcfp->fws,xsp->firstset); 1366 SetUnion(newcfp->fws,xsp->firstset);
1286 if( xsp->lambda==LEMON_FALSE ) break; 1367 if( xsp->lambda==LEMON_FALSE ) break;
1287 » } 1368 }
1288 » } 1369 }
1289 if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp); 1370 if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);
1290 } 1371 }
1291 } 1372 }
1292 } 1373 }
1293 return; 1374 return;
1294 } 1375 }
1295 1376
1296 /* Sort the configuration list */ 1377 /* Sort the configuration list */
1297 void Configlist_sort(){ 1378 void Configlist_sort(){
1298 current = (struct config *)msort((char *)current,(char **)&(current->next),Con figcmp); 1379 current = (struct config *)msort((char *)current,(char **)&(current->next),Con figcmp);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 if( azDefine==0 ){ 1460 if( azDefine==0 ){
1380 fprintf(stderr,"out of memory\n"); 1461 fprintf(stderr,"out of memory\n");
1381 exit(1); 1462 exit(1);
1382 } 1463 }
1383 paz = &azDefine[nDefine-1]; 1464 paz = &azDefine[nDefine-1];
1384 *paz = (char *) malloc( lemonStrlen(z)+1 ); 1465 *paz = (char *) malloc( lemonStrlen(z)+1 );
1385 if( *paz==0 ){ 1466 if( *paz==0 ){
1386 fprintf(stderr,"out of memory\n"); 1467 fprintf(stderr,"out of memory\n");
1387 exit(1); 1468 exit(1);
1388 } 1469 }
1389 strcpy(*paz, z); 1470 lemon_strcpy(*paz, z);
1390 for(z=*paz; *z && *z!='='; z++){} 1471 for(z=*paz; *z && *z!='='; z++){}
1391 *z = 0; 1472 *z = 0;
1392 } 1473 }
1393 1474
1394 static char *user_templatename = NULL; 1475 static char *user_templatename = NULL;
1395 static void handle_T_option(char *z){ 1476 static void handle_T_option(char *z){
1396 user_templatename = (char *) malloc( lemonStrlen(z)+1 ); 1477 user_templatename = (char *) malloc( lemonStrlen(z)+1 );
1397 if( user_templatename==0 ){ 1478 if( user_templatename==0 ){
1398 memory_error(); 1479 memory_error();
1399 } 1480 }
1400 strcpy(user_templatename, z); 1481 lemon_strcpy(user_templatename, z);
1401 } 1482 }
1402 1483
1403 /* The main program. Parse the command line and do it... */ 1484 /* The main program. Parse the command line and do it... */
1404 int main(int argc, char **argv) 1485 int main(int argc, char **argv)
1405 { 1486 {
1406 static int version = 0; 1487 static int version = 0;
1407 static int rpflag = 0; 1488 static int rpflag = 0;
1408 static int basisflag = 0; 1489 static int basisflag = 0;
1409 static int compress = 0; 1490 static int compress = 0;
1410 static int quiet = 0; 1491 static int quiet = 0;
(...skipping 15 matching lines...) Expand all
1426 {OPT_FLAG, "r", (char*)&noResort, "Do not sort or renumber states"}, 1507 {OPT_FLAG, "r", (char*)&noResort, "Do not sort or renumber states"},
1427 {OPT_FLAG, "s", (char*)&statistics, 1508 {OPT_FLAG, "s", (char*)&statistics,
1428 "Print parser stats to standard output."}, 1509 "Print parser stats to standard output."},
1429 {OPT_FLAG, "x", (char*)&version, "Print the version number."}, 1510 {OPT_FLAG, "x", (char*)&version, "Print the version number."},
1430 {OPT_FLAG,0,0,0} 1511 {OPT_FLAG,0,0,0}
1431 }; 1512 };
1432 int i; 1513 int i;
1433 int exitcode; 1514 int exitcode;
1434 struct lemon lem; 1515 struct lemon lem;
1435 1516
1436 atexit(LemonAtExit);
1437
1438 OptInit(argv,options,stderr); 1517 OptInit(argv,options,stderr);
1439 if( version ){ 1518 if( version ){
1440 printf("Lemon version 1.0\n"); 1519 printf("Lemon version 1.0\n");
1441 exit(0); 1520 exit(0);
1442 } 1521 }
1443 if( OptNArgs()!=1 ){ 1522 if( OptNArgs()!=1 ){
1444 fprintf(stderr,"Exactly one filename argument is required.\n"); 1523 fprintf(stderr,"Exactly one filename argument is required.\n");
1445 exit(1); 1524 exit(1);
1446 } 1525 }
1447 memset(&lem, 0, sizeof(lem)); 1526 memset(&lem, 0, sizeof(lem));
(...skipping 13 matching lines...) Expand all
1461 1540
1462 /* Parse the input file */ 1541 /* Parse the input file */
1463 Parse(&lem); 1542 Parse(&lem);
1464 if( lem.errorcnt ) exit(lem.errorcnt); 1543 if( lem.errorcnt ) exit(lem.errorcnt);
1465 if( lem.nrule==0 ){ 1544 if( lem.nrule==0 ){
1466 fprintf(stderr,"Empty grammar.\n"); 1545 fprintf(stderr,"Empty grammar.\n");
1467 exit(1); 1546 exit(1);
1468 } 1547 }
1469 1548
1470 /* Count and index the symbols of the grammar */ 1549 /* Count and index the symbols of the grammar */
1550 Symbol_new("{default}");
1471 lem.nsymbol = Symbol_count(); 1551 lem.nsymbol = Symbol_count();
1472 Symbol_new("{default}");
1473 lem.symbols = Symbol_arrayof(); 1552 lem.symbols = Symbol_arrayof();
1474 for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; 1553 for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
1475 qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), Symbolcmpp); 1554 qsort(lem.symbols,lem.nsymbol,sizeof(struct symbol*), Symbolcmpp);
1476 for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i; 1555 for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
1556 while( lem.symbols[i-1]->type==MULTITERMINAL ){ i--; }
1557 assert( strcmp(lem.symbols[i-1]->name,"{default}")==0 );
1558 lem.nsymbol = i - 1;
1477 for(i=1; isupper(lem.symbols[i]->name[0]); i++); 1559 for(i=1; isupper(lem.symbols[i]->name[0]); i++);
1478 lem.nterminal = i; 1560 lem.nterminal = i;
1479 1561
1480 /* Generate a reprint of the grammar, if requested on the command line */ 1562 /* Generate a reprint of the grammar, if requested on the command line */
1481 if( rpflag ){ 1563 if( rpflag ){
1482 Reprint(&lem); 1564 Reprint(&lem);
1483 }else{ 1565 }else{
1484 /* Initialize the size for all follow and first sets */ 1566 /* Initialize the size for all follow and first sets */
1485 SetSize(lem.nterminal+1); 1567 SetSize(lem.nterminal+1);
1486 1568
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1530 lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule); 1612 lem.nterminal, lem.nsymbol - lem.nterminal, lem.nrule);
1531 printf(" %d states, %d parser table entries, %d conflicts\ n", 1613 printf(" %d states, %d parser table entries, %d conflicts\ n",
1532 lem.nstate, lem.tablesize, lem.nconflict); 1614 lem.nstate, lem.tablesize, lem.nconflict);
1533 } 1615 }
1534 if( lem.nconflict > 0 ){ 1616 if( lem.nconflict > 0 ){
1535 fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict); 1617 fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict);
1536 } 1618 }
1537 1619
1538 /* return 0 on success, 1 on failure. */ 1620 /* return 0 on success, 1 on failure. */
1539 exitcode = ((lem.errorcnt > 0) || (lem.nconflict > 0)) ? 1 : 0; 1621 exitcode = ((lem.errorcnt > 0) || (lem.nconflict > 0)) ? 1 : 0;
1540 successful_exit = (exitcode == 0);
1541 exit(exitcode); 1622 exit(exitcode);
1542 return (exitcode); 1623 return (exitcode);
1543 } 1624 }
1544 /******************** From the file "msort.c" *******************************/ 1625 /******************** From the file "msort.c" *******************************/
1545 /* 1626 /*
1546 ** A generic merge-sort program. 1627 ** A generic merge-sort program.
1547 ** 1628 **
1548 ** USAGE: 1629 ** USAGE:
1549 ** Let "ptr" be a pointer to some structure which is at the head of 1630 ** Let "ptr" be a pointer to some structure which is at the head of
1550 ** a null-terminated list. Then to sort the list call: 1631 ** a null-terminated list. Then to sort the list call:
(...skipping 10 matching lines...) Expand all
1561 ** The function returns a new pointer which is the head of the list 1642 ** The function returns a new pointer which is the head of the list
1562 ** after sorting. 1643 ** after sorting.
1563 ** 1644 **
1564 ** ALGORITHM: 1645 ** ALGORITHM:
1565 ** Merge-sort. 1646 ** Merge-sort.
1566 */ 1647 */
1567 1648
1568 /* 1649 /*
1569 ** Return a pointer to the next structure in the linked list. 1650 ** Return a pointer to the next structure in the linked list.
1570 */ 1651 */
1571 #define NEXT(A) (*(char**)(((unsigned long)A)+offset)) 1652 #define NEXT(A) (*(char**)(((char*)A)+offset))
1572 1653
1573 /* 1654 /*
1574 ** Inputs: 1655 ** Inputs:
1575 ** a: A sorted, null-terminated linked list. (May be null). 1656 ** a: A sorted, null-terminated linked list. (May be null).
1576 ** b: A sorted, null-terminated linked list. (May be null). 1657 ** b: A sorted, null-terminated linked list. (May be null).
1577 ** cmp: A pointer to the comparison function. 1658 ** cmp: A pointer to the comparison function.
1578 ** offset: Offset in the structure to the "next" field. 1659 ** offset: Offset in the structure to the "next" field.
1579 ** 1660 **
1580 ** Return Value: 1661 ** Return Value:
1581 ** A pointer to the head of a sorted list containing the elements 1662 ** A pointer to the head of a sorted list containing the elements
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
1955 LHS_ALIAS_3, 2036 LHS_ALIAS_3,
1956 RHS_ALIAS_1, 2037 RHS_ALIAS_1,
1957 RHS_ALIAS_2, 2038 RHS_ALIAS_2,
1958 PRECEDENCE_MARK_1, 2039 PRECEDENCE_MARK_1,
1959 PRECEDENCE_MARK_2, 2040 PRECEDENCE_MARK_2,
1960 RESYNC_AFTER_RULE_ERROR, 2041 RESYNC_AFTER_RULE_ERROR,
1961 RESYNC_AFTER_DECL_ERROR, 2042 RESYNC_AFTER_DECL_ERROR,
1962 WAITING_FOR_DESTRUCTOR_SYMBOL, 2043 WAITING_FOR_DESTRUCTOR_SYMBOL,
1963 WAITING_FOR_DATATYPE_SYMBOL, 2044 WAITING_FOR_DATATYPE_SYMBOL,
1964 WAITING_FOR_FALLBACK_ID, 2045 WAITING_FOR_FALLBACK_ID,
1965 WAITING_FOR_WILDCARD_ID 2046 WAITING_FOR_WILDCARD_ID,
2047 WAITING_FOR_CLASS_ID,
2048 WAITING_FOR_CLASS_TOKEN
1966 }; 2049 };
1967 struct pstate { 2050 struct pstate {
1968 char *filename; /* Name of the input file */ 2051 char *filename; /* Name of the input file */
1969 int tokenlineno; /* Linenumber at which current token starts */ 2052 int tokenlineno; /* Linenumber at which current token starts */
1970 int errorcnt; /* Number of errors so far */ 2053 int errorcnt; /* Number of errors so far */
1971 char *tokenstart; /* Text of current token */ 2054 char *tokenstart; /* Text of current token */
1972 struct lemon *gp; /* Global state vector */ 2055 struct lemon *gp; /* Global state vector */
1973 enum e_state state; /* The state of the parser */ 2056 enum e_state state; /* The state of the parser */
1974 struct symbol *fallback; /* The fallback token */ 2057 struct symbol *fallback; /* The fallback token */
2058 struct symbol *tkclass; /* Token class symbol */
1975 struct symbol *lhs; /* Left-hand side of current rule */ 2059 struct symbol *lhs; /* Left-hand side of current rule */
1976 const char *lhsalias; /* Alias for the LHS */ 2060 const char *lhsalias; /* Alias for the LHS */
1977 int nrhs; /* Number of right-hand side symbols seen */ 2061 int nrhs; /* Number of right-hand side symbols seen */
1978 struct symbol *rhs[MAXRHS]; /* RHS symbols */ 2062 struct symbol *rhs[MAXRHS]; /* RHS symbols */
1979 const char *alias[MAXRHS]; /* Aliases for each RHS symbol (or NULL) */ 2063 const char *alias[MAXRHS]; /* Aliases for each RHS symbol (or NULL) */
1980 struct rule *prevrule; /* Previous rule parsed */ 2064 struct rule *prevrule; /* Previous rule parsed */
1981 const char *declkeyword; /* Keyword of a declaration */ 2065 const char *declkeyword; /* Keyword of a declaration */
1982 char **declargslot; /* Where the declaration argument should be put */ 2066 char **declargslot; /* Where the declaration argument should be put */
1983 int insertLineMacro; /* Add #line before declaration insert */ 2067 int insertLineMacro; /* Add #line before declaration insert */
1984 int *decllinenoslot; /* Where to write declaration line number */ 2068 int *decllinenoslot; /* Where to write declaration line number */
(...skipping 23 matching lines...) Expand all
2008 if( x[0]=='%' ){ 2092 if( x[0]=='%' ){
2009 psp->state = WAITING_FOR_DECL_KEYWORD; 2093 psp->state = WAITING_FOR_DECL_KEYWORD;
2010 }else if( islower(x[0]) ){ 2094 }else if( islower(x[0]) ){
2011 psp->lhs = Symbol_new(x); 2095 psp->lhs = Symbol_new(x);
2012 psp->nrhs = 0; 2096 psp->nrhs = 0;
2013 psp->lhsalias = 0; 2097 psp->lhsalias = 0;
2014 psp->state = WAITING_FOR_ARROW; 2098 psp->state = WAITING_FOR_ARROW;
2015 }else if( x[0]=='{' ){ 2099 }else if( x[0]=='{' ){
2016 if( psp->prevrule==0 ){ 2100 if( psp->prevrule==0 ){
2017 ErrorMsg(psp->filename,psp->tokenlineno, 2101 ErrorMsg(psp->filename,psp->tokenlineno,
2018 "There is no prior rule opon which to attach the code \ 2102 "There is no prior rule upon which to attach the code \
2019 fragment which begins on this line."); 2103 fragment which begins on this line.");
2020 psp->errorcnt++; 2104 psp->errorcnt++;
2021 » }else if( psp->prevrule->code!=0 ){ 2105 }else if( psp->prevrule->code!=0 ){
2022 ErrorMsg(psp->filename,psp->tokenlineno, 2106 ErrorMsg(psp->filename,psp->tokenlineno,
2023 "Code fragment beginning on this line is not the first \ 2107 "Code fragment beginning on this line is not the first \
2024 to follow the previous rule."); 2108 to follow the previous rule.");
2025 psp->errorcnt++; 2109 psp->errorcnt++;
2026 }else{ 2110 }else{
2027 psp->prevrule->line = psp->tokenlineno; 2111 psp->prevrule->line = psp->tokenlineno;
2028 psp->prevrule->code = &x[1]; 2112 psp->prevrule->code = &x[1];
2029 » } 2113 }
2030 }else if( x[0]=='[' ){ 2114 }else if( x[0]=='[' ){
2031 psp->state = PRECEDENCE_MARK_1; 2115 psp->state = PRECEDENCE_MARK_1;
2032 }else{ 2116 }else{
2033 ErrorMsg(psp->filename,psp->tokenlineno, 2117 ErrorMsg(psp->filename,psp->tokenlineno,
2034 "Token \"%s\" should be either \"%%\" or a nonterminal name.", 2118 "Token \"%s\" should be either \"%%\" or a nonterminal name.",
2035 x); 2119 x);
2036 psp->errorcnt++; 2120 psp->errorcnt++;
2037 } 2121 }
2038 break; 2122 break;
2039 case PRECEDENCE_MARK_1: 2123 case PRECEDENCE_MARK_1:
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2112 case IN_RHS: 2196 case IN_RHS:
2113 if( x[0]=='.' ){ 2197 if( x[0]=='.' ){
2114 struct rule *rp; 2198 struct rule *rp;
2115 rp = (struct rule *)calloc( sizeof(struct rule) + 2199 rp = (struct rule *)calloc( sizeof(struct rule) +
2116 sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1); 2200 sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1);
2117 if( rp==0 ){ 2201 if( rp==0 ){
2118 ErrorMsg(psp->filename,psp->tokenlineno, 2202 ErrorMsg(psp->filename,psp->tokenlineno,
2119 "Can't allocate enough memory for this rule."); 2203 "Can't allocate enough memory for this rule.");
2120 psp->errorcnt++; 2204 psp->errorcnt++;
2121 psp->prevrule = 0; 2205 psp->prevrule = 0;
2122 » }else{ 2206 }else{
2123 int i; 2207 int i;
2124 rp->ruleline = psp->tokenlineno; 2208 rp->ruleline = psp->tokenlineno;
2125 rp->rhs = (struct symbol**)&rp[1]; 2209 rp->rhs = (struct symbol**)&rp[1];
2126 rp->rhsalias = (const char**)&(rp->rhs[psp->nrhs]); 2210 rp->rhsalias = (const char**)&(rp->rhs[psp->nrhs]);
2127 for(i=0; i<psp->nrhs; i++){ 2211 for(i=0; i<psp->nrhs; i++){
2128 rp->rhs[i] = psp->rhs[i]; 2212 rp->rhs[i] = psp->rhs[i];
2129 rp->rhsalias[i] = psp->alias[i]; 2213 rp->rhsalias[i] = psp->alias[i];
2130 » } 2214 }
2131 rp->lhs = psp->lhs; 2215 rp->lhs = psp->lhs;
2132 rp->lhsalias = psp->lhsalias; 2216 rp->lhsalias = psp->lhsalias;
2133 rp->nrhs = psp->nrhs; 2217 rp->nrhs = psp->nrhs;
2134 rp->code = 0; 2218 rp->code = 0;
2135 rp->precsym = 0; 2219 rp->precsym = 0;
2136 rp->index = psp->gp->nrule++; 2220 rp->index = psp->gp->nrule++;
2137 rp->nextlhs = rp->lhs->rule; 2221 rp->nextlhs = rp->lhs->rule;
2138 rp->lhs->rule = rp; 2222 rp->lhs->rule = rp;
2139 rp->next = 0; 2223 rp->next = 0;
2140 if( psp->firstrule==0 ){ 2224 if( psp->firstrule==0 ){
2141 psp->firstrule = psp->lastrule = rp; 2225 psp->firstrule = psp->lastrule = rp;
2142 » }else{ 2226 }else{
2143 psp->lastrule->next = rp; 2227 psp->lastrule->next = rp;
2144 psp->lastrule = rp; 2228 psp->lastrule = rp;
2145 » } 2229 }
2146 psp->prevrule = rp; 2230 psp->prevrule = rp;
2147 » } 2231 }
2148 psp->state = WAITING_FOR_DECL_OR_RULE; 2232 psp->state = WAITING_FOR_DECL_OR_RULE;
2149 }else if( isalpha(x[0]) ){ 2233 }else if( isalpha(x[0]) ){
2150 if( psp->nrhs>=MAXRHS ){ 2234 if( psp->nrhs>=MAXRHS ){
2151 ErrorMsg(psp->filename,psp->tokenlineno, 2235 ErrorMsg(psp->filename,psp->tokenlineno,
2152 "Too many symbols on RHS of rule beginning at \"%s\".", 2236 "Too many symbols on RHS of rule beginning at \"%s\".",
2153 x); 2237 x);
2154 psp->errorcnt++; 2238 psp->errorcnt++;
2155 psp->state = RESYNC_AFTER_RULE_ERROR; 2239 psp->state = RESYNC_AFTER_RULE_ERROR;
2156 » }else{ 2240 }else{
2157 psp->rhs[psp->nrhs] = Symbol_new(x); 2241 psp->rhs[psp->nrhs] = Symbol_new(x);
2158 psp->alias[psp->nrhs] = 0; 2242 psp->alias[psp->nrhs] = 0;
2159 psp->nrhs++; 2243 psp->nrhs++;
2160 » } 2244 }
2161 }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){ 2245 }else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){
2162 struct symbol *msp = psp->rhs[psp->nrhs-1]; 2246 struct symbol *msp = psp->rhs[psp->nrhs-1];
2163 if( msp->type!=MULTITERMINAL ){ 2247 if( msp->type!=MULTITERMINAL ){
2164 struct symbol *origsp = msp; 2248 struct symbol *origsp = msp;
2165 msp = (struct symbol *) calloc(1,sizeof(*msp)); 2249 msp = (struct symbol *) calloc(1,sizeof(*msp));
2166 memset(msp, 0, sizeof(*msp)); 2250 memset(msp, 0, sizeof(*msp));
2167 msp->type = MULTITERMINAL; 2251 msp->type = MULTITERMINAL;
2168 msp->nsubsym = 1; 2252 msp->nsubsym = 1;
2169 msp->subsym = (struct symbol **) calloc(1,sizeof(struct symbol*)); 2253 msp->subsym = (struct symbol **) calloc(1,sizeof(struct symbol*));
2170 msp->subsym[0] = origsp; 2254 msp->subsym[0] = origsp;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2214 case WAITING_FOR_DECL_KEYWORD: 2298 case WAITING_FOR_DECL_KEYWORD:
2215 if( isalpha(x[0]) ){ 2299 if( isalpha(x[0]) ){
2216 psp->declkeyword = x; 2300 psp->declkeyword = x;
2217 psp->declargslot = 0; 2301 psp->declargslot = 0;
2218 psp->decllinenoslot = 0; 2302 psp->decllinenoslot = 0;
2219 psp->insertLineMacro = 1; 2303 psp->insertLineMacro = 1;
2220 psp->state = WAITING_FOR_DECL_ARG; 2304 psp->state = WAITING_FOR_DECL_ARG;
2221 if( strcmp(x,"name")==0 ){ 2305 if( strcmp(x,"name")==0 ){
2222 psp->declargslot = &(psp->gp->name); 2306 psp->declargslot = &(psp->gp->name);
2223 psp->insertLineMacro = 0; 2307 psp->insertLineMacro = 0;
2224 » }else if( strcmp(x,"include")==0 ){ 2308 }else if( strcmp(x,"include")==0 ){
2225 psp->declargslot = &(psp->gp->include); 2309 psp->declargslot = &(psp->gp->include);
2226 » }else if( strcmp(x,"code")==0 ){ 2310 }else if( strcmp(x,"code")==0 ){
2227 psp->declargslot = &(psp->gp->extracode); 2311 psp->declargslot = &(psp->gp->extracode);
2228 » }else if( strcmp(x,"token_destructor")==0 ){ 2312 }else if( strcmp(x,"token_destructor")==0 ){
2229 psp->declargslot = &psp->gp->tokendest; 2313 psp->declargslot = &psp->gp->tokendest;
2230 » }else if( strcmp(x,"default_destructor")==0 ){ 2314 }else if( strcmp(x,"default_destructor")==0 ){
2231 psp->declargslot = &psp->gp->vardest; 2315 psp->declargslot = &psp->gp->vardest;
2232 » }else if( strcmp(x,"token_prefix")==0 ){ 2316 }else if( strcmp(x,"token_prefix")==0 ){
2233 psp->declargslot = &psp->gp->tokenprefix; 2317 psp->declargslot = &psp->gp->tokenprefix;
2234 psp->insertLineMacro = 0; 2318 psp->insertLineMacro = 0;
2235 » }else if( strcmp(x,"syntax_error")==0 ){ 2319 }else if( strcmp(x,"syntax_error")==0 ){
2236 psp->declargslot = &(psp->gp->error); 2320 psp->declargslot = &(psp->gp->error);
2237 » }else if( strcmp(x,"parse_accept")==0 ){ 2321 }else if( strcmp(x,"parse_accept")==0 ){
2238 psp->declargslot = &(psp->gp->accept); 2322 psp->declargslot = &(psp->gp->accept);
2239 » }else if( strcmp(x,"parse_failure")==0 ){ 2323 }else if( strcmp(x,"parse_failure")==0 ){
2240 psp->declargslot = &(psp->gp->failure); 2324 psp->declargslot = &(psp->gp->failure);
2241 » }else if( strcmp(x,"stack_overflow")==0 ){ 2325 }else if( strcmp(x,"stack_overflow")==0 ){
2242 psp->declargslot = &(psp->gp->overflow); 2326 psp->declargslot = &(psp->gp->overflow);
2243 }else if( strcmp(x,"extra_argument")==0 ){ 2327 }else if( strcmp(x,"extra_argument")==0 ){
2244 psp->declargslot = &(psp->gp->arg); 2328 psp->declargslot = &(psp->gp->arg);
2245 psp->insertLineMacro = 0; 2329 psp->insertLineMacro = 0;
2246 }else if( strcmp(x,"token_type")==0 ){ 2330 }else if( strcmp(x,"token_type")==0 ){
2247 psp->declargslot = &(psp->gp->tokentype); 2331 psp->declargslot = &(psp->gp->tokentype);
2248 psp->insertLineMacro = 0; 2332 psp->insertLineMacro = 0;
2249 }else if( strcmp(x,"default_type")==0 ){ 2333 }else if( strcmp(x,"default_type")==0 ){
2250 psp->declargslot = &(psp->gp->vartype); 2334 psp->declargslot = &(psp->gp->vartype);
2251 psp->insertLineMacro = 0; 2335 psp->insertLineMacro = 0;
2252 }else if( strcmp(x,"stack_size")==0 ){ 2336 }else if( strcmp(x,"stack_size")==0 ){
2253 psp->declargslot = &(psp->gp->stacksize); 2337 psp->declargslot = &(psp->gp->stacksize);
2254 psp->insertLineMacro = 0; 2338 psp->insertLineMacro = 0;
2255 }else if( strcmp(x,"start_symbol")==0 ){ 2339 }else if( strcmp(x,"start_symbol")==0 ){
2256 psp->declargslot = &(psp->gp->start); 2340 psp->declargslot = &(psp->gp->start);
2257 psp->insertLineMacro = 0; 2341 psp->insertLineMacro = 0;
2258 }else if( strcmp(x,"left")==0 ){ 2342 }else if( strcmp(x,"left")==0 ){
2259 psp->preccounter++; 2343 psp->preccounter++;
2260 psp->declassoc = LEFT; 2344 psp->declassoc = LEFT;
2261 psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; 2345 psp->state = WAITING_FOR_PRECEDENCE_SYMBOL;
2262 }else if( strcmp(x,"right")==0 ){ 2346 }else if( strcmp(x,"right")==0 ){
2263 psp->preccounter++; 2347 psp->preccounter++;
2264 psp->declassoc = RIGHT; 2348 psp->declassoc = RIGHT;
2265 psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; 2349 psp->state = WAITING_FOR_PRECEDENCE_SYMBOL;
2266 }else if( strcmp(x,"nonassoc")==0 ){ 2350 }else if( strcmp(x,"nonassoc")==0 ){
2267 psp->preccounter++; 2351 psp->preccounter++;
2268 psp->declassoc = NONE; 2352 psp->declassoc = NONE;
2269 psp->state = WAITING_FOR_PRECEDENCE_SYMBOL; 2353 psp->state = WAITING_FOR_PRECEDENCE_SYMBOL;
2270 » }else if( strcmp(x,"destructor")==0 ){ 2354 }else if( strcmp(x,"destructor")==0 ){
2271 psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL; 2355 psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL;
2272 » }else if( strcmp(x,"type")==0 ){ 2356 }else if( strcmp(x,"type")==0 ){
2273 psp->state = WAITING_FOR_DATATYPE_SYMBOL; 2357 psp->state = WAITING_FOR_DATATYPE_SYMBOL;
2274 }else if( strcmp(x,"fallback")==0 ){ 2358 }else if( strcmp(x,"fallback")==0 ){
2275 psp->fallback = 0; 2359 psp->fallback = 0;
2276 psp->state = WAITING_FOR_FALLBACK_ID; 2360 psp->state = WAITING_FOR_FALLBACK_ID;
2277 }else if( strcmp(x,"wildcard")==0 ){ 2361 }else if( strcmp(x,"wildcard")==0 ){
2278 psp->state = WAITING_FOR_WILDCARD_ID; 2362 psp->state = WAITING_FOR_WILDCARD_ID;
2363 }else if( strcmp(x,"token_class")==0 ){
2364 psp->state = WAITING_FOR_CLASS_ID;
2279 }else{ 2365 }else{
2280 ErrorMsg(psp->filename,psp->tokenlineno, 2366 ErrorMsg(psp->filename,psp->tokenlineno,
2281 "Unknown declaration keyword: \"%%%s\".",x); 2367 "Unknown declaration keyword: \"%%%s\".",x);
2282 psp->errorcnt++; 2368 psp->errorcnt++;
2283 psp->state = RESYNC_AFTER_DECL_ERROR; 2369 psp->state = RESYNC_AFTER_DECL_ERROR;
2284 » } 2370 }
2285 }else{ 2371 }else{
2286 ErrorMsg(psp->filename,psp->tokenlineno, 2372 ErrorMsg(psp->filename,psp->tokenlineno,
2287 "Illegal declaration keyword: \"%s\".",x); 2373 "Illegal declaration keyword: \"%s\".",x);
2288 psp->errorcnt++; 2374 psp->errorcnt++;
2289 psp->state = RESYNC_AFTER_DECL_ERROR; 2375 psp->state = RESYNC_AFTER_DECL_ERROR;
2290 } 2376 }
2291 break; 2377 break;
2292 case WAITING_FOR_DESTRUCTOR_SYMBOL: 2378 case WAITING_FOR_DESTRUCTOR_SYMBOL:
2293 if( !isalpha(x[0]) ){ 2379 if( !isalpha(x[0]) ){
2294 ErrorMsg(psp->filename,psp->tokenlineno, 2380 ErrorMsg(psp->filename,psp->tokenlineno,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2329 case WAITING_FOR_PRECEDENCE_SYMBOL: 2415 case WAITING_FOR_PRECEDENCE_SYMBOL:
2330 if( x[0]=='.' ){ 2416 if( x[0]=='.' ){
2331 psp->state = WAITING_FOR_DECL_OR_RULE; 2417 psp->state = WAITING_FOR_DECL_OR_RULE;
2332 }else if( isupper(x[0]) ){ 2418 }else if( isupper(x[0]) ){
2333 struct symbol *sp; 2419 struct symbol *sp;
2334 sp = Symbol_new(x); 2420 sp = Symbol_new(x);
2335 if( sp->prec>=0 ){ 2421 if( sp->prec>=0 ){
2336 ErrorMsg(psp->filename,psp->tokenlineno, 2422 ErrorMsg(psp->filename,psp->tokenlineno,
2337 "Symbol \"%s\" has already be given a precedence.",x); 2423 "Symbol \"%s\" has already be given a precedence.",x);
2338 psp->errorcnt++; 2424 psp->errorcnt++;
2339 » }else{ 2425 }else{
2340 sp->prec = psp->preccounter; 2426 sp->prec = psp->preccounter;
2341 sp->assoc = psp->declassoc; 2427 sp->assoc = psp->declassoc;
2342 » } 2428 }
2343 }else{ 2429 }else{
2344 ErrorMsg(psp->filename,psp->tokenlineno, 2430 ErrorMsg(psp->filename,psp->tokenlineno,
2345 "Can't assign a precedence to \"%s\".",x); 2431 "Can't assign a precedence to \"%s\".",x);
2346 psp->errorcnt++; 2432 psp->errorcnt++;
2347 } 2433 }
2348 break; 2434 break;
2349 case WAITING_FOR_DECL_ARG: 2435 case WAITING_FOR_DECL_ARG:
2350 if( x[0]=='{' || x[0]=='\"' || isalnum(x[0]) ){ 2436 if( x[0]=='{' || x[0]=='\"' || isalnum(x[0]) ){
2351 const char *zOld, *zNew; 2437 const char *zOld, *zNew;
2352 char *zBuf, *z; 2438 char *zBuf, *z;
2353 int nOld, n, nLine, nNew, nBack; 2439 int nOld, n, nLine, nNew, nBack;
2354 int addLineMacro; 2440 int addLineMacro;
2355 char zLine[50]; 2441 char zLine[50];
2356 zNew = x; 2442 zNew = x;
2357 if( zNew[0]=='"' || zNew[0]=='{' ) zNew++; 2443 if( zNew[0]=='"' || zNew[0]=='{' ) zNew++;
2358 nNew = lemonStrlen(zNew); 2444 nNew = lemonStrlen(zNew);
2359 if( *psp->declargslot ){ 2445 if( *psp->declargslot ){
2360 zOld = *psp->declargslot; 2446 zOld = *psp->declargslot;
2361 }else{ 2447 }else{
2362 zOld = ""; 2448 zOld = "";
2363 } 2449 }
2364 nOld = lemonStrlen(zOld); 2450 nOld = lemonStrlen(zOld);
2365 n = nOld + nNew + 20; 2451 n = nOld + nNew + 20;
2366 addLineMacro = !psp->gp->nolinenosflag && psp->insertLineMacro && 2452 addLineMacro = !psp->gp->nolinenosflag && psp->insertLineMacro &&
2367 (psp->decllinenoslot==0 || psp->decllinenoslot[0]!=0); 2453 (psp->decllinenoslot==0 || psp->decllinenoslot[0]!=0);
2368 if( addLineMacro ){ 2454 if( addLineMacro ){
2369 for(z=psp->filename, nBack=0; *z; z++){ 2455 for(z=psp->filename, nBack=0; *z; z++){
2370 if( *z=='\\' ) nBack++; 2456 if( *z=='\\' ) nBack++;
2371 } 2457 }
2372 sprintf(zLine, "#line %d ", psp->tokenlineno); 2458 lemon_sprintf(zLine, "#line %d ", psp->tokenlineno);
2373 nLine = lemonStrlen(zLine); 2459 nLine = lemonStrlen(zLine);
2374 n += nLine + lemonStrlen(psp->filename) + nBack; 2460 n += nLine + lemonStrlen(psp->filename) + nBack;
2375 } 2461 }
2376 *psp->declargslot = (char *) realloc(*psp->declargslot, n); 2462 *psp->declargslot = (char *) realloc(*psp->declargslot, n);
2377 zBuf = *psp->declargslot + nOld; 2463 zBuf = *psp->declargslot + nOld;
2378 if( addLineMacro ){ 2464 if( addLineMacro ){
2379 if( nOld && zBuf[-1]!='\n' ){ 2465 if( nOld && zBuf[-1]!='\n' ){
2380 *(zBuf++) = '\n'; 2466 *(zBuf++) = '\n';
2381 } 2467 }
2382 memcpy(zBuf, zLine, nLine); 2468 memcpy(zBuf, zLine, nLine);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2437 struct symbol *sp = Symbol_new(x); 2523 struct symbol *sp = Symbol_new(x);
2438 if( psp->gp->wildcard==0 ){ 2524 if( psp->gp->wildcard==0 ){
2439 psp->gp->wildcard = sp; 2525 psp->gp->wildcard = sp;
2440 }else{ 2526 }else{
2441 ErrorMsg(psp->filename, psp->tokenlineno, 2527 ErrorMsg(psp->filename, psp->tokenlineno,
2442 "Extra wildcard to token: %s", x); 2528 "Extra wildcard to token: %s", x);
2443 psp->errorcnt++; 2529 psp->errorcnt++;
2444 } 2530 }
2445 } 2531 }
2446 break; 2532 break;
2533 case WAITING_FOR_CLASS_ID:
2534 if( !islower(x[0]) ){
2535 ErrorMsg(psp->filename, psp->tokenlineno,
2536 "%%token_class must be followed by an identifier: ", x);
2537 psp->errorcnt++;
2538 psp->state = RESYNC_AFTER_DECL_ERROR;
2539 }else if( Symbol_find(x) ){
2540 ErrorMsg(psp->filename, psp->tokenlineno,
2541 "Symbol \"%s\" already used", x);
2542 psp->errorcnt++;
2543 psp->state = RESYNC_AFTER_DECL_ERROR;
2544 }else{
2545 psp->tkclass = Symbol_new(x);
2546 psp->tkclass->type = MULTITERMINAL;
2547 psp->state = WAITING_FOR_CLASS_TOKEN;
2548 }
2549 break;
2550 case WAITING_FOR_CLASS_TOKEN:
2551 if( x[0]=='.' ){
2552 psp->state = WAITING_FOR_DECL_OR_RULE;
2553 }else if( isupper(x[0]) || ((x[0]=='|' || x[0]=='/') && isupper(x[1])) ){
2554 struct symbol *msp = psp->tkclass;
2555 msp->nsubsym++;
2556 msp->subsym = (struct symbol **) realloc(msp->subsym,
2557 sizeof(struct symbol*)*msp->nsubsym);
2558 if( !isupper(x[0]) ) x++;
2559 msp->subsym[msp->nsubsym-1] = Symbol_new(x);
2560 }else{
2561 ErrorMsg(psp->filename, psp->tokenlineno,
2562 "%%token_class argument \"%s\" should be a token", x);
2563 psp->errorcnt++;
2564 psp->state = RESYNC_AFTER_DECL_ERROR;
2565 }
2566 break;
2447 case RESYNC_AFTER_RULE_ERROR: 2567 case RESYNC_AFTER_RULE_ERROR:
2448 /* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; 2568 /* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE;
2449 ** break; */ 2569 ** break; */
2450 case RESYNC_AFTER_DECL_ERROR: 2570 case RESYNC_AFTER_DECL_ERROR:
2451 if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE; 2571 if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE;
2452 if( x[0]=='%' ) psp->state = WAITING_FOR_DECL_KEYWORD; 2572 if( x[0]=='%' ) psp->state = WAITING_FOR_DECL_KEYWORD;
2453 break; 2573 break;
2454 } 2574 }
2455 } 2575 }
2456 2576
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2531 fp = fopen(ps.filename,"rb"); 2651 fp = fopen(ps.filename,"rb");
2532 if( fp==0 ){ 2652 if( fp==0 ){
2533 ErrorMsg(ps.filename,0,"Can't open this file for reading."); 2653 ErrorMsg(ps.filename,0,"Can't open this file for reading.");
2534 gp->errorcnt++; 2654 gp->errorcnt++;
2535 return; 2655 return;
2536 } 2656 }
2537 fseek(fp,0,2); 2657 fseek(fp,0,2);
2538 filesize = ftell(fp); 2658 filesize = ftell(fp);
2539 rewind(fp); 2659 rewind(fp);
2540 filebuf = (char *)malloc( filesize+1 ); 2660 filebuf = (char *)malloc( filesize+1 );
2541 if( filebuf==0 ){ 2661 if( filesize>100000000 || filebuf==0 ){
2542 ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.", 2662 ErrorMsg(ps.filename,0,"Input file too large.");
2543 filesize+1);
2544 gp->errorcnt++; 2663 gp->errorcnt++;
2664 fclose(fp);
2545 return; 2665 return;
2546 } 2666 }
2547 if( fread(filebuf,1,filesize,fp)!=filesize ){ 2667 if( fread(filebuf,1,filesize,fp)!=filesize ){
2548 ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.", 2668 ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.",
2549 filesize); 2669 filesize);
2550 free(filebuf); 2670 free(filebuf);
2551 gp->errorcnt++; 2671 gp->errorcnt++;
2672 fclose(fp);
2552 return; 2673 return;
2553 } 2674 }
2554 fclose(fp); 2675 fclose(fp);
2555 filebuf[filesize] = 0; 2676 filebuf[filesize] = 0;
2556 2677
2557 /* Make an initial pass through the file to handle %ifdef and %ifndef */ 2678 /* Make an initial pass through the file to handle %ifdef and %ifndef */
2558 preprocess_input(filebuf); 2679 preprocess_input(filebuf);
2559 2680
2560 /* Now scan the text of the input file */ 2681 /* Now scan the text of the input file */
2561 lineno = 1; 2682 lineno = 1;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2600 else if( c=='{' ) level++; 2721 else if( c=='{' ) level++;
2601 else if( c=='}' ) level--; 2722 else if( c=='}' ) level--;
2602 else if( c=='/' && cp[1]=='*' ){ /* Skip comments */ 2723 else if( c=='/' && cp[1]=='*' ){ /* Skip comments */
2603 int prevc; 2724 int prevc;
2604 cp = &cp[2]; 2725 cp = &cp[2];
2605 prevc = 0; 2726 prevc = 0;
2606 while( (c= *cp)!=0 && (c!='/' || prevc!='*') ){ 2727 while( (c= *cp)!=0 && (c!='/' || prevc!='*') ){
2607 if( c=='\n' ) lineno++; 2728 if( c=='\n' ) lineno++;
2608 prevc = c; 2729 prevc = c;
2609 cp++; 2730 cp++;
2610 » } 2731 }
2611 » }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */ 2732 }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */
2612 cp = &cp[2]; 2733 cp = &cp[2];
2613 while( (c= *cp)!=0 && c!='\n' ) cp++; 2734 while( (c= *cp)!=0 && c!='\n' ) cp++;
2614 if( c ) lineno++; 2735 if( c ) lineno++;
2615 » }else if( c=='\'' || c=='\"' ){ /* String a character literals */ 2736 }else if( c=='\'' || c=='\"' ){ /* String a character literals */
2616 int startchar, prevc; 2737 int startchar, prevc;
2617 startchar = c; 2738 startchar = c;
2618 prevc = 0; 2739 prevc = 0;
2619 for(cp++; (c= *cp)!=0 && (c!=startchar || prevc=='\\'); cp++){ 2740 for(cp++; (c= *cp)!=0 && (c!=startchar || prevc=='\\'); cp++){
2620 if( c=='\n' ) lineno++; 2741 if( c=='\n' ) lineno++;
2621 if( prevc=='\\' ) prevc = 0; 2742 if( prevc=='\\' ) prevc = 0;
2622 else prevc = c; 2743 else prevc = c;
2623 » } 2744 }
2624 » } 2745 }
2625 } 2746 }
2626 if( c==0 ){ 2747 if( c==0 ){
2627 ErrorMsg(ps.filename,ps.tokenlineno, 2748 ErrorMsg(ps.filename,ps.tokenlineno,
2628 "C code starting on this line is not terminated before the end of the file."); 2749 "C code starting on this line is not terminated before the end of the file.");
2629 ps.errorcnt++; 2750 ps.errorcnt++;
2630 nextcp = cp; 2751 nextcp = cp;
2631 }else{ 2752 }else{
2632 nextcp = cp+1; 2753 nextcp = cp+1;
2633 } 2754 }
2634 }else if( isalnum(c) ){ /* Identifiers */ 2755 }else if( isalnum(c) ){ /* Identifiers */
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2729 PRIVATE char *file_makename(struct lemon *lemp, const char *suffix) 2850 PRIVATE char *file_makename(struct lemon *lemp, const char *suffix)
2730 { 2851 {
2731 char *name; 2852 char *name;
2732 char *cp; 2853 char *cp;
2733 2854
2734 name = (char*)malloc( lemonStrlen(lemp->filename) + lemonStrlen(suffix) + 5 ); 2855 name = (char*)malloc( lemonStrlen(lemp->filename) + lemonStrlen(suffix) + 5 );
2735 if( name==0 ){ 2856 if( name==0 ){
2736 fprintf(stderr,"Can't allocate space for a filename.\n"); 2857 fprintf(stderr,"Can't allocate space for a filename.\n");
2737 exit(1); 2858 exit(1);
2738 } 2859 }
2739 strcpy(name,lemp->filename); 2860 lemon_strcpy(name,lemp->filename);
2740 cp = strrchr(name,'.'); 2861 cp = strrchr(name,'.');
2741 if( cp ) *cp = 0; 2862 if( cp ) *cp = 0;
2742 strcat(name,suffix); 2863 lemon_strcat(name,suffix);
2743 return name; 2864 return name;
2744 } 2865 }
2745 2866
2746 /* Open a file with a name based on the name of the input file, 2867 /* Open a file with a name based on the name of the input file,
2747 ** but with a different (specified) suffix, and return a pointer 2868 ** but with a different (specified) suffix, and return a pointer
2748 ** to the stream */ 2869 ** to the stream */
2749 PRIVATE FILE *file_open( 2870 PRIVATE FILE *file_open(
2750 struct lemon *lemp, 2871 struct lemon *lemp,
2751 const char *suffix, 2872 const char *suffix,
2752 const char *mode 2873 const char *mode
2753 ){ 2874 ){
2754 FILE *fp; 2875 FILE *fp;
2755 2876
2756 if( lemp->outname ) free(lemp->outname); 2877 if( lemp->outname ) free(lemp->outname);
2757 lemp->outname = file_makename(lemp, suffix); 2878 lemp->outname = file_makename(lemp, suffix);
2758 fp = fopen(lemp->outname,mode); 2879 fp = fopen(lemp->outname,mode);
2759 if( fp==0 && *mode=='w' ){ 2880 if( fp==0 && *mode=='w' ){
2760 fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname); 2881 fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname);
2761 lemp->errorcnt++; 2882 lemp->errorcnt++;
2762 return 0; 2883 return 0;
2763 } 2884 }
2764
2765 /* Add files we create to a list, so we can delete them if we fail. This
2766 ** is to keep makefiles from getting confused. We don't include .out files,
2767 ** though: this is debug information, and you don't want it deleted if there
2768 ** was an error you need to track down.
2769 */
2770 if(( *mode=='w' ) && (strcmp(suffix, ".out") != 0)){
2771 const char **ptr = (const char **)
2772 realloc(made_files, sizeof (const char **) * (made_files_count + 1));
2773 const char *fname = Strsafe(lemp->outname);
2774 if ((ptr == NULL) || (fname == NULL)) {
2775 free(ptr);
2776 memory_error();
2777 }
2778 made_files = ptr;
2779 made_files[made_files_count++] = fname;
2780 }
2781 return fp; 2885 return fp;
2782 } 2886 }
2783 2887
2784 /* Duplicate the input file without comments and without actions 2888 /* Duplicate the input file without comments and without actions
2785 ** on rules */ 2889 ** on rules */
2786 void Reprint(struct lemon *lemp) 2890 void Reprint(struct lemon *lemp)
2787 { 2891 {
2788 struct rule *rp; 2892 struct rule *rp;
2789 struct symbol *sp; 2893 struct symbol *sp;
2790 int i, j, maxlen, len, ncolumns, skip; 2894 int i, j, maxlen, len, ncolumns, skip;
(...skipping 15 matching lines...) Expand all
2806 printf(" %3d %-*.*s",j,maxlen,maxlen,sp->name); 2910 printf(" %3d %-*.*s",j,maxlen,maxlen,sp->name);
2807 } 2911 }
2808 printf("\n"); 2912 printf("\n");
2809 } 2913 }
2810 for(rp=lemp->rule; rp; rp=rp->next){ 2914 for(rp=lemp->rule; rp; rp=rp->next){
2811 printf("%s",rp->lhs->name); 2915 printf("%s",rp->lhs->name);
2812 /* if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */ 2916 /* if( rp->lhsalias ) printf("(%s)",rp->lhsalias); */
2813 printf(" ::="); 2917 printf(" ::=");
2814 for(i=0; i<rp->nrhs; i++){ 2918 for(i=0; i<rp->nrhs; i++){
2815 sp = rp->rhs[i]; 2919 sp = rp->rhs[i];
2816 printf(" %s", sp->name);
2817 if( sp->type==MULTITERMINAL ){ 2920 if( sp->type==MULTITERMINAL ){
2921 printf(" %s", sp->subsym[0]->name);
2818 for(j=1; j<sp->nsubsym; j++){ 2922 for(j=1; j<sp->nsubsym; j++){
2819 printf("|%s", sp->subsym[j]->name); 2923 printf("|%s", sp->subsym[j]->name);
2820 } 2924 }
2925 }else{
2926 printf(" %s", sp->name);
2821 } 2927 }
2822 /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */ 2928 /* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */
2823 } 2929 }
2824 printf("."); 2930 printf(".");
2825 if( rp->precsym ) printf(" [%s]",rp->precsym->name); 2931 if( rp->precsym ) printf(" [%s]",rp->precsym->name);
2826 /* if( rp->code ) printf("\n %s",rp->code); */ 2932 /* if( rp->code ) printf("\n %s",rp->code); */
2827 printf("\n"); 2933 printf("\n");
2828 } 2934 }
2829 } 2935 }
2830 2936
2831 void ConfigPrint(FILE *fp, struct config *cfp) 2937 void ConfigPrint(FILE *fp, struct config *cfp)
2832 { 2938 {
2833 struct rule *rp; 2939 struct rule *rp;
2834 struct symbol *sp; 2940 struct symbol *sp;
2835 int i, j; 2941 int i, j;
2836 rp = cfp->rp; 2942 rp = cfp->rp;
2837 fprintf(fp,"%s ::=",rp->lhs->name); 2943 fprintf(fp,"%s ::=",rp->lhs->name);
2838 for(i=0; i<=rp->nrhs; i++){ 2944 for(i=0; i<=rp->nrhs; i++){
2839 if( i==cfp->dot ) fprintf(fp," *"); 2945 if( i==cfp->dot ) fprintf(fp," *");
2840 if( i==rp->nrhs ) break; 2946 if( i==rp->nrhs ) break;
2841 sp = rp->rhs[i]; 2947 sp = rp->rhs[i];
2842 fprintf(fp," %s", sp->name);
2843 if( sp->type==MULTITERMINAL ){ 2948 if( sp->type==MULTITERMINAL ){
2949 fprintf(fp," %s", sp->subsym[0]->name);
2844 for(j=1; j<sp->nsubsym; j++){ 2950 for(j=1; j<sp->nsubsym; j++){
2845 fprintf(fp,"|%s",sp->subsym[j]->name); 2951 fprintf(fp,"|%s",sp->subsym[j]->name);
2846 } 2952 }
2953 }else{
2954 fprintf(fp," %s", sp->name);
2847 } 2955 }
2848 } 2956 }
2849 } 2957 }
2850 2958
2851 /* #define TEST */ 2959 /* #define TEST */
2852 #if 0 2960 #if 0
2853 /* Print a set */ 2961 /* Print a set */
2854 PRIVATE void SetPrint(out,set,lemp) 2962 PRIVATE void SetPrint(out,set,lemp)
2855 FILE *out; 2963 FILE *out;
2856 char *set; 2964 char *set;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2946 fp = file_open(lemp,".out","wb"); 3054 fp = file_open(lemp,".out","wb");
2947 if( fp==0 ) return; 3055 if( fp==0 ) return;
2948 for(i=0; i<lemp->nstate; i++){ 3056 for(i=0; i<lemp->nstate; i++){
2949 stp = lemp->sorted[i]; 3057 stp = lemp->sorted[i];
2950 fprintf(fp,"State %d:\n",stp->statenum); 3058 fprintf(fp,"State %d:\n",stp->statenum);
2951 if( lemp->basisflag ) cfp=stp->bp; 3059 if( lemp->basisflag ) cfp=stp->bp;
2952 else cfp=stp->cfp; 3060 else cfp=stp->cfp;
2953 while( cfp ){ 3061 while( cfp ){
2954 char buf[20]; 3062 char buf[20];
2955 if( cfp->dot==cfp->rp->nrhs ){ 3063 if( cfp->dot==cfp->rp->nrhs ){
2956 sprintf(buf,"(%d)",cfp->rp->index); 3064 lemon_sprintf(buf,"(%d)",cfp->rp->index);
2957 fprintf(fp," %5s ",buf); 3065 fprintf(fp," %5s ",buf);
2958 }else{ 3066 }else{
2959 fprintf(fp," "); 3067 fprintf(fp," ");
2960 } 3068 }
2961 ConfigPrint(fp,cfp); 3069 ConfigPrint(fp,cfp);
2962 fprintf(fp,"\n"); 3070 fprintf(fp,"\n");
2963 #if 0 3071 #if 0
2964 SetPrint(fp,cfp->fws,lemp); 3072 SetPrint(fp,cfp->fws,lemp);
2965 PlinkPrint(fp,cfp->fplp,"To "); 3073 PlinkPrint(fp,cfp->fplp,"To ");
2966 PlinkPrint(fp,cfp->bplp,"From"); 3074 PlinkPrint(fp,cfp->bplp,"From");
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3011 3119
3012 #ifdef __WIN32__ 3120 #ifdef __WIN32__
3013 cp = strrchr(argv0,'\\'); 3121 cp = strrchr(argv0,'\\');
3014 #else 3122 #else
3015 cp = strrchr(argv0,'/'); 3123 cp = strrchr(argv0,'/');
3016 #endif 3124 #endif
3017 if( cp ){ 3125 if( cp ){
3018 c = *cp; 3126 c = *cp;
3019 *cp = 0; 3127 *cp = 0;
3020 path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 ); 3128 path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 );
3021 if( path ) sprintf(path,"%s/%s",argv0,name); 3129 if( path ) lemon_sprintf(path,"%s/%s",argv0,name);
3022 *cp = c; 3130 *cp = c;
3023 }else{ 3131 }else{
3024 pathlist = getenv("PATH"); 3132 pathlist = getenv("PATH");
3025 if( pathlist==0 ) pathlist = ".:/bin:/usr/bin"; 3133 if( pathlist==0 ) pathlist = ".:/bin:/usr/bin";
3026 pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 ); 3134 pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 );
3027 path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 ); 3135 path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 );
3028 if( (pathbuf != 0) && (path!=0) ){ 3136 if( (pathbuf != 0) && (path!=0) ){
3029 pathbufptr = pathbuf; 3137 pathbufptr = pathbuf;
3030 strcpy(pathbuf, pathlist); 3138 lemon_strcpy(pathbuf, pathlist);
3031 while( *pathbuf ){ 3139 while( *pathbuf ){
3032 cp = strchr(pathbuf,':'); 3140 cp = strchr(pathbuf,':');
3033 if( cp==0 ) cp = &pathbuf[lemonStrlen(pathbuf)]; 3141 if( cp==0 ) cp = &pathbuf[lemonStrlen(pathbuf)];
3034 c = *cp; 3142 c = *cp;
3035 *cp = 0; 3143 *cp = 0;
3036 sprintf(path,"%s/%s",pathbuf,name); 3144 lemon_sprintf(path,"%s/%s",pathbuf,name);
3037 *cp = c; 3145 *cp = c;
3038 if( c==0 ) pathbuf[0] = 0; 3146 if( c==0 ) pathbuf[0] = 0;
3039 else pathbuf = &cp[1]; 3147 else pathbuf = &cp[1];
3040 if( access(path,modemask)==0 ) break; 3148 if( access(path,modemask)==0 ) break;
3041 } 3149 }
3042 free(pathbufptr); 3150 free(pathbufptr);
3043 } 3151 }
3044 } 3152 }
3045 return path; 3153 return path;
3046 } 3154 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3117 if( in==0 ){ 3225 if( in==0 ){
3118 fprintf(stderr,"Can't open the template file \"%s\".\n",user_templatename) ; 3226 fprintf(stderr,"Can't open the template file \"%s\".\n",user_templatename) ;
3119 lemp->errorcnt++; 3227 lemp->errorcnt++;
3120 return 0; 3228 return 0;
3121 } 3229 }
3122 return in; 3230 return in;
3123 } 3231 }
3124 3232
3125 cp = strrchr(lemp->filename,'.'); 3233 cp = strrchr(lemp->filename,'.');
3126 if( cp ){ 3234 if( cp ){
3127 sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename); 3235 lemon_sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename);
3128 }else{ 3236 }else{
3129 sprintf(buf,"%s.lt",lemp->filename); 3237 lemon_sprintf(buf,"%s.lt",lemp->filename);
3130 } 3238 }
3131 if( access(buf,004)==0 ){ 3239 if( access(buf,004)==0 ){
3132 tpltname = buf; 3240 tpltname = buf;
3133 }else if( access(templatename,004)==0 ){ 3241 }else if( access(templatename,004)==0 ){
3134 tpltname = templatename; 3242 tpltname = templatename;
3135 }else{ 3243 }else{
3136 tpltname = pathsearch(lemp->argv0,templatename,0); 3244 tpltname = pathsearch(lemp->argv0,templatename,0);
3137 } 3245 }
3138 if( tpltname==0 ){ 3246 if( tpltname==0 ){
3139 fprintf(stderr,"Can't find the parser driver template file \"%s\".\n", 3247 fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
3270 n = lemonStrlen(zText); 3378 n = lemonStrlen(zText);
3271 } 3379 }
3272 if( (int) (n+sizeof(zInt)*2+used) >= alloced ){ 3380 if( (int) (n+sizeof(zInt)*2+used) >= alloced ){
3273 alloced = n + sizeof(zInt)*2 + used + 200; 3381 alloced = n + sizeof(zInt)*2 + used + 200;
3274 z = (char *) realloc(z, alloced); 3382 z = (char *) realloc(z, alloced);
3275 } 3383 }
3276 if( z==0 ) return empty; 3384 if( z==0 ) return empty;
3277 while( n-- > 0 ){ 3385 while( n-- > 0 ){
3278 c = *(zText++); 3386 c = *(zText++);
3279 if( c=='%' && n>0 && zText[0]=='d' ){ 3387 if( c=='%' && n>0 && zText[0]=='d' ){
3280 sprintf(zInt, "%d", p1); 3388 lemon_sprintf(zInt, "%d", p1);
3281 p1 = p2; 3389 p1 = p2;
3282 strcpy(&z[used], zInt); 3390 lemon_strcpy(&z[used], zInt);
3283 used += lemonStrlen(&z[used]); 3391 used += lemonStrlen(&z[used]);
3284 zText++; 3392 zText++;
3285 n--; 3393 n--;
3286 }else{ 3394 }else{
3287 z[used++] = c; 3395 z[used++] = c;
3288 } 3396 }
3289 } 3397 }
3290 z[used] = 0; 3398 z[used] = 0;
3291 return z; 3399 return z;
3292 } 3400 }
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
3421 struct lemon *lemp, /* The main info structure for this parser */ 3529 struct lemon *lemp, /* The main info structure for this parser */
3422 int *plineno, /* Pointer to the line number */ 3530 int *plineno, /* Pointer to the line number */
3423 int mhflag /* True if generating makeheaders output */ 3531 int mhflag /* True if generating makeheaders output */
3424 ){ 3532 ){
3425 int lineno = *plineno; /* The line number of the output */ 3533 int lineno = *plineno; /* The line number of the output */
3426 char **types; /* A hash table of datatypes */ 3534 char **types; /* A hash table of datatypes */
3427 int arraysize; /* Size of the "types" array */ 3535 int arraysize; /* Size of the "types" array */
3428 int maxdtlength; /* Maximum length of any ".datatype" field. */ 3536 int maxdtlength; /* Maximum length of any ".datatype" field. */
3429 char *stddt; /* Standardized name for a datatype */ 3537 char *stddt; /* Standardized name for a datatype */
3430 int i,j; /* Loop counters */ 3538 int i,j; /* Loop counters */
3431 int hash; /* For hashing the name of a type */ 3539 unsigned hash; /* For hashing the name of a type */
3432 const char *name; /* Name of the parser */ 3540 const char *name; /* Name of the parser */
3433 3541
3434 /* Allocate and initialize types[] and allocate stddt[] */ 3542 /* Allocate and initialize types[] and allocate stddt[] */
3435 arraysize = lemp->nsymbol * 2; 3543 arraysize = lemp->nsymbol * 2;
3436 types = (char**)calloc( arraysize, sizeof(char*) ); 3544 types = (char**)calloc( arraysize, sizeof(char*) );
3545 if( types==0 ){
3546 fprintf(stderr,"Out of memory.\n");
3547 exit(1);
3548 }
3437 for(i=0; i<arraysize; i++) types[i] = 0; 3549 for(i=0; i<arraysize; i++) types[i] = 0;
3438 maxdtlength = 0; 3550 maxdtlength = 0;
3439 if( lemp->vartype ){ 3551 if( lemp->vartype ){
3440 maxdtlength = lemonStrlen(lemp->vartype); 3552 maxdtlength = lemonStrlen(lemp->vartype);
3441 } 3553 }
3442 for(i=0; i<lemp->nsymbol; i++){ 3554 for(i=0; i<lemp->nsymbol; i++){
3443 int len; 3555 int len;
3444 struct symbol *sp = lemp->symbols[i]; 3556 struct symbol *sp = lemp->symbols[i];
3445 if( sp->datatype==0 ) continue; 3557 if( sp->datatype==0 ) continue;
3446 len = lemonStrlen(sp->datatype); 3558 len = lemonStrlen(sp->datatype);
3447 if( len>maxdtlength ) maxdtlength = len; 3559 if( len>maxdtlength ) maxdtlength = len;
3448 } 3560 }
3449 stddt = (char*)malloc( maxdtlength*2 + 1 ); 3561 stddt = (char*)malloc( maxdtlength*2 + 1 );
3450 if( types==0 || stddt==0 ){ 3562 if( stddt==0 ){
3451 fprintf(stderr,"Out of memory.\n"); 3563 fprintf(stderr,"Out of memory.\n");
3452 exit(1); 3564 exit(1);
3453 } 3565 }
3454 3566
3455 /* Build a hash table of datatypes. The ".dtnum" field of each symbol 3567 /* Build a hash table of datatypes. The ".dtnum" field of each symbol
3456 ** is filled in with the hash index plus 1. A ".dtnum" value of 0 is 3568 ** is filled in with the hash index plus 1. A ".dtnum" value of 0 is
3457 ** used for terminal symbols. If there is no %default_type defined then 3569 ** used for terminal symbols. If there is no %default_type defined then
3458 ** 0 is also used as the .dtnum value for nonterminals which do not specify 3570 ** 0 is also used as the .dtnum value for nonterminals which do not specify
3459 ** a datatype using the %type directive. 3571 ** a datatype using the %type directive.
3460 */ 3572 */
(...skipping 23 matching lines...) Expand all
3484 for(j=0; stddt[j]; j++){ 3596 for(j=0; stddt[j]; j++){
3485 hash = hash*53 + stddt[j]; 3597 hash = hash*53 + stddt[j];
3486 } 3598 }
3487 hash = (hash & 0x7fffffff)%arraysize; 3599 hash = (hash & 0x7fffffff)%arraysize;
3488 while( types[hash] ){ 3600 while( types[hash] ){
3489 if( strcmp(types[hash],stddt)==0 ){ 3601 if( strcmp(types[hash],stddt)==0 ){
3490 sp->dtnum = hash + 1; 3602 sp->dtnum = hash + 1;
3491 break; 3603 break;
3492 } 3604 }
3493 hash++; 3605 hash++;
3494 if( hash>=arraysize ) hash = 0; 3606 if( hash>=(unsigned)arraysize ) hash = 0;
3495 } 3607 }
3496 if( types[hash]==0 ){ 3608 if( types[hash]==0 ){
3497 sp->dtnum = hash + 1; 3609 sp->dtnum = hash + 1;
3498 types[hash] = (char*)malloc( lemonStrlen(stddt)+1 ); 3610 types[hash] = (char*)malloc( lemonStrlen(stddt)+1 );
3499 if( types[hash]==0 ){ 3611 if( types[hash]==0 ){
3500 fprintf(stderr,"Out of memory.\n"); 3612 fprintf(stderr,"Out of memory.\n");
3501 exit(1); 3613 exit(1);
3502 } 3614 }
3503 strcpy(types[hash],stddt); 3615 lemon_strcpy(types[hash],stddt);
3504 } 3616 }
3505 } 3617 }
3506 3618
3507 /* Print out the definition of YYTOKENTYPE and YYMINORTYPE */ 3619 /* Print out the definition of YYTOKENTYPE and YYMINORTYPE */
3508 name = lemp->name ? lemp->name : "Parse"; 3620 name = lemp->name ? lemp->name : "Parse";
3509 lineno = *plineno; 3621 lineno = *plineno;
3510 if( mhflag ){ fprintf(out,"#if INTERFACE\n"); lineno++; } 3622 if( mhflag ){ fprintf(out,"#if INTERFACE\n"); lineno++; }
3511 fprintf(out,"#define %sTOKENTYPE %s\n",name, 3623 fprintf(out,"#define %sTOKENTYPE %s\n",name,
3512 lemp->tokentype?lemp->tokentype:"void*"); lineno++; 3624 lemp->tokentype?lemp->tokentype:"void*"); lineno++;
3513 if( mhflag ){ fprintf(out,"#endif\n"); lineno++; } 3625 if( mhflag ){ fprintf(out,"#endif\n"); lineno++; }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3579 } 3691 }
3580 3692
3581 /* 3693 /*
3582 ** Write text on "out" that describes the rule "rp". 3694 ** Write text on "out" that describes the rule "rp".
3583 */ 3695 */
3584 static void writeRuleText(FILE *out, struct rule *rp){ 3696 static void writeRuleText(FILE *out, struct rule *rp){
3585 int j; 3697 int j;
3586 fprintf(out,"%s ::=", rp->lhs->name); 3698 fprintf(out,"%s ::=", rp->lhs->name);
3587 for(j=0; j<rp->nrhs; j++){ 3699 for(j=0; j<rp->nrhs; j++){
3588 struct symbol *sp = rp->rhs[j]; 3700 struct symbol *sp = rp->rhs[j];
3589 fprintf(out," %s", sp->name); 3701 if( sp->type!=MULTITERMINAL ){
3590 if( sp->type==MULTITERMINAL ){ 3702 fprintf(out," %s", sp->name);
3703 }else{
3591 int k; 3704 int k;
3705 fprintf(out," %s", sp->subsym[0]->name);
3592 for(k=1; k<sp->nsubsym; k++){ 3706 for(k=1; k<sp->nsubsym; k++){
3593 fprintf(out,"|%s",sp->subsym[k]->name); 3707 fprintf(out,"|%s",sp->subsym[k]->name);
3594 } 3708 }
3595 } 3709 }
3596 } 3710 }
3597 } 3711 }
3598 3712
3599 3713
3600 /* Generate C source code for the parser */ 3714 /* Generate C source code for the parser */
3601 void ReportTable( 3715 void ReportTable(
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
3882 p->name, p->fallback->name); 3996 p->name, p->fallback->name);
3883 } 3997 }
3884 lineno++; 3998 lineno++;
3885 } 3999 }
3886 } 4000 }
3887 tplt_xfer(lemp->name, in, out, &lineno); 4001 tplt_xfer(lemp->name, in, out, &lineno);
3888 4002
3889 /* Generate a table containing the symbolic name of every symbol 4003 /* Generate a table containing the symbolic name of every symbol
3890 */ 4004 */
3891 for(i=0; i<lemp->nsymbol; i++){ 4005 for(i=0; i<lemp->nsymbol; i++){
3892 sprintf(line,"\"%s\",",lemp->symbols[i]->name); 4006 lemon_sprintf(line,"\"%s\",",lemp->symbols[i]->name);
3893 fprintf(out," %-15s",line); 4007 fprintf(out," %-15s",line);
3894 if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; } 4008 if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; }
3895 } 4009 }
3896 if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; } 4010 if( (i&3)!=0 ){ fprintf(out,"\n"); lineno++; }
3897 tplt_xfer(lemp->name,in,out,&lineno); 4011 tplt_xfer(lemp->name,in,out,&lineno);
3898 4012
3899 /* Generate a table containing a text string that describes every 4013 /* Generate a table containing a text string that describes every
3900 ** rule in the rule set of the grammar. This information is used 4014 ** rule in the rule set of the grammar. This information is used
3901 ** when tracing REDUCE actions. 4015 ** when tracing REDUCE actions.
3902 */ 4016 */
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4047 FILE *out, *in; 4161 FILE *out, *in;
4048 const char *prefix; 4162 const char *prefix;
4049 char line[LINESIZE]; 4163 char line[LINESIZE];
4050 char pattern[LINESIZE]; 4164 char pattern[LINESIZE];
4051 int i; 4165 int i;
4052 4166
4053 if( lemp->tokenprefix ) prefix = lemp->tokenprefix; 4167 if( lemp->tokenprefix ) prefix = lemp->tokenprefix;
4054 else prefix = ""; 4168 else prefix = "";
4055 in = file_open(lemp,".h","rb"); 4169 in = file_open(lemp,".h","rb");
4056 if( in ){ 4170 if( in ){
4171 int nextChar;
4057 for(i=1; i<lemp->nterminal && fgets(line,LINESIZE,in); i++){ 4172 for(i=1; i<lemp->nterminal && fgets(line,LINESIZE,in); i++){
4058 sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); 4173 lemon_sprintf(pattern,"#define %s%-30s %3d\n",
4174 prefix,lemp->symbols[i]->name,i);
4059 if( strcmp(line,pattern) ) break; 4175 if( strcmp(line,pattern) ) break;
4060 } 4176 }
4177 nextChar = fgetc(in);
4061 fclose(in); 4178 fclose(in);
4062 if( i==lemp->nterminal ){ 4179 if( i==lemp->nterminal && nextChar==EOF ){
4063 /* No change in the file. Don't rewrite it. */ 4180 /* No change in the file. Don't rewrite it. */
4064 return; 4181 return;
4065 } 4182 }
4066 } 4183 }
4067 out = file_open(lemp,".h","wb"); 4184 out = file_open(lemp,".h","wb");
4068 if( out ){ 4185 if( out ){
4069 for(i=1; i<lemp->nterminal; i++){ 4186 for(i=1; i<lemp->nterminal; i++){
4070 fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i); 4187 fprintf(out,"#define %s%-30s %3d\n",prefix,lemp->symbols[i]->name,i);
4071 } 4188 }
4072 fclose(out); 4189 fclose(out);
4073 } 4190 }
4074 return; 4191 return;
4075 } 4192 }
4076 4193
4077 /* Reduce the size of the action tables, if possible, by making use 4194 /* Reduce the size of the action tables, if possible, by making use
4078 ** of defaults. 4195 ** of defaults.
4079 ** 4196 **
4080 ** In this version, we take the most frequent REDUCE action and make 4197 ** In this version, we take the most frequent REDUCE action and make
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
4258 ** from a specification in the file 4375 ** from a specification in the file
4259 ** "table.q" 4376 ** "table.q"
4260 ** by the associative array code building program "aagen". 4377 ** by the associative array code building program "aagen".
4261 ** Do not edit this file! Instead, edit the specification 4378 ** Do not edit this file! Instead, edit the specification
4262 ** file, then rerun aagen. 4379 ** file, then rerun aagen.
4263 */ 4380 */
4264 /* 4381 /*
4265 ** Code for processing tables in the LEMON parser generator. 4382 ** Code for processing tables in the LEMON parser generator.
4266 */ 4383 */
4267 4384
4268 PRIVATE int strhash(const char *x) 4385 PRIVATE unsigned strhash(const char *x)
4269 { 4386 {
4270 int h = 0; 4387 unsigned h = 0;
4271 while( *x) h = h*13 + *(x++); 4388 while( *x ) h = h*13 + *(x++);
4272 return h; 4389 return h;
4273 } 4390 }
4274 4391
4275 /* Works like strdup, sort of. Save a string in malloced memory, but 4392 /* Works like strdup, sort of. Save a string in malloced memory, but
4276 ** keep strings in a table so that the same string is not in more 4393 ** keep strings in a table so that the same string is not in more
4277 ** than one place. 4394 ** than one place.
4278 */ 4395 */
4279 const char *Strsafe(const char *y) 4396 const char *Strsafe(const char *y)
4280 { 4397 {
4281 const char *z; 4398 const char *z;
4282 char *cpy; 4399 char *cpy;
4283 4400
4284 if( y==0 ) return 0; 4401 if( y==0 ) return 0;
4285 z = Strsafe_find(y); 4402 z = Strsafe_find(y);
4286 if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){ 4403 if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){
4287 strcpy(cpy,y); 4404 lemon_strcpy(cpy,y);
4288 z = cpy; 4405 z = cpy;
4289 Strsafe_insert(z); 4406 Strsafe_insert(z);
4290 } 4407 }
4291 MemoryCheck(z); 4408 MemoryCheck(z);
4292 return z; 4409 return z;
4293 } 4410 }
4294 4411
4295 /* There is one instance of the following structure for each 4412 /* There is one instance of the following structure for each
4296 ** associative array of type "x1". 4413 ** associative array of type "x1".
4297 */ 4414 */
(...skipping 18 matching lines...) Expand all
4316 /* There is only one instance of the array, which is the following */ 4433 /* There is only one instance of the array, which is the following */
4317 static struct s_x1 *x1a; 4434 static struct s_x1 *x1a;
4318 4435
4319 /* Allocate a new associative array */ 4436 /* Allocate a new associative array */
4320 void Strsafe_init(){ 4437 void Strsafe_init(){
4321 if( x1a ) return; 4438 if( x1a ) return;
4322 x1a = (struct s_x1*)malloc( sizeof(struct s_x1) ); 4439 x1a = (struct s_x1*)malloc( sizeof(struct s_x1) );
4323 if( x1a ){ 4440 if( x1a ){
4324 x1a->size = 1024; 4441 x1a->size = 1024;
4325 x1a->count = 0; 4442 x1a->count = 0;
4326 x1a->tbl = (x1node*)malloc( 4443 x1a->tbl = (x1node*)calloc(1024, sizeof(x1node) + sizeof(x1node*));
4327 (sizeof(x1node) + sizeof(x1node*))*1024 );
4328 if( x1a->tbl==0 ){ 4444 if( x1a->tbl==0 ){
4329 free(x1a); 4445 free(x1a);
4330 x1a = 0; 4446 x1a = 0;
4331 }else{ 4447 }else{
4332 int i; 4448 int i;
4333 x1a->ht = (x1node**)&(x1a->tbl[1024]); 4449 x1a->ht = (x1node**)&(x1a->tbl[1024]);
4334 for(i=0; i<1024; i++) x1a->ht[i] = 0; 4450 for(i=0; i<1024; i++) x1a->ht[i] = 0;
4335 } 4451 }
4336 } 4452 }
4337 } 4453 }
4338 /* Insert a new record into the array. Return TRUE if successful. 4454 /* Insert a new record into the array. Return TRUE if successful.
4339 ** Prior data with the same key is NOT overwritten */ 4455 ** Prior data with the same key is NOT overwritten */
4340 int Strsafe_insert(const char *data) 4456 int Strsafe_insert(const char *data)
4341 { 4457 {
4342 x1node *np; 4458 x1node *np;
4343 int h; 4459 unsigned h;
4344 int ph; 4460 unsigned ph;
4345 4461
4346 if( x1a==0 ) return 0; 4462 if( x1a==0 ) return 0;
4347 ph = strhash(data); 4463 ph = strhash(data);
4348 h = ph & (x1a->size-1); 4464 h = ph & (x1a->size-1);
4349 np = x1a->ht[h]; 4465 np = x1a->ht[h];
4350 while( np ){ 4466 while( np ){
4351 if( strcmp(np->data,data)==0 ){ 4467 if( strcmp(np->data,data)==0 ){
4352 /* An existing entry with the same key is found. */ 4468 /* An existing entry with the same key is found. */
4353 /* Fail because overwrite is not allows. */ 4469 /* Fail because overwrite is not allows. */
4354 return 0; 4470 return 0;
4355 } 4471 }
4356 np = np->next; 4472 np = np->next;
4357 } 4473 }
4358 if( x1a->count>=x1a->size ){ 4474 if( x1a->count>=x1a->size ){
4359 /* Need to make the hash table bigger */ 4475 /* Need to make the hash table bigger */
4360 int i,size; 4476 int i,size;
4361 struct s_x1 array; 4477 struct s_x1 array;
4362 array.size = size = x1a->size*2; 4478 array.size = size = x1a->size*2;
4363 array.count = x1a->count; 4479 array.count = x1a->count;
4364 array.tbl = (x1node*)malloc( 4480 array.tbl = (x1node*)calloc(size, sizeof(x1node) + sizeof(x1node*));
4365 (sizeof(x1node) + sizeof(x1node*))*size );
4366 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 4481 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
4367 array.ht = (x1node**)&(array.tbl[size]); 4482 array.ht = (x1node**)&(array.tbl[size]);
4368 for(i=0; i<size; i++) array.ht[i] = 0; 4483 for(i=0; i<size; i++) array.ht[i] = 0;
4369 for(i=0; i<x1a->count; i++){ 4484 for(i=0; i<x1a->count; i++){
4370 x1node *oldnp, *newnp; 4485 x1node *oldnp, *newnp;
4371 oldnp = &(x1a->tbl[i]); 4486 oldnp = &(x1a->tbl[i]);
4372 h = strhash(oldnp->data) & (size-1); 4487 h = strhash(oldnp->data) & (size-1);
4373 newnp = &(array.tbl[i]); 4488 newnp = &(array.tbl[i]);
4374 if( array.ht[h] ) array.ht[h]->from = &(newnp->next); 4489 if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
4375 newnp->next = array.ht[h]; 4490 newnp->next = array.ht[h];
(...skipping 12 matching lines...) Expand all
4388 np->next = x1a->ht[h]; 4503 np->next = x1a->ht[h];
4389 x1a->ht[h] = np; 4504 x1a->ht[h] = np;
4390 np->from = &(x1a->ht[h]); 4505 np->from = &(x1a->ht[h]);
4391 return 1; 4506 return 1;
4392 } 4507 }
4393 4508
4394 /* Return a pointer to data assigned to the given key. Return NULL 4509 /* Return a pointer to data assigned to the given key. Return NULL
4395 ** if no such key. */ 4510 ** if no such key. */
4396 const char *Strsafe_find(const char *key) 4511 const char *Strsafe_find(const char *key)
4397 { 4512 {
4398 int h; 4513 unsigned h;
4399 x1node *np; 4514 x1node *np;
4400 4515
4401 if( x1a==0 ) return 0; 4516 if( x1a==0 ) return 0;
4402 h = strhash(key) & (x1a->size-1); 4517 h = strhash(key) & (x1a->size-1);
4403 np = x1a->ht[h]; 4518 np = x1a->ht[h];
4404 while( np ){ 4519 while( np ){
4405 if( strcmp(np->data,key)==0 ) break; 4520 if( strcmp(np->data,key)==0 ) break;
4406 np = np->next; 4521 np = np->next;
4407 } 4522 }
4408 return np ? np->data : 0; 4523 return np ? np->data : 0;
(...skipping 21 matching lines...) Expand all
4430 sp->destructor = 0; 4545 sp->destructor = 0;
4431 sp->destLineno = 0; 4546 sp->destLineno = 0;
4432 sp->datatype = 0; 4547 sp->datatype = 0;
4433 sp->useCnt = 0; 4548 sp->useCnt = 0;
4434 Symbol_insert(sp,sp->name); 4549 Symbol_insert(sp,sp->name);
4435 } 4550 }
4436 sp->useCnt++; 4551 sp->useCnt++;
4437 return sp; 4552 return sp;
4438 } 4553 }
4439 4554
4440 /* Compare two symbols for working purposes 4555 /* Compare two symbols for sorting purposes. Return negative,
4556 ** zero, or positive if a is less then, equal to, or greater
4557 ** than b.
4441 ** 4558 **
4442 ** Symbols that begin with upper case letters (terminals or tokens) 4559 ** Symbols that begin with upper case letters (terminals or tokens)
4443 ** must sort before symbols that begin with lower case letters 4560 ** must sort before symbols that begin with lower case letters
4444 ** (non-terminals). Other than that, the order does not matter. 4561 ** (non-terminals). And MULTITERMINAL symbols (created using the
4562 ** %token_class directive) must sort at the very end. Other than
4563 ** that, the order does not matter.
4445 ** 4564 **
4446 ** We find experimentally that leaving the symbols in their original 4565 ** We find experimentally that leaving the symbols in their original
4447 ** order (the order they appeared in the grammar file) gives the 4566 ** order (the order they appeared in the grammar file) gives the
4448 ** smallest parser tables in SQLite. 4567 ** smallest parser tables in SQLite.
4449 */ 4568 */
4450 int Symbolcmpp(const void *_a, const void *_b) 4569 int Symbolcmpp(const void *_a, const void *_b)
4451 { 4570 {
4452 const struct symbol **a = (const struct symbol **) _a; 4571 const struct symbol *a = *(const struct symbol **) _a;
4453 const struct symbol **b = (const struct symbol **) _b; 4572 const struct symbol *b = *(const struct symbol **) _b;
4454 int i1 = (**a).index + 10000000*((**a).name[0]>'Z'); 4573 int i1 = a->type==MULTITERMINAL ? 3 : a->name[0]>'Z' ? 2 : 1;
4455 int i2 = (**b).index + 10000000*((**b).name[0]>'Z'); 4574 int i2 = b->type==MULTITERMINAL ? 3 : b->name[0]>'Z' ? 2 : 1;
4456 assert( i1!=i2 || strcmp((**a).name,(**b).name)==0 ); 4575 return i1==i2 ? a->index - b->index : i1 - i2;
4457 return i1-i2;
4458 } 4576 }
4459 4577
4460 /* There is one instance of the following structure for each 4578 /* There is one instance of the following structure for each
4461 ** associative array of type "x2". 4579 ** associative array of type "x2".
4462 */ 4580 */
4463 struct s_x2 { 4581 struct s_x2 {
4464 int size; /* The number of available slots. */ 4582 int size; /* The number of available slots. */
4465 /* Must be a power of 2 greater than or */ 4583 /* Must be a power of 2 greater than or */
4466 /* equal to 1 */ 4584 /* equal to 1 */
4467 int count; /* Number of currently slots filled */ 4585 int count; /* Number of currently slots filled */
(...skipping 14 matching lines...) Expand all
4482 /* There is only one instance of the array, which is the following */ 4600 /* There is only one instance of the array, which is the following */
4483 static struct s_x2 *x2a; 4601 static struct s_x2 *x2a;
4484 4602
4485 /* Allocate a new associative array */ 4603 /* Allocate a new associative array */
4486 void Symbol_init(){ 4604 void Symbol_init(){
4487 if( x2a ) return; 4605 if( x2a ) return;
4488 x2a = (struct s_x2*)malloc( sizeof(struct s_x2) ); 4606 x2a = (struct s_x2*)malloc( sizeof(struct s_x2) );
4489 if( x2a ){ 4607 if( x2a ){
4490 x2a->size = 128; 4608 x2a->size = 128;
4491 x2a->count = 0; 4609 x2a->count = 0;
4492 x2a->tbl = (x2node*)malloc( 4610 x2a->tbl = (x2node*)calloc(128, sizeof(x2node) + sizeof(x2node*));
4493 (sizeof(x2node) + sizeof(x2node*))*128 );
4494 if( x2a->tbl==0 ){ 4611 if( x2a->tbl==0 ){
4495 free(x2a); 4612 free(x2a);
4496 x2a = 0; 4613 x2a = 0;
4497 }else{ 4614 }else{
4498 int i; 4615 int i;
4499 x2a->ht = (x2node**)&(x2a->tbl[128]); 4616 x2a->ht = (x2node**)&(x2a->tbl[128]);
4500 for(i=0; i<128; i++) x2a->ht[i] = 0; 4617 for(i=0; i<128; i++) x2a->ht[i] = 0;
4501 } 4618 }
4502 } 4619 }
4503 } 4620 }
4504 /* Insert a new record into the array. Return TRUE if successful. 4621 /* Insert a new record into the array. Return TRUE if successful.
4505 ** Prior data with the same key is NOT overwritten */ 4622 ** Prior data with the same key is NOT overwritten */
4506 int Symbol_insert(struct symbol *data, const char *key) 4623 int Symbol_insert(struct symbol *data, const char *key)
4507 { 4624 {
4508 x2node *np; 4625 x2node *np;
4509 int h; 4626 unsigned h;
4510 int ph; 4627 unsigned ph;
4511 4628
4512 if( x2a==0 ) return 0; 4629 if( x2a==0 ) return 0;
4513 ph = strhash(key); 4630 ph = strhash(key);
4514 h = ph & (x2a->size-1); 4631 h = ph & (x2a->size-1);
4515 np = x2a->ht[h]; 4632 np = x2a->ht[h];
4516 while( np ){ 4633 while( np ){
4517 if( strcmp(np->key,key)==0 ){ 4634 if( strcmp(np->key,key)==0 ){
4518 /* An existing entry with the same key is found. */ 4635 /* An existing entry with the same key is found. */
4519 /* Fail because overwrite is not allows. */ 4636 /* Fail because overwrite is not allows. */
4520 return 0; 4637 return 0;
4521 } 4638 }
4522 np = np->next; 4639 np = np->next;
4523 } 4640 }
4524 if( x2a->count>=x2a->size ){ 4641 if( x2a->count>=x2a->size ){
4525 /* Need to make the hash table bigger */ 4642 /* Need to make the hash table bigger */
4526 int i,size; 4643 int i,size;
4527 struct s_x2 array; 4644 struct s_x2 array;
4528 array.size = size = x2a->size*2; 4645 array.size = size = x2a->size*2;
4529 array.count = x2a->count; 4646 array.count = x2a->count;
4530 array.tbl = (x2node*)malloc( 4647 array.tbl = (x2node*)calloc(size, sizeof(x2node) + sizeof(x2node*));
4531 (sizeof(x2node) + sizeof(x2node*))*size );
4532 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 4648 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
4533 array.ht = (x2node**)&(array.tbl[size]); 4649 array.ht = (x2node**)&(array.tbl[size]);
4534 for(i=0; i<size; i++) array.ht[i] = 0; 4650 for(i=0; i<size; i++) array.ht[i] = 0;
4535 for(i=0; i<x2a->count; i++){ 4651 for(i=0; i<x2a->count; i++){
4536 x2node *oldnp, *newnp; 4652 x2node *oldnp, *newnp;
4537 oldnp = &(x2a->tbl[i]); 4653 oldnp = &(x2a->tbl[i]);
4538 h = strhash(oldnp->key) & (size-1); 4654 h = strhash(oldnp->key) & (size-1);
4539 newnp = &(array.tbl[i]); 4655 newnp = &(array.tbl[i]);
4540 if( array.ht[h] ) array.ht[h]->from = &(newnp->next); 4656 if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
4541 newnp->next = array.ht[h]; 4657 newnp->next = array.ht[h];
(...skipping 14 matching lines...) Expand all
4556 np->next = x2a->ht[h]; 4672 np->next = x2a->ht[h];
4557 x2a->ht[h] = np; 4673 x2a->ht[h] = np;
4558 np->from = &(x2a->ht[h]); 4674 np->from = &(x2a->ht[h]);
4559 return 1; 4675 return 1;
4560 } 4676 }
4561 4677
4562 /* Return a pointer to data assigned to the given key. Return NULL 4678 /* Return a pointer to data assigned to the given key. Return NULL
4563 ** if no such key. */ 4679 ** if no such key. */
4564 struct symbol *Symbol_find(const char *key) 4680 struct symbol *Symbol_find(const char *key)
4565 { 4681 {
4566 int h; 4682 unsigned h;
4567 x2node *np; 4683 x2node *np;
4568 4684
4569 if( x2a==0 ) return 0; 4685 if( x2a==0 ) return 0;
4570 h = strhash(key) & (x2a->size-1); 4686 h = strhash(key) & (x2a->size-1);
4571 np = x2a->ht[h]; 4687 np = x2a->ht[h];
4572 while( np ){ 4688 while( np ){
4573 if( strcmp(np->key,key)==0 ) break; 4689 if( strcmp(np->key,key)==0 ) break;
4574 np = np->next; 4690 np = np->next;
4575 } 4691 }
4576 return np ? np->data : 0; 4692 return np ? np->data : 0;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4630 if( rc==0 ) rc = a->dot - b->dot; 4746 if( rc==0 ) rc = a->dot - b->dot;
4631 } 4747 }
4632 if( rc==0 ){ 4748 if( rc==0 ){
4633 if( a ) rc = 1; 4749 if( a ) rc = 1;
4634 if( b ) rc = -1; 4750 if( b ) rc = -1;
4635 } 4751 }
4636 return rc; 4752 return rc;
4637 } 4753 }
4638 4754
4639 /* Hash a state */ 4755 /* Hash a state */
4640 PRIVATE int statehash(struct config *a) 4756 PRIVATE unsigned statehash(struct config *a)
4641 { 4757 {
4642 int h=0; 4758 unsigned h=0;
4643 while( a ){ 4759 while( a ){
4644 h = h*571 + a->rp->index*37 + a->dot; 4760 h = h*571 + a->rp->index*37 + a->dot;
4645 a = a->bp; 4761 a = a->bp;
4646 } 4762 }
4647 return h; 4763 return h;
4648 } 4764 }
4649 4765
4650 /* Allocate a new state structure */ 4766 /* Allocate a new state structure */
4651 struct state *State_new() 4767 struct state *State_new()
4652 { 4768 {
(...skipping 28 matching lines...) Expand all
4681 /* There is only one instance of the array, which is the following */ 4797 /* There is only one instance of the array, which is the following */
4682 static struct s_x3 *x3a; 4798 static struct s_x3 *x3a;
4683 4799
4684 /* Allocate a new associative array */ 4800 /* Allocate a new associative array */
4685 void State_init(){ 4801 void State_init(){
4686 if( x3a ) return; 4802 if( x3a ) return;
4687 x3a = (struct s_x3*)malloc( sizeof(struct s_x3) ); 4803 x3a = (struct s_x3*)malloc( sizeof(struct s_x3) );
4688 if( x3a ){ 4804 if( x3a ){
4689 x3a->size = 128; 4805 x3a->size = 128;
4690 x3a->count = 0; 4806 x3a->count = 0;
4691 x3a->tbl = (x3node*)malloc( 4807 x3a->tbl = (x3node*)calloc(128, sizeof(x3node) + sizeof(x3node*));
4692 (sizeof(x3node) + sizeof(x3node*))*128 );
4693 if( x3a->tbl==0 ){ 4808 if( x3a->tbl==0 ){
4694 free(x3a); 4809 free(x3a);
4695 x3a = 0; 4810 x3a = 0;
4696 }else{ 4811 }else{
4697 int i; 4812 int i;
4698 x3a->ht = (x3node**)&(x3a->tbl[128]); 4813 x3a->ht = (x3node**)&(x3a->tbl[128]);
4699 for(i=0; i<128; i++) x3a->ht[i] = 0; 4814 for(i=0; i<128; i++) x3a->ht[i] = 0;
4700 } 4815 }
4701 } 4816 }
4702 } 4817 }
4703 /* Insert a new record into the array. Return TRUE if successful. 4818 /* Insert a new record into the array. Return TRUE if successful.
4704 ** Prior data with the same key is NOT overwritten */ 4819 ** Prior data with the same key is NOT overwritten */
4705 int State_insert(struct state *data, struct config *key) 4820 int State_insert(struct state *data, struct config *key)
4706 { 4821 {
4707 x3node *np; 4822 x3node *np;
4708 int h; 4823 unsigned h;
4709 int ph; 4824 unsigned ph;
4710 4825
4711 if( x3a==0 ) return 0; 4826 if( x3a==0 ) return 0;
4712 ph = statehash(key); 4827 ph = statehash(key);
4713 h = ph & (x3a->size-1); 4828 h = ph & (x3a->size-1);
4714 np = x3a->ht[h]; 4829 np = x3a->ht[h];
4715 while( np ){ 4830 while( np ){
4716 if( statecmp(np->key,key)==0 ){ 4831 if( statecmp(np->key,key)==0 ){
4717 /* An existing entry with the same key is found. */ 4832 /* An existing entry with the same key is found. */
4718 /* Fail because overwrite is not allows. */ 4833 /* Fail because overwrite is not allows. */
4719 return 0; 4834 return 0;
4720 } 4835 }
4721 np = np->next; 4836 np = np->next;
4722 } 4837 }
4723 if( x3a->count>=x3a->size ){ 4838 if( x3a->count>=x3a->size ){
4724 /* Need to make the hash table bigger */ 4839 /* Need to make the hash table bigger */
4725 int i,size; 4840 int i,size;
4726 struct s_x3 array; 4841 struct s_x3 array;
4727 array.size = size = x3a->size*2; 4842 array.size = size = x3a->size*2;
4728 array.count = x3a->count; 4843 array.count = x3a->count;
4729 array.tbl = (x3node*)malloc( 4844 array.tbl = (x3node*)calloc(size, sizeof(x3node) + sizeof(x3node*));
4730 (sizeof(x3node) + sizeof(x3node*))*size );
4731 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 4845 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
4732 array.ht = (x3node**)&(array.tbl[size]); 4846 array.ht = (x3node**)&(array.tbl[size]);
4733 for(i=0; i<size; i++) array.ht[i] = 0; 4847 for(i=0; i<size; i++) array.ht[i] = 0;
4734 for(i=0; i<x3a->count; i++){ 4848 for(i=0; i<x3a->count; i++){
4735 x3node *oldnp, *newnp; 4849 x3node *oldnp, *newnp;
4736 oldnp = &(x3a->tbl[i]); 4850 oldnp = &(x3a->tbl[i]);
4737 h = statehash(oldnp->key) & (size-1); 4851 h = statehash(oldnp->key) & (size-1);
4738 newnp = &(array.tbl[i]); 4852 newnp = &(array.tbl[i]);
4739 if( array.ht[h] ) array.ht[h]->from = &(newnp->next); 4853 if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
4740 newnp->next = array.ht[h]; 4854 newnp->next = array.ht[h];
(...skipping 14 matching lines...) Expand all
4755 np->next = x3a->ht[h]; 4869 np->next = x3a->ht[h];
4756 x3a->ht[h] = np; 4870 x3a->ht[h] = np;
4757 np->from = &(x3a->ht[h]); 4871 np->from = &(x3a->ht[h]);
4758 return 1; 4872 return 1;
4759 } 4873 }
4760 4874
4761 /* Return a pointer to data assigned to the given key. Return NULL 4875 /* Return a pointer to data assigned to the given key. Return NULL
4762 ** if no such key. */ 4876 ** if no such key. */
4763 struct state *State_find(struct config *key) 4877 struct state *State_find(struct config *key)
4764 { 4878 {
4765 int h; 4879 unsigned h;
4766 x3node *np; 4880 x3node *np;
4767 4881
4768 if( x3a==0 ) return 0; 4882 if( x3a==0 ) return 0;
4769 h = statehash(key) & (x3a->size-1); 4883 h = statehash(key) & (x3a->size-1);
4770 np = x3a->ht[h]; 4884 np = x3a->ht[h];
4771 while( np ){ 4885 while( np ){
4772 if( statecmp(np->key,key)==0 ) break; 4886 if( statecmp(np->key,key)==0 ) break;
4773 np = np->next; 4887 np = np->next;
4774 } 4888 }
4775 return np ? np->data : 0; 4889 return np ? np->data : 0;
4776 } 4890 }
4777 4891
4778 /* Return an array of pointers to all data in the table. 4892 /* Return an array of pointers to all data in the table.
4779 ** The array is obtained from malloc. Return NULL if memory allocation 4893 ** The array is obtained from malloc. Return NULL if memory allocation
4780 ** problems, or if the array is empty. */ 4894 ** problems, or if the array is empty. */
4781 struct state **State_arrayof() 4895 struct state **State_arrayof()
4782 { 4896 {
4783 struct state **array; 4897 struct state **array;
4784 int i,size; 4898 int i,size;
4785 if( x3a==0 ) return 0; 4899 if( x3a==0 ) return 0;
4786 size = x3a->count; 4900 size = x3a->count;
4787 array = (struct state **)malloc( sizeof(struct state *)*size ); 4901 array = (struct state **)calloc(size, sizeof(struct state *));
4788 if( array ){ 4902 if( array ){
4789 for(i=0; i<size; i++) array[i] = x3a->tbl[i].data; 4903 for(i=0; i<size; i++) array[i] = x3a->tbl[i].data;
4790 } 4904 }
4791 return array; 4905 return array;
4792 } 4906 }
4793 4907
4794 /* Hash a configuration */ 4908 /* Hash a configuration */
4795 PRIVATE int confighash(struct config *a) 4909 PRIVATE unsigned confighash(struct config *a)
4796 { 4910 {
4797 int h=0; 4911 unsigned h=0;
4798 h = h*571 + a->rp->index*37 + a->dot; 4912 h = h*571 + a->rp->index*37 + a->dot;
4799 return h; 4913 return h;
4800 } 4914 }
4801 4915
4802 /* There is one instance of the following structure for each 4916 /* There is one instance of the following structure for each
4803 ** associative array of type "x4". 4917 ** associative array of type "x4".
4804 */ 4918 */
4805 struct s_x4 { 4919 struct s_x4 {
4806 int size; /* The number of available slots. */ 4920 int size; /* The number of available slots. */
4807 /* Must be a power of 2 greater than or */ 4921 /* Must be a power of 2 greater than or */
(...skipping 15 matching lines...) Expand all
4823 /* There is only one instance of the array, which is the following */ 4937 /* There is only one instance of the array, which is the following */
4824 static struct s_x4 *x4a; 4938 static struct s_x4 *x4a;
4825 4939
4826 /* Allocate a new associative array */ 4940 /* Allocate a new associative array */
4827 void Configtable_init(){ 4941 void Configtable_init(){
4828 if( x4a ) return; 4942 if( x4a ) return;
4829 x4a = (struct s_x4*)malloc( sizeof(struct s_x4) ); 4943 x4a = (struct s_x4*)malloc( sizeof(struct s_x4) );
4830 if( x4a ){ 4944 if( x4a ){
4831 x4a->size = 64; 4945 x4a->size = 64;
4832 x4a->count = 0; 4946 x4a->count = 0;
4833 x4a->tbl = (x4node*)malloc( 4947 x4a->tbl = (x4node*)calloc(64, sizeof(x4node) + sizeof(x4node*));
4834 (sizeof(x4node) + sizeof(x4node*))*64 );
4835 if( x4a->tbl==0 ){ 4948 if( x4a->tbl==0 ){
4836 free(x4a); 4949 free(x4a);
4837 x4a = 0; 4950 x4a = 0;
4838 }else{ 4951 }else{
4839 int i; 4952 int i;
4840 x4a->ht = (x4node**)&(x4a->tbl[64]); 4953 x4a->ht = (x4node**)&(x4a->tbl[64]);
4841 for(i=0; i<64; i++) x4a->ht[i] = 0; 4954 for(i=0; i<64; i++) x4a->ht[i] = 0;
4842 } 4955 }
4843 } 4956 }
4844 } 4957 }
4845 /* Insert a new record into the array. Return TRUE if successful. 4958 /* Insert a new record into the array. Return TRUE if successful.
4846 ** Prior data with the same key is NOT overwritten */ 4959 ** Prior data with the same key is NOT overwritten */
4847 int Configtable_insert(struct config *data) 4960 int Configtable_insert(struct config *data)
4848 { 4961 {
4849 x4node *np; 4962 x4node *np;
4850 int h; 4963 unsigned h;
4851 int ph; 4964 unsigned ph;
4852 4965
4853 if( x4a==0 ) return 0; 4966 if( x4a==0 ) return 0;
4854 ph = confighash(data); 4967 ph = confighash(data);
4855 h = ph & (x4a->size-1); 4968 h = ph & (x4a->size-1);
4856 np = x4a->ht[h]; 4969 np = x4a->ht[h];
4857 while( np ){ 4970 while( np ){
4858 if( Configcmp((const char *) np->data,(const char *) data)==0 ){ 4971 if( Configcmp((const char *) np->data,(const char *) data)==0 ){
4859 /* An existing entry with the same key is found. */ 4972 /* An existing entry with the same key is found. */
4860 /* Fail because overwrite is not allows. */ 4973 /* Fail because overwrite is not allows. */
4861 return 0; 4974 return 0;
4862 } 4975 }
4863 np = np->next; 4976 np = np->next;
4864 } 4977 }
4865 if( x4a->count>=x4a->size ){ 4978 if( x4a->count>=x4a->size ){
4866 /* Need to make the hash table bigger */ 4979 /* Need to make the hash table bigger */
4867 int i,size; 4980 int i,size;
4868 struct s_x4 array; 4981 struct s_x4 array;
4869 array.size = size = x4a->size*2; 4982 array.size = size = x4a->size*2;
4870 array.count = x4a->count; 4983 array.count = x4a->count;
4871 array.tbl = (x4node*)malloc( 4984 array.tbl = (x4node*)calloc(size, sizeof(x4node) + sizeof(x4node*));
4872 (sizeof(x4node) + sizeof(x4node*))*size );
4873 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */ 4985 if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
4874 array.ht = (x4node**)&(array.tbl[size]); 4986 array.ht = (x4node**)&(array.tbl[size]);
4875 for(i=0; i<size; i++) array.ht[i] = 0; 4987 for(i=0; i<size; i++) array.ht[i] = 0;
4876 for(i=0; i<x4a->count; i++){ 4988 for(i=0; i<x4a->count; i++){
4877 x4node *oldnp, *newnp; 4989 x4node *oldnp, *newnp;
4878 oldnp = &(x4a->tbl[i]); 4990 oldnp = &(x4a->tbl[i]);
4879 h = confighash(oldnp->data) & (size-1); 4991 h = confighash(oldnp->data) & (size-1);
4880 newnp = &(array.tbl[i]); 4992 newnp = &(array.tbl[i]);
4881 if( array.ht[h] ) array.ht[h]->from = &(newnp->next); 4993 if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
4882 newnp->next = array.ht[h]; 4994 newnp->next = array.ht[h];
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
4919 ** as it is removed. ("f" may be null to avoid this step.) */ 5031 ** as it is removed. ("f" may be null to avoid this step.) */
4920 void Configtable_clear(int(*f)(struct config *)) 5032 void Configtable_clear(int(*f)(struct config *))
4921 { 5033 {
4922 int i; 5034 int i;
4923 if( x4a==0 || x4a->count==0 ) return; 5035 if( x4a==0 || x4a->count==0 ) return;
4924 if( f ) for(i=0; i<x4a->count; i++) (*f)(x4a->tbl[i].data); 5036 if( f ) for(i=0; i<x4a->count; i++) (*f)(x4a->tbl[i].data);
4925 for(i=0; i<x4a->size; i++) x4a->ht[i] = 0; 5037 for(i=0; i<x4a->size; i++) x4a->ht[i] = 0;
4926 x4a->count = 0; 5038 x4a->count = 0;
4927 return; 5039 return;
4928 } 5040 }
OLDNEW
« no previous file with comments | « third_party/sqlite/src/tool/getlock.c ('k') | third_party/sqlite/src/tool/logest.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698