source: trunk/third/enscript/states/lex.l @ 17620

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