2 /* GObject introspection: C lexer
4 * Copyright (c) 1997 Sandro Sigala <ssigala@globalnet.it>
5 * Copyright (c) 2007-2008 Jürg Billeter <j@bitron.ch>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include "scannerparser.h"
37 #include "grealpath.h"
41 extern int yylex (GIGenerator *igenerator);
42 #define YY_DECL int yylex (GIGenerator *igenerator)
43 static int yywrap (void);
44 static void parse_comment (GIGenerator *igenerator);
45 static void process_directive (GIGenerator *igenerator);
46 static int check_identifier (GIGenerator *igenerator, const char *);
49 intsuffix ([uU][lL]?)|([lL][uU]?)
50 fracconst ([0-9]*\.[0-9]+)|([0-9]+\.)
51 exppart [eE][-+]?[0-9]+
53 chartext ([^\'])|(\\.)
54 stringtext ([^\"])|(\\.)
58 "\n" { ++lineno; } /* " */
59 [\t\f\v\r ]+ { /* Ignore whitespace. */ }
61 "/*" { parse_comment(igenerator); }
64 "#define "[a-zA-Z_][a-zA-Z_0-9]*"(" { yyless (yyleng - 1); return FUNCTION_MACRO; }
65 "#define "[a-zA-Z_][a-zA-Z_0-9]* { return OBJECT_MACRO; }
67 "#" { process_directive(igenerator); }
81 "..." { return ELLIPSIS; }
97 "+=" { return ADDEQ; }
98 "-=" { return SUBEQ; }
99 "*=" { return MULEQ; }
100 "/=" { return DIVEQ; }
101 "%=" { return MODEQ; }
102 "^=" { return XOREQ; }
103 "&=" { return ANDEQ; }
104 "|=" { return OREQ; }
107 "<<=" { return SLEQ; }
108 ">>=" { return SREQ; }
110 "!=" { return NOTEQ; }
111 "<=" { return LTEQ; }
112 ">=" { return GTEQ; }
113 "&&" { return ANDAND; }
114 "||" { return OROR; }
115 "++" { return PLUSPLUS; }
116 "--" { return MINUSMINUS; }
118 "->" { return ARROW; }
120 [a-zA-Z_][a-zA-Z_0-9]* { if (igenerator->macro_scan) return IDENTIFIER; else REJECT; }
122 "auto" { return AUTO; }
123 "_Bool" { return BOOL; }
124 "break" { return BREAK; }
125 "case" { return CASE; }
126 "char" { return CHAR; }
127 "const" { return CONST; }
128 "continue" { return CONTINUE; }
129 "default" { return DEFAULT; }
131 "double" { return DOUBLE; }
132 "else" { return ELSE; }
133 "enum" { return ENUM; }
134 "extern" { return EXTERN; }
135 "float" { return FLOAT; }
136 "for" { return FOR; }
137 "goto" { return GOTO; }
139 "inline" { return INLINE; }
140 "int" { return INT; }
141 "long" { return LONG; }
142 "register" { return REGISTER; }
143 "restrict" { return RESTRICT; }
144 "return" { return RETURN; }
145 "short" { return SHORT; }
146 "signed" { return SIGNED; }
147 "sizeof" { return SIZEOF; }
148 "static" { return STATIC; }
149 "struct" { return STRUCT; }
150 "switch" { return SWITCH; }
151 "typedef" { return TYPEDEF; }
152 "union" { return UNION; }
153 "unsigned" { return UNSIGNED; }
154 "void" { return VOID; }
155 "volatile" { return VOLATILE; }
156 "while" { return WHILE; }
158 [a-zA-Z_][a-zA-Z_0-9]* { return check_identifier(igenerator, yytext); }
160 "0"[xX][0-9a-fA-F]+{intsuffix}? { return INTEGER; }
161 "0"[0-7]+{intsuffix}? { return INTEGER; }
162 [0-9]+{intsuffix}? { return INTEGER; }
164 {fracconst}{exppart}?{floatsuffix}? { return FLOATING; }
165 [0-9]+{exppart}{floatsuffix}? { return FLOATING; }
167 "'"{chartext}*"'" { return CHARACTER; }
168 "L'"{chartext}*"'" { return CHARACTER; }
170 "\""{stringtext}*"\"" { return STRING; }
171 "L\""{stringtext}*"\"" { return STRING; }
173 . { fprintf(stderr, "%s:%d: unexpected character `%c'\n", igenerator->current_filename, lineno, yytext[0]); }
177 static int yywrap (void)
182 static void parse_gtkdoc (GIGenerator *igenerator, int *c1, int *c2)
184 gboolean isline = FALSE;
188 CDirective *directive;
204 } while (*c2 != EOF && !(*c1 == '*' && *c2 == '/'));
211 parts = g_strsplit (line, ": ", 2);
213 if (g_strv_length (parts) == 2)
218 else /* parts == 1 */
224 directive = cdirective_new (name, value);
225 igenerator->directives = g_slist_prepend (igenerator->directives,
231 static void parse_comment (GIGenerator *igenerator)
238 while (c2 != EOF && !(c1 == '*' && c2 == '/'))
245 if (c1 == ' ' && c2 == '@')
249 parse_gtkdoc (igenerator, &c1, &c2);
254 static int check_identifier (GIGenerator *igenerator, const char *s)
257 * This function checks if `s' is a type name or an
261 if (g_igenerator_is_typedef (igenerator, s)) {
263 } else if (strcmp (s, "__builtin_va_list") == 0) {
270 static void process_directive (GIGenerator *igenerator)
272 /* extract current filename from #line directives */
273 GString *filename_builder;
274 gboolean in_string, found_filename;
277 found_filename = FALSE;
279 filename_builder = g_string_new ("");
282 while (c != EOF && c != '\n') {
286 found_filename = TRUE;
287 } else if (c >= '0' && c <= '9') {
288 if (!found_filename) {
289 lineno = lineno * 10 + (c - '0');
295 } else if (c == '\\') {
296 g_string_append_c (filename_builder, c);
298 g_string_append_c (filename_builder, c);
300 g_string_append_c (filename_builder, c);
306 if (filename_builder->len > 0) {
307 char *filename = g_strcompress (filename_builder->str);
308 g_free (igenerator->current_filename);
309 igenerator->current_filename = g_realpath(filename);
313 g_string_free (filename_builder, TRUE);