Added facility for open character sets, eg [a-].
[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.7  1996-10-29 13:57:28  adam
8  * Include of zebrautl.h instead of alexutil.h.
9  *
10  * Revision 1.6  1996/01/08 09:09:21  adam
11  * Function dfa_parse got 'const' string argument.
12  * New functions to define char mappings made public.
13  *
14  * Revision 1.5  1995/09/04  12:33:27  adam
15  * Various cleanup. YAZ util used instead.
16  *
17  * Revision 1.4  1995/01/25  11:30:51  adam
18  * Simple error reporting when parsing regular expressions.
19  * Memory usage reduced.
20  *
21  * Revision 1.3  1995/01/24  16:00:22  adam
22  * Added -ansi to CFLAGS.
23  * Some changes to the dfa module.
24  *
25  * Revision 1.2  1994/09/26  16:30:57  adam
26  * Minor changes. imalloc uses xmalloc now.
27  *
28  * Revision 1.1  1994/09/26  10:16:56  adam
29  * First version of dfa module in alex. This version uses yacc to parse
30  * regular expressions. This should be hand-made instead.
31  *
32  */
33 #include <stdio.h>
34 #include <assert.h>
35
36 #include <stdlib.h>
37 #include <string.h>
38 #include <ctype.h>
39
40 #include <zebrautl.h>
41 #include <dfa.h>
42 #include "lexer.h"
43
44 #define MAXLINE 512
45
46 static FILE *inf;
47 static FILE *outf;
48 static const char *inf_name;
49 static int line_no;
50 static int err_no;
51
52 static void
53     prep        (char **s),
54     read_defs   (void),
55     read_rules  (struct DFA *dfap),
56     read_tail   (void);
57
58 static char
59     *read_line  (void);
60
61 static void prep (char **s)
62 {
63     static char expr_buf[MAXLINE+1];
64     char *dst = expr_buf;
65     const char *src = *s;
66     int c;
67
68     while ((c = *src++))
69         *dst++ = c;
70
71     *dst = '\0';
72     *s = expr_buf;
73 }
74
75 static char *read_line (void)
76 {
77     static char linebuf[MAXLINE+1];
78     ++line_no;
79     return fgets (linebuf, MAXLINE, inf);
80 }
81
82 static void read_defs (void)
83 {
84     const char *s;
85     while ((s=read_line()))
86     {
87         if (*s == '%' && s[1] == '%')
88             return;
89         else if (*s == '\0' || isspace (*s))
90             fputs (s, outf);
91     }
92     error ("missing rule section");
93 }
94
95 static void read_rules (struct DFA *dfa)
96 {
97     char *s;
98     const char *sc;
99     int i;
100     int no = 0;
101
102     fputs ("\n#ifndef YY_BREAK\n#define YY_BREAK break;\n#endif\n", outf);
103     fputs ("void lexact (int no)\n{\n", outf);
104     fputs (  "\tswitch (no)\n\t{\n", outf);
105     while ((s=read_line()))
106     {
107         if (*s == '%' && s[1] == '%')
108             break;
109         else if (*s == '\0' || isspace (*s))
110             /* copy rest of line to output */
111             fputs (s, outf);
112         else
113         { 
114             /* preprocess regular expression */
115             prep (&s);                   
116             /* now parse regular expression */
117             sc = s;
118             i = dfa_parse (dfa, &sc);
119             if (i)
120             {
121                 fprintf (stderr, "%s #%d: regular expression syntax error\n",
122                         inf_name, line_no);
123                 assert (0);
124                 err_no++;
125             }
126             else
127             {
128                 if (no)
129                     fputs ("\t\tYY_BREAK\n", outf);
130                 no++;
131                 fprintf (outf, "\tcase %d:\n#line %d\n\t\t", no, line_no);
132             }
133             while (*sc == '\t' || *sc == ' ')
134                 sc++;
135             fputs (sc, outf);
136         }
137     }
138     fputs ("\tYY_BREAK\n\t}\n}\n", outf);
139     if (!no)
140         error ("no regular expressions in rule section");
141 }
142
143 static void read_tail (void)
144 {
145     const char *s;
146     while ((s=read_line()))
147         fputs (s, outf);
148 }
149
150 int read_file (const char *s, struct DFA *dfa)
151 {
152     inf_name = s;
153     if (!(inf=fopen (s,"r")))
154     {
155         error ("cannot open `%s'", s);
156         return -1;
157     }
158
159     if (!(outf=fopen ("lex.yy.c", "w")))
160     {
161         error ("cannot open `%s'", "lex.yy.c");
162         return -2;
163     }
164
165     line_no = 0;
166     err_no = 0;
167
168     read_defs ();
169     read_rules (dfa);
170     read_tail ();
171
172     fclose (outf);
173     fclose (inf);
174     return err_no;
175 }