Minor changes.
[egate.git] / fml / fmltoken.c
1 /*
2  * Copyright (c) 1995, the EUROPAGATE consortium (see below).
3  *
4  * The EUROPAGATE consortium members are:
5  *
6  *    University College Dublin
7  *    Danmarks Teknologiske Videnscenter
8  *    An Chomhairle Leabharlanna
9  *    Consejo Superior de Investigaciones Cientificas
10  *
11  * Permission to use, copy, modify, distribute, and sell this software and
12  * its documentation, in whole or in part, for any purpose, is hereby granted,
13  * provided that:
14  *
15  * 1. This copyright and permission notice appear in all copies of the
16  * software and its documentation. Notices of copyright or attribution
17  * which appear at the beginning of any file must remain unchanged.
18  *
19  * 2. The names of EUROPAGATE or the project partners may not be used to
20  * endorse or promote products derived from this software without specific
21  * prior written permission.
22  *
23  * 3. Users of this software (implementors and gateway operators) agree to
24  * inform the EUROPAGATE consortium of their use of the software. This
25  * information will be used to evaluate the EUROPAGATE project and the
26  * software, and to plan further developments. The consortium may use
27  * the information in later publications.
28  * 
29  * 4. Users of this software agree to make their best efforts, when
30  * documenting their use of the software, to acknowledge the EUROPAGATE
31  * consortium, and the role played by the software in their work.
32  *
33  * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
34  * EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
35  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
36  * IN NO EVENT SHALL THE EUROPAGATE CONSORTIUM OR ITS MEMBERS BE LIABLE
37  * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF
38  * ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
39  * OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND
40  * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
41  * USE OR PERFORMANCE OF THIS SOFTWARE.
42  *
43  */
44 /*
45  * FML interpreter. Europagate, 1995
46  *
47  * $Log: fmltoken.c,v $
48  * Revision 1.7  1995/05/16 09:39:35  adam
49  * LICENSE.
50  *
51  * Revision 1.6  1995/02/23  08:32:07  adam
52  * Changed header.
53  *
54  * Revision 1.4  1995/02/10  18:15:53  adam
55  * FML function 'strcmp' implemented. This function can be used to
56  * test for existence of MARC fields.
57  *
58  * Revision 1.3  1995/02/10  15:50:57  adam
59  * MARC interface implemented. Minor bugs fixed. fmltest can
60  * be used to format single MARC records. New function '\list'
61  * implemented.
62  *
63  * Revision 1.2  1995/02/07  16:09:24  adam
64  * The \ character is no longer INCLUDED when terminating a token.
65  * Major changes in tokenization routines. Bug fixes in expressions
66  * with lists (fml_sub0).
67  *
68  * Revision 1.1.1.1  1995/02/06  13:48:10  adam
69  * First version of the FML interpreter. It's slow and memory isn't
70  * freed properly. In particular, the FML nodes aren't released yet.
71  *
72  */
73 #include <string.h>
74 #include <assert.h>
75 #include <stdio.h>
76
77 #include "fmlp.h"
78
79 static int look_char;
80 static int look_type;
81 static char lex_buf[FML_MAX_TOKEN];
82
83 static void lexer (Fml fml);
84
85 struct fml_node *fml_group (Fml fml);
86
87 struct fml_node *fml_tokenize (Fml fml)
88 {
89     struct fml_node *p;
90
91     look_char = (*fml->read_func)();
92     p = fml_group (fml);
93     if (fml->debug)
94     {
95         fml_pr_list (p);
96         printf ("\n");
97     }
98     if (look_char != fml->eof_mark)
99     {
100         fprintf (stderr, "Ill formed parantheses");
101         exit (1);
102     }
103     return p;
104 }
105
106 void fml_pr_list (struct fml_node *p)
107 {
108     printf ("{");
109
110     while (p)
111     {
112         if (p->is_atom)
113         {
114             char buf[100];
115             fml_atom_str (p->p[0], buf);
116             printf (" %s", buf);
117         }
118         else
119         {
120             printf (" ");
121             fml_pr_list (p->p[0]);
122         }
123         p = p->p[1];
124     }
125     printf (" }");         
126 }
127
128 struct fml_node *fml_group (Fml fml)
129 {
130     struct fml_node *ptr0 = NULL, *ptr1, *ptr2;
131
132     lexer (fml);
133     if (look_type == 0)
134         return NULL;
135     while (1)
136     {
137         if (look_type == 'a')
138         {
139             ptr2 = fml_node_alloc (fml);
140             if (!ptr0)
141                 ptr0 = ptr2;
142             else
143                 ptr1->p[1] = ptr2;
144             ptr2->p[0] = fml_atom_alloc (fml, lex_buf);
145             ptr2->is_atom = 1;
146         }
147         else if (look_type == '{')
148         {
149             struct fml_node *sptr = fml_group (fml);
150             if (sptr)
151             {
152                 ptr2 = fml_node_alloc (fml);
153                 if (!ptr0)
154                     ptr0 = ptr2;
155                 else
156                         ptr1->p[1] = ptr2;
157                 ptr2->p[0] = sptr;
158                 ptr2->is_atom = 0;
159             }
160             else
161             {
162                 ptr2 = fml_node_alloc (fml);
163                 if (!ptr0)
164                     ptr0 = ptr2;
165                 else
166                     ptr1->p[1] = ptr2;
167                 ptr2->is_atom = 0;
168             }
169         }
170         else
171             break;
172         lexer (fml);
173         ptr1 = ptr2;
174     }
175     return ptr0;
176 }
177
178 static void lexer (Fml fml)
179 {
180     int off;
181     while (1) 
182     {
183         if (look_char == fml->eof_mark)
184         {
185             look_type = 0;
186             return;
187         }
188         else if (look_char == fml->comment_char)
189         {
190             do
191                 look_char = (*fml->read_func)();
192             while (look_char != '\n' && look_char != fml->eof_mark);
193         }
194         else
195         {
196             if (!strchr (fml->white_chars, look_char))
197                 break;
198             look_char = (*fml->read_func)();
199         }
200     }
201     if (look_char == '{')
202     {
203         look_type = '{';
204         look_char = (*fml->read_func)();
205     }
206     else if (look_char == '}')
207     {
208         look_type = '}';
209         look_char = (*fml->read_func)();
210     }        
211     else if (look_char == '\'')
212     {
213         off = 0;
214         look_char = (*fml->read_func)();
215         while (look_char != fml->eof_mark && look_char != '\'')
216         {
217             lex_buf[off++] = look_char;
218             if (look_char == '\\')
219             {
220                 look_char = (*fml->read_func)();
221                 switch (look_char)
222                 {
223                 case 'n':
224                     lex_buf[off-1] = '\n';
225                     break;
226                 case 't':
227                     lex_buf[off-1] = '\n';
228                     break;
229                 case '\'':
230                     lex_buf[off-1] = '\''; 
231                     break;
232                 default:
233                     lex_buf[off-1] = look_char;
234                 }
235             }
236             look_char = (*fml->read_func)();
237         } 
238         lex_buf[off] = '\0';
239         look_type = 'a';
240         if (look_char == '\'')
241             look_char = (*fml->read_func)();
242     }
243     else
244     {
245         off = 0;
246         do
247         {
248             lex_buf[off++] = look_char;
249             look_char = (*fml->read_func)();
250         } while (look_char != fml->eof_mark
251                  && !strchr (fml->white_chars, look_char)
252                  && look_char != '{' && look_char != '}');
253         lex_buf[off] = '\0';
254         look_type = 'a';
255     }
256 #if 0
257     if (fml->debug)
258     {
259         if (look_type == 'a')
260             printf ("[%s]", lex_buf);
261         else
262             printf ("[%c]", look_type);
263     }
264 #endif
265 }