URI: 
       lex.l - enscript - GNU Enscript
  HTML git clone git://thinkerwim.org/enscript.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       lex.l (7736B)
       ---
            1 %{
            2 /*
            3  * Lexer for states.
            4  * Copyright (c) 1997-1998 Markku Rossi.
            5  *
            6  * Author: Markku Rossi <mtr@iki.fi>
            7  */
            8 
            9 /*
           10  * This file is part of GNU Enscript.
           11  *
           12  * Enscript is free software: you can redistribute it and/or modify
           13  * it under the terms of the GNU General Public License as published by
           14  * the Free Software Foundation, either version 3 of the License, or
           15  * (at your option) any later version.
           16  *
           17  * Enscript is distributed in the hope that it will be useful,
           18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
           19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
           20  * GNU General Public License for more details.
           21  *
           22  * You should have received a copy of the GNU General Public License
           23  * along with Enscript.  If not, see <http://www.gnu.org/licenses/>.
           24  */
           25 
           26 /*
           27  * $Id: lex.l,v 1.1.1.1 2003/03/05 07:25:52 mtr Exp $
           28  */
           29 
           30 #include "defs.h"
           31 #include "gram.h"
           32 
           33 static void eat_comment ();
           34 static char *read_string ___P ((unsigned int *len_return));
           35 static void read_regexp ___P ((Node *node));
           36 %}
           37 
           38 real        [+-]?[0-9]+\.[0-9]*|[+-]?\.[0-9]+
           39 integer        [+-]?[0-9]+
           40 symbol        [a-zA-Z_][a-zA-Z_0-9]*|\$.
           41 
           42 %%
           43 
           44 "/*"                 { eat_comment (); }
           45 [ \t\r\f]        { ; }
           46 \n                { linenum++; }
           47 
           48 \"                { yylval.node = node_alloc (nSTRING);
           49                   yylval.node->u.str.data
           50                     = read_string (&yylval.node->u.str.len);
           51                   return tSTRING;
           52                 }
           53 
           54 '[^\\]'         { yylval.node = node_alloc (nINTEGER);
           55                   yylval.node->u.integer = yytext[1];
           56                   return tINTEGER;
           57                 }
           58 
           59 '\\.'                { yylval.node = node_alloc (nINTEGER);
           60                   switch (yytext[2])
           61                     {
           62                     case 'n':
           63                       yylval.node->u.integer = '\n';
           64                       break;
           65 
           66                     case 't':
           67                       yylval.node->u.integer = '\t';
           68                       break;
           69 
           70                     case 'v':
           71                       yylval.node->u.integer = '\v';
           72                       break;
           73 
           74                     case 'b':
           75                       yylval.node->u.integer = '\b';
           76                       break;
           77 
           78                     case 'r':
           79                       yylval.node->u.integer = '\r';
           80                       break;
           81 
           82                     case 'f':
           83                       yylval.node->u.integer = '\f';
           84                       break;
           85 
           86                     case 'a':
           87                       yylval.node->u.integer = '\a';
           88                       break;
           89 
           90                     default:
           91                       yylval.node->u.integer = yytext[2];
           92                       break;
           93                     }
           94 
           95                   return tINTEGER;
           96                 }
           97 
           98 \/                { yylval.node = node_alloc (nREGEXP);
           99                   read_regexp (yylval.node);
          100                   return tREGEXP;
          101                 }
          102 
          103 "BEGIN"         { return tBEGIN; }
          104 "END"                 { return tEND; }
          105 "div"                 { return tDIV; }
          106 "else"                 { return tELSE; }
          107 "extends"        { return tEXTENDS; }
          108 "for"                 { return tFOR; }
          109 "if"                 { return tIF; }
          110 "local"                { return tLOCAL; }
          111 "namerules"         { return tNAMERULES; }
          112 "return"        { return tRETURN; }
          113 "start"         { return tSTART; }
          114 "startrules"         { return tSTARTRULES; }
          115 "state"         { return tSTATE; }
          116 "sub"                 { return tSUB; }
          117 "while"                { return tWHILE; }
          118 
          119 "=="                 { return tEQ; }
          120 "!="                 { return tNE; }
          121 "<="                 { return tLE; }
          122 ">="                 { return tGE; }
          123 "&&"                 { return tAND; }
          124 "||"                 { return tOR; }
          125 "++"                 { return tPLUSPLUS; }
          126 "--"                 { return tMINUSMINUS; }
          127 "+="                { return tADDASSIGN; }
          128 "-="                { return tSUBASSIGN; }
          129 "*="                { return tMULASSIGN; }
          130 "div="                { return tDIVASSIGN; }
          131 
          132 {real}                 { yylval.node = node_alloc (nREAL);
          133                   yylval.node->u.real = atof (yytext);
          134                   return tREAL;
          135                 }
          136 {integer}        { yylval.node = node_alloc (nINTEGER);
          137                   yylval.node->u.integer = atoi (yytext);
          138                   return tINTEGER;
          139                 }
          140 {symbol}        { yylval.node = node_alloc (nSYMBOL);
          141                   yylval.node->u.sym = xstrdup (yytext);
          142                   return tSYMBOL;
          143                 }
          144 
          145 .                { return yytext[0]; }
          146 
          147 %%
          148 
          149 static void
          150 eat_comment ()
          151 {
          152   int c;
          153 
          154   while ((c = input ()) != EOF)
          155     {
          156       if (c == '\n')
          157         linenum++;
          158       else if (c == '*')
          159         {
          160           c = input ();
          161           if (c == '/')
          162             /* All done. */
          163             return;
          164 
          165           if (c == EOF)
          166             {
          167               yyerror (_("error: EOF in comment"));
          168               break;
          169             }
          170           unput (c);
          171         }
          172     }
          173   yyerror (_("error: EOF in comment"));
          174 }
          175 
          176 
          177 int
          178 yywrap ()
          179 {
          180   return 1;
          181 }
          182 
          183 static char *
          184 read_string (len_return)
          185      unsigned int *len_return;
          186 {
          187   char *buf = NULL;
          188   char *buf2;
          189   int buflen = 0;
          190   int bufpos = 0;
          191   int ch;
          192   int done = 0;
          193 
          194   while (!done)
          195     {
          196       ch = input ();
          197       if (ch == '\n')
          198         linenum++;
          199 
          200       switch (ch)
          201         {
          202         case EOF:
          203         unexpected_eof:
          204           yyerror (_("error: EOF in string constant"));
          205           done = 1;
          206           break;
          207 
          208         case '"':
          209           done = 1;
          210           break;
          211 
          212         case '\\':
          213           ch = input ();
          214           switch (ch)
          215             {
          216             case 'n':
          217               ch = '\n';
          218               break;
          219 
          220             case 't':
          221               ch = '\t';
          222               break;
          223 
          224             case 'v':
          225               ch = '\v';
          226               break;
          227 
          228             case 'b':
          229               ch = '\b';
          230               break;
          231 
          232             case 'r':
          233               ch = '\r';
          234               break;
          235 
          236             case 'f':
          237               ch = '\f';
          238               break;
          239 
          240             case 'a':
          241               ch = '\a';
          242               break;
          243 
          244             case EOF:
          245               goto unexpected_eof;
          246               break;
          247 
          248             default:
          249               if (ch == '0')
          250                 {
          251                   int i;
          252                   int val = 0;
          253 
          254                   for (i = 0; i < 3; i++)
          255                     {
          256                       ch = input ();
          257                       if ('0' <= ch && ch <= '7')
          258                         val = val * 8 + ch - '0';
          259                       else
          260                         {
          261                           unput (ch);
          262                           break;
          263                         }
          264                     }
          265                   ch = val;
          266                 }
          267               break;
          268             }
          269           /* FALLTHROUGH */
          270 
          271         default:
          272           if (bufpos >= buflen)
          273             {
          274               buflen += 1024;
          275               buf = (char *) xrealloc (buf, buflen);
          276             }
          277           buf[bufpos++] = ch;
          278           break;
          279         }
          280     }
          281 
          282   buf2 = (char *) xmalloc (bufpos + 1);
          283   memcpy (buf2, buf, bufpos);
          284   buf2[bufpos] = '\0';
          285   xfree (buf);
          286 
          287   *len_return = bufpos;
          288 
          289   return buf2;
          290 }
          291 
          292 
          293 static void
          294 read_regexp (node)
          295      Node *node;
          296 {
          297   char *buf = NULL;
          298   char *buf2;
          299   int buflen = 0;
          300   int bufpos = 0;
          301   int ch;
          302   int done = 0;
          303 
          304   while (!done)
          305     {
          306       ch = input ();
          307       switch (ch)
          308         {
          309         case EOF:
          310         unexpected_eof:
          311           yyerror (_("error: EOF in regular expression"));
          312           done = 1;
          313           break;
          314 
          315         case '/':
          316           done = 1;
          317           break;
          318 
          319         case '\\':
          320           ch = input ();
          321           switch (ch)
          322             {
          323             case '\n':
          324               /* Line break. */
          325               linenum++;
          326               continue;
          327               break;
          328 
          329             case 'n':
          330               ch = '\n';
          331               break;
          332 
          333             case 'r':
          334               ch = '\r';
          335               break;
          336 
          337             case 'f':
          338               ch = '\f';
          339               break;
          340 
          341             case 't':
          342               ch = '\t';
          343               break;
          344 
          345             case '/':
          346             case '\\':
          347               /* Quote these. */
          348               break;
          349 
          350             case EOF:
          351               goto unexpected_eof;
          352               break;
          353 
          354             default:
          355               if (ch == '0')
          356                 {
          357                   int i;
          358                   int val = 0;
          359 
          360                   for (i = 0; i < 3; i++)
          361                     {
          362                       ch = input ();
          363                       if ('0' <= ch && ch <= '7')
          364                         val = val * 8 + ch - '0';
          365                       else
          366                         {
          367                           unput (ch);
          368                           break;
          369                         }
          370                     }
          371                   ch = val;
          372                 }
          373               else
          374                 {
          375                   /* Pass it through. */
          376                   unput (ch);
          377                   ch = '\\';
          378                 }
          379               break;
          380             }
          381           /* FALLTHROUGH */
          382 
          383         default:
          384           if (bufpos >= buflen)
          385             {
          386               buflen += 1024;
          387               buf = (char *) xrealloc (buf, buflen);
          388             }
          389           buf[bufpos++] = ch;
          390           break;
          391         }
          392     }
          393 
          394   /* Possible options. */
          395   done = 0;
          396   while (!done)
          397     {
          398       ch = input ();
          399       switch (ch)
          400         {
          401         case 'i':
          402           /* Case-insensitive regular expression. */
          403           node->u.re.flags |= fRE_CASE_INSENSITIVE;
          404           break;
          405 
          406         default:
          407           /* Unknown option => this belongs to the next token. */
          408           unput (ch);
          409           done = 1;
          410           break;
          411         }
          412     }
          413 
          414   buf2 = (char *) xmalloc (bufpos + 1);
          415   memcpy (buf2, buf, bufpos);
          416   buf2[bufpos] = '\0';
          417   xfree (buf);
          418 
          419   node->u.re.data = buf2;
          420   node->u.re.len = bufpos;
          421 }
          422 
          423 
          424 /*
          425 Local variables:
          426 mode: c
          427 End:
          428 */