Added Gnulib intprops module.
[portablexdr.git] / rpcgen_scan.l
1 /* -*- C -*-
2  * rpcgen - Generate XDR bindings automatically.
3  * Copyright (C) 2008 Red Hat Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 %{
21 #include <config.h>
22 #include "rpcgen_parse.h"
23 #include "rpcgen_int.h"
24 %}
25
26 %option noyywrap
27 %option nounput
28 %option yylineno
29
30 HEXLIT     "0x"[0-9a-fA-F]+
31 DECLIT     0|[1-9][0-9]*
32 OCTLIT     0[0-7]+
33 INTLIT     {HEXLIT}|{DECLIT}|{OCTLIT}
34 IDENT      [a-zA-Z_][a-zA-Z_0-9]*
35 WS         [[:space:]]+
36
37 %x cstring
38
39 %%
40
41  /* # lineno "filename"
42   * cpp itself sets file and line numbers using these directives.  We
43   * have to parse this ourselves, since these could occur anywhere in
44   * the input, eg. in the middle of a struct definition.
45   */
46 ^"#".*\n    {
47   char *filename;
48   int lineno;
49
50   /* Allocate enough space to store the returned filename string. */
51   filename = malloc (strlen (yytext));
52   if (filename == NULL) perrorf ("malloc");
53
54   if (sscanf (yytext+2, "%d \"%[^\"]\"", &lineno, filename) == 2) {
55     yylineno = lineno-1;
56     free (input_filename);
57     input_filename = filename;
58   }
59   else free (filename);
60  }
61
62  /* Anything on a line beginning with % is passed to the output.  Again
63   * we have to handle this within the scanner.
64   */
65 ^"%".*\n   fputs (yytext+1, yyout);
66
67  /* C string constants. */
68 \"         start_string(); BEGIN (cstring);
69 <cstring>{
70   \"       BEGIN (INITIAL); yylval.str = end_string(); return STRLIT;
71
72   \n       error ("unterminated string constant");
73   <<EOF>>  error ("unterminated string constant");
74
75   \\[0-7]{1,3} {
76     /* octal escape sequence */
77     int result;
78
79     (void) sscanf (yytext + 1, "%o", &result);
80
81     if (result > 0xff)
82       error ("octal constant is out of range");
83
84     add_char (result);
85   }
86
87   /* Does C allow these?? Maybe confusing it with OCaml.
88   \\x[0-9a-fA-F]{2} {
89     int result;
90
91     (void) sscanf( yytext + 1, "%x", &result );
92
93     add_char (result);
94   } */
95
96   \\[0-9]+ {
97     /* generate error - bad escape sequence; something
98      * like '\48' or '\0777777'
99      */
100     error ("bad escape sequence: %s\n", yytext);
101   }
102
103   \\n  add_char ('\n');
104   \\t  add_char ('\t');
105   \\r  add_char ('\r');
106   \\b  add_char ('\b');
107   \\f  add_char ('\f');
108
109   /* Backslash followed by a literal newline character. */
110   \\\n add_char ('\n');
111
112   /* Unrecognised escape character - should be an error? */
113   \\.  add_char (yytext[1]);
114
115   [^\\\n\"]+ {
116     add_string (yytext);
117   }
118 }
119
120  /* Keywords. */
121 struct     return STRUCT;
122 enum       return ENUM;
123 const      return CONST;
124 typedef    return TYPEDEF;
125 union      return UNION;
126 switch     return SWITCH;
127 case       return CASE;
128 default    return DEFAULT;
129 program    return PROGRAM;
130
131 unsigned   return UNSIGNED;
132 signed     return SIGNED;
133 char       return CHAR;
134 short      return SHORT;
135 int        return INT;
136 hyper      return HYPER;
137 float      return FLOAT;
138 double     return DOUBLE;
139 string     return STRING;
140 opaque     return OPAQUE;
141 bool       return BOOL;
142
143 void       return VOID;
144
145  /* Identifiers. */
146 {IDENT}    { yylval.str = strdup (yytext); return IDENT; }
147
148  /* Numeric constants are tricky to scan accurately, so keep them as
149   * strings and pass them through directly to the C compiler.
150   */
151 {INTLIT}   { yylval.str = strdup (yytext); return INTLIT; }
152
153  /* Single characters with special meaning. */
154 ":"|";"|","|"{"|"}"|"("|")"|"["|"]"|"<"|">"|"="|"*" return yytext[0];
155
156  /* Ignore whitespace. */
157 {WS}
158
159  /* Anything else is an error. */
160 .          error ("invalid character in input near '%c'", yytext[0]);