1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) Sébastien Granjoux 2009 <seb.sfo@free.fr>
6 * main.c is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * main.c is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "mk-scanner.h"
23 #include "mk-parser.h"
26 #include "libanjuta/anjuta-debug.h"
27 #include "libanjuta/anjuta-token-stream.h"
32 #define YY_INPUT(buffer, result, max_size) result = anjuta_token_stream_read (yyextra->stream, buffer, max_size)
34 #define YY_EXTRA_TYPE MkpScanner*
36 //#define YY_USER_INIT {yy_flex_debug = 1;}
38 static gint mkp_scanner_parse_end (MkpScanner *scanner);
40 #define RETURN(tok) *yylval = anjuta_token_stream_tokenize (yyextra->stream, tok, yyleng); \
47 AnjutaTokenStream *stream;
54 %option reentrant noyywrap yylineno
56 /* Remove some warnings */
57 %option nounput noinput
59 %option prefix="mkp_mk_yy"
61 %option bison-bridge bison-locations
63 %option never-interactive
69 NAME [^ \t\n\r:#=$"'`&@\\]*
76 ([ ]|\\\n)([ \t]|\\\n)* { RETURN (SPACE); }
82 \$\([^ \t\n\r:#=$)]+\) { RETURN (VARIABLE); }
84 \$\{[^ \t\n\r:#=$}]+\} { RETURN (VARIABLE); }
86 \$[^ \t\n\r\(\{] { RETURN (VARIABLE); }
92 :: { RETURN (DOUBLE_COLON); }
94 ; { RETURN (SEMI_COLON); }
96 \| { RETURN (ORDER); }
98 \= { RETURN (EQUAL); }
100 := { RETURN (IMMEDIATE_EQUAL); }
102 \?= { RETURN (CONDITIONAL_EQUAL); }
104 \+= { RETURN (APPEND); }
106 \\[ ] { RETURN (CHARACTER); }
108 \\: { RETURN (CHARACTER); }
110 \\= { RETURN (CHARACTER); }
112 \\# { RETURN (CHARACTER); }
114 .PHONY { RETURN (_PHONY); }
116 .SUFFIXES { RETURN (_SUFFIXES); }
118 .DEFAULT { RETURN (_DEFAULT); }
120 .PRECIOUS { RETURN (_PRECIOUS); }
122 .INTERMEDIATE { RETURN (_INTERMEDIATE); }
124 .SECONDARY { RETURN (_SECONDARY); }
126 .SECONDEXPANSION { RETURN (_SECONDEXPANSION); }
128 .DELETE_ON_ERROR { RETURN (_DELETE_ON_ERROR); }
130 .IGNORE { RETURN (_IGNORE); }
132 .LOW_RESOLUTION_TIME { RETURN (_LOW_RESOLUTION_TIME); }
134 .SILENT { RETURN (_SILENT); }
136 .EXPORT_ALL_VARIABLES { RETURN (_EXPORT_ALL_VARIABLES); }
138 .NOTPARALLEL { RETURN (_NOTPARALLEL); }
140 ifeq { RETURN (IFEQ); }
142 else { RETURN (ELSE); }
144 endif { RETURN (ENDIF); }
146 {NAME} { RETURN (NAME); }
148 . { RETURN (CHARACTER); }
150 <<EOF>> { if (mkp_scanner_parse_end (yyextra) == YY_NULL) return YY_NULL; }
156 *---------------------------------------------------------------------------*/
159 mkp_scanner_parse_end (MkpScanner *scanner)
161 yypop_buffer_state(scanner->scanner);
162 scanner->stream = anjuta_token_stream_pop (scanner->stream);
164 if (scanner->stream == NULL)
175 *---------------------------------------------------------------------------*/
178 mkp_yyerror (YYLTYPE *loc, MkpScanner *scanner, char const *s)
180 AnjutaTokenFileLocation location;
182 //g_message ("error at %d error at * %d string \"%s\"", anjuta_token_get_type((AnjutaToken *)loc), anjuta_token_get_type(*loc), anjuta_token_get_string ((AnjutaToken *loc));
183 if (mkp_project_get_token_location (scanner->project, &location, *loc))
185 g_message ("%s:%d.%d %s\n", location.filename, location.line, location.column, s);
186 g_free (location.filename);
190 g_message ("%s \n", s);
195 mkp_scanner_update_variable (MkpScanner *scanner, AnjutaToken *variable)
197 mkp_project_update_variable (scanner->project, variable);
201 mkp_scanner_add_rule (MkpScanner *scanner, AnjutaToken *rule)
203 mkp_project_add_rule (scanner->project, rule);
207 mkp_scanner_parse_variable (MkpScanner *scanner, AnjutaToken *variable)
210 AnjutaToken *content;
212 anjuta_token_set_type (variable, ANJUTA_TOKEN_VARIABLE);
213 content = anjuta_token_new_static (ANJUTA_TOKEN_CONTENT, NULL);
214 anjuta_token_stream_append_token (scanner->stream, content);
216 group = mkp_project_get_variable_token (scanner->project, variable);
217 //fprintf(stdout, "get variable %s is %p\n", anjuta_token_evaluate (variable), group);
220 //AnjutaToken *token;
222 //anjuta_token_dump (group);
223 //token = anjuta_token_group_into_token (group);
224 //anjuta_token_set_type (token, ANJUTA_TOKEN_CONTENT);
225 //anjuta_token_dump (token);
226 //fprintf (stdout,"variable %s\n", anjuta_token_get_string (variable));
227 //anjuta_token_dump (group);
228 mkp_scanner_parse_token (scanner, group, NULL);
229 //anjuta_token_free (token);
234 *---------------------------------------------------------------------------*/
237 mkp_scanner_parse_token (MkpScanner *scanner, AnjutaToken *token, GError **error)
240 AnjutaTokenStream *stream;
242 stream = anjuta_token_stream_push (scanner->stream, NULL, token, NULL);
243 first = anjuta_token_stream_get_root (stream);
245 if (scanner->stream != NULL)
247 /* Parse an included file or a expanded variable */
249 scanner->stream = stream;
250 yypush_buffer_state(yy_create_buffer(NULL, YY_BUF_SIZE, scanner->scanner), scanner->scanner);
257 scanner->stream = stream;
258 ps = mkp_yypstate_new ();
261 YYSTYPE yylval_param;
262 YYLTYPE yylloc_param;
263 gint yychar = mkp_mk_yylex (&yylval_param, &yylloc_param, scanner->scanner);
265 yylloc_param = yylval_param;
266 status = mkp_yypush_parse (ps, yychar, &yylval_param, &yylloc_param, scanner);
267 } while (status == YYPUSH_MORE);
268 mkp_yypstate_delete (ps);
274 /* Constructor & Destructor
275 *---------------------------------------------------------------------------*/
278 mkp_scanner_new (MkpProject *project)
282 scanner = g_new0 (MkpScanner, 1);
284 yylex_init(&scanner->scanner);
285 yyset_extra (scanner, scanner->scanner);
287 scanner->project = project;
293 mkp_scanner_free (MkpScanner *scanner)
295 g_return_if_fail (scanner != NULL);
297 yylex_destroy(scanner->scanner);