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