diff --git a/ldefs.h b/ldefs.h index 408fe15..6987c31 100644 --- a/ldefs.h +++ b/ldefs.h @@ -155,6 +155,7 @@ extern lchar yycgidtbl[]; extern int yycgid(wchar_t); extern Boolean handleeuc; /* TRUE iff -w or -e option is specified. */ extern Boolean widecio; /* TRUE iff -w option is specified. */ +extern Boolean caseless; /* TRUE iff -i option is specified. */ #define DEFSECTION 1 #define RULESECTION 2 diff --git a/lex.1 b/lex.1 index 5e041c5..23d6857 100644 --- a/lex.1 +++ b/lex.1 @@ -89,6 +89,10 @@ Generates output that can handle multibyte characters, with \fIyytext[]\fR being of type \fIunsigned char[]\fR. This option is an extension. .TP +.B \-i +Generates a case insensitive scanner (%option case-insensitive)\fR. +This option is an extension. +.TP .B \-n Opposite of .BR \-v ; diff --git a/main.c b/main.c index 4557c57..c6caabc 100644 --- a/main.c +++ b/main.c @@ -88,16 +88,17 @@ main(int argc, char **argv) int c; Boolean eoption = 0, woption = 0; const char *driver = 0; + const char *fnout = "yy.lex.c"; sargv = argv; sargc = argc; errorf = stderr; setlocale(LC_CTYPE, ""); + while ((c = getopt(argc, argv, #ifdef DEBUG - while ((c = getopt(argc, argv, "dyctvnewVQ:o:")) != EOF) { -#else - while ((c = getopt(argc, argv, "ctvnewVQ:o:")) != EOF) { + "dy" #endif + "ctvneiwVQ:o:")) != EOF) { switch (c) { #ifdef DEBUG case 'd': @@ -149,9 +150,12 @@ main(int argc, char **argv) handleeuc = 1; widecio = 0; break; + case 'i': + caseless = TRUE; + break; default: fprintf(stderr, - "Usage: lex [-ewctvnV] [-o outfile] [-Q(y/n)] [file]\n"); + "Usage: lex [-eiwctvnV] [-o outfile] [-Q(y/n)] [file]\n"); exit(1); } } @@ -172,6 +176,13 @@ main(int argc, char **argv) } } else fin = stdin; + if(!fout) { + fout = fopen(fnout, "w"); + if (!fout) + error( + "lex: could not open %s for writing", + fnout); + } /* may be gotten: def, subs, sname, schar, ccl, dchar */ gch(); diff --git a/ncform b/ncform index a6d8f02..518201e 100644 --- a/ncform +++ b/ncform @@ -51,6 +51,11 @@ yylook() register struct yywork *yyt; struct yysvf *yyz; int yych, yyfirst; +#ifdef LEXCASELESS + int yychnc; +#else +#define yychnc yych +#endif struct yywork *yyr; # ifdef LEXDEBUG int debug; @@ -120,8 +125,11 @@ yylook() } # endif yyr = yyt; +#ifdef LEXCASELESS + yychnc = tolower(yych); +#endif if ( yyt > yycrank){ - yyt = yyr + yych; + yyt = yyr + yychnc; if (yyt <= yytop && yyt->verify+yysvec == yystate){ if(yyt->advance+yysvec == YYLERR) /* error transitions */ {unput(*--yylastch);break;} @@ -139,7 +147,7 @@ yylook() # ifdef LEXDEBUG if(debug)fprintf(yyout,"compressed state\n"); # endif - yyt = yyt + yych; + yyt = yyt + yychnc; if(yyt <= yytop && yyt->verify+yysvec == yystate){ if(yyt->advance+yysvec == YYLERR) /* error transitions */ {unput(*--yylastch);break;} @@ -150,11 +158,11 @@ yylook() } goto contin; } - yyt = yyr + YYU(yymatch[yych]); + yyt = yyr + YYU(yymatch[yychnc]); # ifdef LEXDEBUG if(debug){ fprintf(yyout,"try fall back character "); - allprint(YYU(yymatch[yych])); + allprint(YYU(yymatch[yychnc])); putchar('\n'); } # endif diff --git a/once.h b/once.h index 44470f5..1c2ebc7 100644 --- a/once.h +++ b/once.h @@ -158,6 +158,7 @@ CHR *psave; Boolean handleeuc = FALSE; Boolean widecio = FALSE; +Boolean caseless = FALSE; int isArray = 1; /* XCU4: for %array %pointer */ diff --git a/parser.y b/parser.y index 893784a..c597cb7 100644 --- a/parser.y +++ b/parser.y @@ -132,7 +132,7 @@ defns: defns STR STR error("Too many definitions"); dp += slength($3.cp) + 1; if(dp >= dchar+DEFCHAR) - error("Definitions too long"); + error("Definitions too long (%d)", DEFCHAR); subs[dptr]=def[dptr]=0; /* for lookup - require ending null */ } | @@ -316,13 +316,19 @@ static int wcwordtos(CHR *ws, char *buf, size_t buflen) { static void flex_noyywrap(void) { fprintf(fout, "# define yywrap() 1\n"); } +static void flex_caseless(void) { + fprintf(fout, "# define LEXCASELESS 1\n"); + fprintf(fout, "#include \n"); + caseless = TRUE; +} static void parse_flex_opts(CHR *p) { static const struct { - const char name[9]; + const char *name; void(*action)(void); } flex_opts[] = { { "noyywrap", flex_noyywrap}, - { {0}, 0 } + { "case-insensitive", flex_caseless}, + { 0, 0 } }; while(1) { char buf[60+MB_LEN_MAX]; @@ -795,6 +801,7 @@ start: if(prev != '\n') /* not at line begin, not start */ goto character; t = slptr; + x = 0; do { i = 0; if(!isascii(c = gch())) @@ -857,7 +864,7 @@ start: while((c=gch()) && c != '"' && c != '\n'){ if(c == '\\') c = usescape(c=gch()); remch(c); - token[i++] = c; + token[i++] = caseless ? tolower(c) : c; if(i >= TOKENSIZE){ warning("String too long"); i = TOKENSIZE-1; @@ -923,8 +930,8 @@ Character range specified between different codesets."); ('0'<=j && k<='9'))) warning("Non-portable Character Class"); token[i++] = RANGE; - token[i++] = j; - token[i++] = k; + token[i++] = caseless ? tolower(j) : j; + token[i++] = caseless ? tolower(k) : k; light = FALSE; } else { error("unmatched hyphen"); @@ -935,7 +942,7 @@ Character range specified between different codesets."); } else { j = c; remch(c); - token[i++] = c; /* Remember whatever.*/ + token[i++] = caseless ? tolower(c) : c; /* Remember whatever.*/ light = TRUE; ESCAPE = FALSE; } @@ -969,9 +976,10 @@ Character range specified between different codesets."); if(alpha(peek)){ i = 0; yylval.cp = (CHR *)token; - token[i++] = c; + token[i++] = caseless ? tolower(c) : c; while(alpha(peek)) { - remch(token[i++] = gch()); + c = gch(); + remch(token[i++] = caseless ? tolower(c) : c); if(i >= TOKENSIZE) { warning("string too long"); i = TOKENSIZE - 1; diff --git a/sub1.c b/sub1.c index d0e9633..71920d4 100644 --- a/sub1.c +++ b/sub1.c @@ -674,14 +674,11 @@ gch(void) int mn2(int a, intptr_t d, intptr_t c) { - if (tptr >= treesize) { + if (tptr >= treesize || d >= treesize || c >= treesize) { tptr++; - error("Parse tree too big %s", + error("Parse tree too big (%d) %s", treesize, (treesize == TREESIZE ? "\nTry using %e num" : "")); } - if (d >= treesize) { - error("Parse error"); - } name[tptr] = a; left[tptr] = d; right[tptr] = c; @@ -723,7 +720,7 @@ mn1(int a, intptr_t d) { if (tptr >= treesize) { tptr++; - error("Parse tree too big %s", + error("Parse tree too big (%d) %s", treesize, (treesize == TREESIZE ? "\nTry using %e num" : "")); } name[tptr] = a; @@ -766,7 +763,7 @@ mn0(int a) { if (tptr >= treesize) { tptr++; - error("Parse tree too big %s", + error("Parse tree too big (%d) %s", treesize, (treesize == TREESIZE ? "\nTry using %e num" : "")); } diff --git a/sub2.c b/sub2.c index 6a14764..0ae25a3 100644 --- a/sub2.c +++ b/sub2.c @@ -93,7 +93,8 @@ cfoll(int v) *pcptr++ = 0; if (pcptr > pchar + pchlen) error( - "Too many packed character classes"); + "Too many packed character classes (%d)", + pchlen); left[v] = (intptr_t)p; name[v] = RCCL; /* RNCCL eliminated */ #ifdef DEBUG @@ -167,7 +168,7 @@ add(int **array, int n) nxtpos = temp; if (nxtpos >= positions+maxpos) error( - "Too many positions %s", + "Too many positions (%d) %s", maxpos, (maxpos == MAXPOS ? "\nTry using %p num" : "")); } @@ -426,8 +427,8 @@ cgoto(void) else if (xstate == -1) { if (stnum+1 >= nstates) { stnum++; - error("Too many states %s", - (nstates == NSTATES ? + error("Too many states (%d) %s", + nstates, (nstates == NSTATES ? "\nTry using %n num":"")); } add(state, ++stnum); @@ -698,6 +699,8 @@ packtrans(int st, CHR *tch, int *tst, int cnt, int tryit) #endif nopack: /* stick it in */ + if((nptr+cnt) > ntrans) + goto errntrans; gotof[st] = nptr; nexts[nptr] = cnt; for (i = 0; i < cnt; i++) { @@ -712,10 +715,12 @@ packtrans(int st, CHR *tch, int *tst, int cnt, int tryit) gotof[st] = -1; nptr--; } else - if (nptr > ntrans) + if (nptr > ntrans) { +errntrans: error( - "Too many transitions %s", + "Too many transitions (%d) %s", ntrans, (ntrans == NTRANS ? "\nTry using %a num" : "")); + } } #ifdef DEBUG @@ -968,7 +973,7 @@ layout(void) do { startup += 1; if (startup > outsize - ZCH) - error("output table overflow"); + error("output table overflow (%d)", outsize); for (j = bot; j <= top; j++) { k = startup+ctable[nchar[j]]; if (verify[k]) @@ -995,7 +1000,7 @@ layout(void) do { startup += 1; if (startup > outsize - ZCH) - error("output table overflow"); + error("output table overflow (%d)", outsize); for (j = bot; j <= top; j++) { k = startup + nchar[j]; if (verify[k]) @@ -1070,12 +1075,12 @@ layout(void) else fprintf(fout, "0"); #ifdef DEBUG - fprintf(fout, " },\t\t/* state %d */", i); + fprintf(fout, " },\n\t/* state %d */", i); #endif - fprintf(fout, " },\t\t/* state %d */", i); + fprintf(fout, " },\n\t/* state %d */", i); } fprintf(fout, - "{ 0,\t0,\t0}};\n" + "{ 0,\t0,\t0}\n};\n" /* put out yymatch */