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