Added -ansi to CFLAGS.
[idzebra-moved-to-github.git] / dfa / readfile.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: readfile.c,v $
7  * Revision 1.3  1995-01-24 16:00:22  adam
8  * Added -ansi to CFLAGS.
9  * Some changes to the dfa module.
10  *
11  * Revision 1.2  1994/09/26  16:30:57  adam
12  * Minor changes. imalloc uses xmalloc now.
13  *
14  * Revision 1.1  1994/09/26  10:16:56  adam
15  * First version of dfa module in alex. This version uses yacc to parse
16  * regular expressions. This should be hand-made instead.
17  *
18  */
19 #include <stdio.h>
20 #include <assert.h>
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <ctype.h>
25
26 #include <util.h>
27 #include <dfa.h>
28 #include "lexer.h"
29
30 #define MAXLINE 512
31
32 static FILE *inf;
33 static FILE *outf;
34 static const char *inf_name;
35 static int line_no;
36 static int err_no;
37
38 static void
39     prep        (char **s),
40     read_defs   (void),
41     read_rules  (struct DFA *dfap),
42     read_tail   (void);
43
44 static char
45     *read_line  (void);
46
47 static void prep (char **s)
48 {
49     static char expr_buf[MAXLINE+1];
50     char *dst = expr_buf;
51     const char *src = *s;
52     int c;
53
54     while ((c = *src++))
55         *dst++ = c;
56
57     *dst = '\0';
58     *s = expr_buf;
59 }
60
61 static char *read_line (void)
62 {
63     static char linebuf[MAXLINE+1];
64     ++line_no;
65     return fgets (linebuf, MAXLINE, inf);
66 }
67
68 static void read_defs (void)
69 {
70     const char *s;
71     while ((s=read_line()))
72     {
73         if (*s == '%' && s[1] == '%')
74             return;
75         else if (*s == '\0' || isspace (*s))
76             fputs (s, outf);
77     }
78     error ("missing rule section");
79 }
80
81 static void read_rules (struct DFA *dfa)
82 {
83     char *s;
84     int i;
85     int no = 0;
86
87     fputs ("\n#ifndef YY_BREAK\n#define YY_BREAK break;\n#endif\n", outf);
88     fputs ("void lexact (int no)\n{\n", outf);
89     fputs (  "\tswitch (no)\n\t{\n", outf);
90     while ((s=read_line()))
91     {
92         if (*s == '%' && s[1] == '%')
93             break;
94         else if (*s == '\0' || isspace (*s))
95             /* copy rest of line to output */
96             fputs (s, outf);
97         else
98         { 
99             /* preprocess regular expression */
100             prep (&s);                   
101             /* now parse regular expression */
102             i = dfa_parse (dfa, &s);
103             if (i)
104             {
105                 fprintf (stderr, "%s #%d: regular expression syntax error\n",
106                         inf_name, line_no);
107                 err_no++;
108             }
109             else
110             {
111                 if (no)
112                     fputs ("\t\tYY_BREAK\n", outf);
113                 no++;
114                 fprintf (outf, "\tcase %d:\n#line %d\n\t\t", no, line_no);
115             }
116             while (*s == '\t' || *s == ' ')
117                 s++;
118             fputs (s, outf);
119         }
120     }
121     fputs ("\tYY_BREAK\n\t}\n}\n", outf);
122     if (!no)
123         error ("no regular expressions in rule section");
124 }
125
126 static void read_tail (void)
127 {
128     const char *s;
129     while ((s=read_line()))
130         fputs (s, outf);
131 }
132
133 int read_file (const char *s, struct DFA *dfa)
134 {
135     inf_name = s;
136     if (!(inf=fopen (s,"r")))
137     {
138         error ("cannot open `%s'", s);
139         return -1;
140     }
141
142     if (!(outf=fopen ("lex.yy.c", "w")))
143     {
144         error ("cannot open `%s'", "lex.yy.c");
145         return -2;
146     }
147
148     line_no = 0;
149     err_no = 0;
150
151     read_defs ();
152     read_rules (dfa);
153     read_tail ();
154
155     fclose (outf);
156     fclose (inf);
157     return err_no;
158 }