Improved handling of qualifiers. Aliases or reserved words.
[egate.git] / ccl / ccltoken.c
1 /* CCL - lexical analysis
2  * Europagate, 1995
3  *
4  * $Log: ccltoken.c,v $
5  * Revision 1.6  1995/04/17 09:31:48  adam
6  * Improved handling of qualifiers. Aliases or reserved words.
7  *
8  * Revision 1.5  1995/02/23  08:32:00  adam
9  * Changed header.
10  *
11  * Revision 1.3  1995/02/15  17:42:16  adam
12  * Minor changes of the api of this module. FILE* argument added
13  * to ccl_pr_tree.
14  *
15  * Revision 1.2  1995/02/14  19:55:13  adam
16  * Header files ccl.h/cclp.h are gone! They have been merged an
17  * moved to ../include/ccl.h.
18  * Node kind(s) in ccl_rpn_node have changed names.
19  *
20  * Revision 1.1  1995/02/13  12:35:21  adam
21  * First version of CCL. Qualifiers aren't handled yet.
22  *
23  */
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <assert.h>
29
30 #include <ccl.h>
31
32 const char *ccl_token_and = "and";
33 const char *ccl_token_or = "or";
34 const char *ccl_token_not = "not andnot";
35 const char *ccl_token_set = "set";
36
37 /*
38  * token_cmp: Compare token with keyword(s)
39  * kw:     Keyword list. Each keyword is separated by space.
40  * token:  CCL token.
41  * return: 1 if token string matches one of the keywords in list;
42  *         0 otherwise.
43  */
44 static int token_cmp (const char *kw, struct ccl_token *token)
45 {
46     const char *cp1 = kw;
47     const char *cp2;
48     while ((cp2 = strchr (cp1, ' ')))
49     {
50         if (token->len == cp2-cp1 &&
51             !memcmp (cp1, token->name, token->len))
52             return 1;
53         cp1 = cp2+1;
54     }
55     return token->len == strlen(cp1) 
56            && !memcmp (cp1, token->name, token->len);
57 }
58
59 /*
60  * ccl_tokenize: tokenize CCL command string.
61  * return: CCL token list.
62  */
63 struct ccl_token *ccl_tokenize (const char *command)
64 {
65     const char *cp = command;
66     struct ccl_token *first = NULL;
67     struct ccl_token *last = NULL;
68
69     while (1)
70     {
71         while (*cp && strchr (" \t\r\n", *cp))
72         {
73             cp++;
74             continue;
75         }
76         if (!first)
77         {
78             first = last = malloc (sizeof (*first));
79             assert (first);
80             last->prev = NULL;
81         }
82         else
83         {
84             last->next = malloc (sizeof(*first));
85             assert (last->next);
86             last->next->prev = last;
87             last = last->next;
88         }
89         last->next = NULL;
90         last->name = cp;
91         last->len = 1;
92         switch (*cp++)
93         {
94         case '\0':
95             last->kind = CCL_TOK_EOL;
96             return first;
97         case '(':
98             last->kind = CCL_TOK_LP;
99             break;
100         case ')':
101             last->kind = CCL_TOK_RP;
102             break;
103         case ',':
104             last->kind = CCL_TOK_COMMA;
105             break;
106         case '%':
107         case '!':
108             last->kind = CCL_TOK_PROX;
109             while (*cp == '%' || *cp == '!')
110             {
111                 ++ last->len;
112                 cp++;
113             }
114             break;
115         case '>':
116         case '<':
117         case '=':
118             if (*cp == '=' || *cp == '<' || *cp == '>')
119             {
120                 cp++;
121                 last->kind = CCL_TOK_REL;
122                 ++ last->len;
123             }
124             else if (cp[-1] == '=')
125                 last->kind = CCL_TOK_EQ;
126             else
127                 last->kind = CCL_TOK_REL;
128             break;
129         case '-':
130             last->kind = CCL_TOK_MINUS;
131             break;
132         case '\"':
133             last->kind = CCL_TOK_TERM;
134             last->name = cp;
135             last->len = 0;
136             while (*cp && *cp != '\"')
137             {
138                 cp++;
139                 ++ last->len;
140             }
141             if (*cp == '\"')
142                 cp++;
143             break;
144         default:
145             while (*cp && !strchr ("(),%!><=- \t\n\r", *cp))
146             {
147                 cp++;
148                 ++ last->len;
149             }
150             if (token_cmp (ccl_token_and, last))
151                 last->kind = CCL_TOK_AND;
152             else if (token_cmp (ccl_token_or, last))
153                 last->kind = CCL_TOK_OR;
154             else if (token_cmp (ccl_token_not, last))
155                 last->kind = CCL_TOK_NOT;
156             else if (token_cmp (ccl_token_set, last))
157                 last->kind = CCL_TOK_SET;
158             else
159                 last->kind = CCL_TOK_TERM;
160         }
161     }
162     return first;
163 }