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