Imported Upstream version 0.4.8
[platform/upstream/libsmi.git] / lib / scanner-sming.l
1 /*
2  * scanner-sming.l --
3  *
4  *      Lexical rules for scanning the SMIng MIB module language.
5  *
6  * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
7  *
8  * See the file "COPYING" for information on usage and redistribution
9  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10  *
11  * @(#) $Id: scanner-sming.l 7734 2008-02-15 07:49:14Z schoenw $
12  */
13
14 %option noyywrap
15
16 %{
17
18 #include <config.h>
19     
20 #ifdef BACKEND_SMING
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include <errno.h>
26
27 #if defined(HAVE_WIN_H)
28 #include "win.h"
29 #endif
30
31 #include "error.h"
32 #include "util.h"
33 #include "parser-sming.h"
34 #include "parser-sming.tab.h"
35 #include "scanner-sming.h"
36
37 #ifdef HAVE_DMALLOC_H
38 #include <dmalloc.h>
39 #endif
40
41
42
43 /* we need a reentrant parser, so yylex gets arguments */
44 #if 0
45 #define YY_DECL int yylex YY_PROTO((YYSTYPE *lvalp, void *parser))
46 #else
47 #define YY_DECL int yylex(YYSTYPE *lvalp, void *parser)
48 #endif
49
50
51
52 #define thisParser (*(Parser *) parser)
53
54
55
56 #define MAX_NUMBER              "18446744073709551615" /* max Counter64 */
57
58
59
60 /*
61  * This makes the usual notation when referencing attributes also
62  * work with our pure parser code.
63  */
64 #define yylval (*lvalp)
65
66
67 static YY_BUFFER_STATE yybuffer[MAX_LEX_DEPTH];
68
69 static int lexDepth = 0; 
70
71  
72 int
73 smingEnterLexRecursion(file)
74     FILE *file;
75 {
76     if (lexDepth >= MAX_LEX_DEPTH) {
77         return (-1);
78     }
79     yybuffer[lexDepth++] = YY_CURRENT_BUFFER;
80     yy_switch_to_buffer(yy_create_buffer(file, YY_BUF_SIZE));
81     return (lexDepth);
82 }
83
84
85  
86 void
87 smingLeaveLexRecursion()
88 {    
89     yy_delete_buffer(YY_CURRENT_BUFFER);
90     yy_switch_to_buffer(yybuffer[--lexDepth]);
91 }
92
93
94
95 %}
96
97
98
99 /*
100  * Lex pattern definitions.
101  */
102 delim           ([^a-zA-Z0-9-])
103 lineBreak       ("\n"|"\n\015"|"\015\n")
104 WSP             (" "|"\t")
105 VCHAR           ([\041-\176])
106 HTAB            "\t"
107 SP              " "
108
109
110 /*
111  * Lex state definitions.
112  */
113 %s              Skipline
114
115 %%
116
117
118
119  /*
120   * Lex rules for comments. Do you use {lineBreak} here because it
121   * introduces a trailing context which is (a) slow and (b) causes
122   * REJECT to be used.
123   */
124
125 <INITIAL>"//"({WSP}|{VCHAR})*/"\n" {
126 }
127
128 <INITIAL>"//"({WSP}|{VCHAR})*/"\n\015" {
129 }
130
131 <INITIAL>"//"({WSP}|{VCHAR})*/"\015\n" {
132 }
133
134  /*
135   * Lex rules for some special tokens.
136   */
137
138 <INITIAL>[\{\}\(\)\;\,\-\.\|] {
139     return yytext[0];
140 }
141     
142 <INITIAL>".." {
143     return DOT_DOT;
144 }
145
146 <INITIAL>"."/[^\.] {
147     return DOT;
148 }
149
150 <INITIAL>"::" {
151     return COLON_COLON;
152 }
153
154  /*
155   * Lex rules for separators.
156   */
157
158 <INITIAL>{lineBreak} {
159     thisParser.line++;
160 }
161
162 <INITIAL>{WSP} {
163 }
164
165  /*
166   * Lex rules for known keywords.
167   */
168
169 <INITIAL>module/{delim} {
170     yylval.id = yytext;
171     return moduleKeyword;
172 }
173
174 <INITIAL>import/{delim} {
175     yylval.id = yytext;
176     return importKeyword;
177 }
178
179 <INITIAL>revision/{delim} {
180     yylval.id = yytext;
181     return revisionKeyword;
182 }
183
184 <INITIAL>date/{delim} {
185     yylval.id = yytext;
186     return dateKeyword;
187 }
188
189 <INITIAL>organization/{delim} {
190     yylval.id = yytext;
191     return organizationKeyword;
192 }
193
194 <INITIAL>contact/{delim} {
195     yylval.id = yytext;
196     return contactKeyword;
197 }
198
199 <INITIAL>description/{delim} {
200     yylval.id = yytext;
201     return descriptionKeyword;
202 }
203
204 <INITIAL>reference/{delim} {
205     yylval.id = yytext;
206     return referenceKeyword;
207 }
208
209 <INITIAL>extension/{delim} {
210     yylval.id = yytext;
211     return extensionKeyword;
212 }
213
214 <INITIAL>typedef/{delim} {
215     yylval.id = yytext;
216     return typedefKeyword;
217 }
218
219 <INITIAL>type/{delim} {
220     yylval.id = yytext;
221     return typeKeyword;
222 }
223
224 <INITIAL>parent/{delim} {
225     yylval.id = yytext;
226     return parentKeyword;
227 }
228
229 <INITIAL>identity/{delim} {
230     yylval.id = yytext;
231     return identityKeyword;
232 }
233
234 <INITIAL>class/{delim} {
235     yylval.id = yytext;
236     return classKeyword;
237 }
238
239 <INITIAL>extends/{delim} {
240     yylval.id = yytext;
241     return extendsKeyword;
242 }
243
244 <INITIAL>attribute/{delim} {
245     yylval.id = yytext;
246     return attributeKeyword;
247 }
248
249 <INITIAL>unique/{delim} {
250     yylval.id = yytext;
251     return uniqueKeyword;
252 }
253
254 <INITIAL>event/{delim} {
255     yylval.id = yytext;
256     return eventKeyword;
257 }
258
259 <INITIAL>format/{delim} {
260     yylval.id = yytext;
261     return formatKeyword;
262 }
263
264 <INITIAL>units/{delim} {
265     yylval.id = yytext;
266     return unitsKeyword;
267 }
268
269 <INITIAL>status/{delim} {
270     yylval.id = yytext;
271     return statusKeyword;
272 }
273
274 <INITIAL>access/{delim} {
275     yylval.id = yytext;
276     return accessKeyword;
277 }
278
279 <INITIAL>default/{delim} {
280     yylval.id = yytext;
281     return defaultKeyword;
282 }
283
284 <INITIAL>abnf/{delim} {
285     yylval.id = yytext;
286     return abnfKeyword;
287 }
288
289
290  /*
291   *Base types keywords
292   */
293 <INITIAL>OctetString/{delim} {
294     yylval.id = yytext;
295     return OctetStringKeyword;
296 }
297
298 <INITIAL>Pointer/{delim} {
299     yylval.id = yytext;
300     return PointerKeyword;
301 }
302
303 <INITIAL>ObjectIdentifier/{delim} {
304     yylval.id = yytext;
305     return ObjectIdentifierKeyword;
306 }
307
308 <INITIAL>Integer32/{delim} {
309     yylval.id = yytext;
310     return Integer32Keyword;
311 }
312
313 <INITIAL>Integer64/{delim} {
314     yylval.id = yytext;
315     return Integer64Keyword;
316 }
317
318 <INITIAL>Unsigned32/{delim} {
319     yylval.id = yytext;
320     return Unsigned32Keyword;
321 }
322
323 <INITIAL>Unsigned64/{delim} {
324     yylval.id = yytext;
325     return Unsigned64Keyword;
326 }
327
328 <INITIAL>Float32/{delim} {
329     yylval.id = yytext;
330     return Float32Keyword;
331 }
332
333 <INITIAL>Float64/{delim} {
334     yylval.id = yytext;
335     return Float64Keyword;
336 }
337
338 <INITIAL>Float128/{delim} {
339     yylval.id = yytext;
340     return Float128Keyword;
341 }
342
343 <INITIAL>Bits/{delim} {
344     yylval.id = yytext;
345     return BitsKeyword;
346 }
347
348 <INITIAL>Enumeration/{delim} {
349     yylval.id = yytext;
350     return EnumerationKeyword;
351 }
352
353  /*
354   *Status keywords
355   */
356
357 <INITIAL>current/{delim} {
358     yylval.id = yytext;
359     return currentKeyword;
360 }
361
362 <INITIAL>deprecated/{delim} {
363     yylval.id = yytext;
364     return deprecatedKeyword;
365 }
366
367 <INITIAL>obsolete/{delim} {
368     yylval.id = yytext;
369     return obsoleteKeyword;
370 }
371
372  /*
373   *Access keywords
374   */
375
376 <INITIAL>eventonly/{delim} {
377     yylval.id = yytext;
378     return eventonlyKeyword;
379 }
380
381 <INITIAL>readonly/{delim} {
382     yylval.id = yytext;
383     return readonlyKeyword;
384 }
385
386 <INITIAL>readwrite/{delim} {
387     yylval.id = yytext;
388     return readwriteKeyword;
389 }
390
391  /*
392   *Special floating point values' keywords
393   */
394
395 <INITIAL>neginf/{delim} {
396     yylval.id = yytext;
397     return neginfKeyword;
398 }
399
400 <INITIAL>posinf/{delim} {
401     yylval.id = yytext;
402     return posinfKeyword;
403 }
404
405 <INITIAL>snan/{delim} {
406     yylval.id = yytext;
407     return snanKeyword;
408 }
409
410 <INITIAL>qnan/{delim} {
411     yylval.id = yytext;
412     return qnanKeyword;
413 }
414
415
416
417  /*
418   * Lex rules for identifiers.
419   */
420
421  /* e.g. module names: REF: draft,p.12-13 */
422 <INITIAL>[A-Z](-?[a-zA-Z0-9_]+)*-? {
423     if (yytext[yyleng-1] == '-') {
424         smiPrintError(parser, ERR_ID_ENDS_IN_HYPHEN, yytext);
425     }
426     if (yyleng > 64) {
427         smiPrintError(parser, ERR_UCIDENTIFIER_64, yytext);
428     }
429     if (strchr(yytext, '_')) {
430         smiPrintError(parser, ERR_UNDERSCORE_IN_IDENTIFIER, yytext);
431     }
432     yylval.text = smiStrdup(yytext);
433     return ucIdentifier;
434 }
435
436  /* same for lowercase names */
437 <INITIAL>[a-z](-?[a-zA-Z0-9_]+)*-? {
438     if (yytext[yyleng-1] == '-') {
439         smiPrintError(parser, ERR_ID_ENDS_IN_HYPHEN, yytext);
440     }
441     if (yyleng > 64) {
442         smiPrintError(parser, ERR_LCIDENTIFIER_64, yytext);
443     }
444     if (strchr(yytext, '_')) {
445         smiPrintError(parser, ERR_UNDERSCORE_IN_IDENTIFIER, yytext);
446     }
447     yylval.text = smiStrdup(yytext);
448     return lcIdentifier;
449 }
450
451  /*
452   * Lex rules for numbers.
453   *
454   * NOTE: `-' is a separate token. Hence, there are no negative numbers.
455   */
456
457 <INITIAL>0+/[0-9] {
458     smiPrintError(parser, ERR_LEADING_ZEROS);
459 }
460
461 <INITIAL>([1-9][0-9]*|0)/[^0-9] {
462     if ((yyleng > sizeof(MAX_NUMBER)-1) ||
463         ((yyleng == sizeof(MAX_NUMBER)-1) &&
464          (strcmp(yytext, MAX_NUMBER) > 0))) {
465         smiPrintError(parser, ERR_NUMBER_TOO_LARGE, yytext);
466     }
467     yylval.text = yytext;
468     return decimalNumber;
469 }
470
471 <INITIAL>0x[0-9a-fA-F]+/[^0-9a-fA-F] {
472     if (yyleng % 2) {
473         smiPrintError(parser, ERR_HEX_STRING_MUL2, yytext);
474     }
475     yylval.text = yytext;
476     return hexadecimalNumber;
477 }
478  /*
479   * Lex rules for floating point values.
480   */
481
482 <INITIAL>([0-9]*\.[0-9]+([eE][+-]?[0-9]+)?)/[^0-9] {
483     yylval.text = yytext;
484     return floatValue;
485 }
486
487  /*
488   * Lex rules for OID's.
489   */
490   
491 <INITIAL>([0-9A-Za-z]-?)+\.([0-9A-Za-z]-?)+\.([0-9A-Za-z]-?)+(\.([0-9A-Za-z]-?)+)*/([^0-9A-Za-z]) {
492     yylval.text = yytext;
493     return OID;
494 }
495
496
497  /*
498   * Lex rules for textSegments.
499   */
500
501 <INITIAL>\"([^\"]|(\\\"))*\" {
502     char *s, *d;                /* the source and destination pointer */
503     int column = 0;             /* the current column */
504     int newlineflag = 0;        /* we have just passed a newline */
505     int cutoffcolumn = 0;       /* cut off white space up to this column */
506                                 /* (computed by caculating the indentation */
507                                 /* of the first column) */
508
509     yytext[yyleng-1] = '\0';
510     for (d = yytext, s = yytext+1; s[0]; s++, d++) {
511
512         if ((s[0] == '\n' && s[1] == '\r')      /* newline sequence */
513             || (s[0] == '\r' && s[1] == '\n')) {
514             thisParser.line += 1;
515             d[0] = '\n';
516             s++;
517             newlineflag = 1;
518             column = 0;
519             if (cutoffcolumn < 0) cutoffcolumn = 0;
520         } else if (s[0] == '\n') {              /* simple newline */
521             thisParser.line += 1;
522             d[0] = '\n';
523             newlineflag = 1;
524             column = 0;
525             if (cutoffcolumn < 0) cutoffcolumn = 0;
526         } else {
527             if (newlineflag && isspace((int)(unsigned char)s[0])) {     /* space after newline */
528                 if (cutoffcolumn <= 0) {
529                     cutoffcolumn -= (s[0] == '\t') ? (8-((column-1) % 8)) : 1;
530                 }
531                 column += (s[0] == '\t') ? (8-((column-1) % 8)) : 1;
532                 if (cutoffcolumn <= 0 || column <= cutoffcolumn) {
533                     d--;
534                 } else {
535                     d[0] = s[0];
536                     newlineflag = 0;
537                 }
538             } else {                            /* everything else */
539                 if (! isascii(s[0])) {
540                     smiPrintError(parser, ERR_ILLEGAL_CHAR_IN_STRING,
541                                   s[0], (unsigned char) s[0]);
542                 }
543                 d[0] = s[0];
544                 newlineflag = 0;
545                 if (cutoffcolumn < 0) {
546                     cutoffcolumn *= -1;
547                 }
548             }
549         }
550     }
551     d[0] = '\0';
552
553     yylval.text = yytext;
554     return textSegment;
555 }
556
557  /*
558   * Skip the remainder of the line
559   */
560 <Skipline>.*{lineBreak} {
561     thisParser.line++;
562     BEGIN(INITIAL);
563 }
564
565  /*
566   * Everything else...
567   */
568
569 . {
570     smiPrintError(parser, ERR_LEX_UNEXPECTED_CHAR);
571     BEGIN(Skipline);
572 }
573
574 %%
575
576 #endif