1 %top{
2 /*
3  * Copyright (c) 2002, 2004 Tama Communications Corporation
4  *
5  * This file is part of GNU GLOBAL.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 /*
22  * scanner for assembly source code.
23  */
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 #include <stdio.h>
28 #ifdef STDC_HEADERS
29 #include <stdlib.h>
30 #endif
31 #include "global.h"
32 #include "anchor.h"
33 #include "incop.h"
34 #include "common.h"
35 #include "htags.h"
36 #include "../libparser/asm_res.h"
37 
38 #define lex_symbol_generation_rule(x) asm_ ## x
39 #include "lexcommon.h"
40 
41 #ifdef ECHO
42 #undef ECHO
43 #endif
44 #define ECHO	echos(LEXTEXT)
45 
46 #define YY_USER_ACTION DEFAULT_YY_USER_ACTION
47 
48 static int last_directive;
49 }
50  /* Definitions */
51 H		0[Xx][0-9A-Fa-f]+
52 N		[0-9]+
53 L		{N}L?
54 D1		{N}\.{N}([Ee][+-]?{N})?
55 D2		\.{N}([Ee][+-]?{N})?
56 NUMBER		-?({L}|{D1}|{D2})
57 ALPHA		[a-zA-Z_\x80-\xff]
58 ALPHANUM	[a-zA-Z_\x80-\xff0-9]
59 WORD		{ALPHA}{ALPHANUM}*
60 
61 %start	ASM C_COMMENT CPP_COMMENT SHELL_COMMENT STRING LITERAL PREPROCESSOR_LINE
62 %option 8bit noyywrap noyy_top_state stack never-interactive prefix="asm_"
63 %%
64  /* Backslash-newline */
65 \\\n		DEFAULT_BACKSLASH_NEWLINE_ACTION
66 
67  /* Comment */
68 <ASM,PREPROCESSOR_LINE>"/*"	{ echos(comment_begin); ECHO; yy_push_state(C_COMMENT); }
69 <C_COMMENT>"*/"	{ ECHO; echos(comment_end); yy_pop_state(); }
70 <C_COMMENT>.	{ put_char(LEXTEXT[0]); }
71 <C_COMMENT><<EOF>> {
72 		if (wflag)
73 			unexpected_eof(LINENO);
74 		yyterminate();
75 	}
76 <ASM,PREPROCESSOR_LINE>"//"	{ echos(comment_begin); ECHO; yy_push_state(CPP_COMMENT); }
77 
78  /* String */
79 <ASM,PREPROCESSOR_LINE>\"	{ ECHO; yy_push_state(STRING); }
80 <STRING>\"	{ ECHO; yy_pop_state(); }
81 <STRING>\\.	{ put_char(LEXTEXT[0]); put_char(LEXTEXT[1]); }
82 
83  /* Literal */
84 <ASM,PREPROCESSOR_LINE>\'	{ ECHO; yy_push_state(LITERAL); }
85 <LITERAL>\'	{ ECHO; yy_pop_state(); }
86 <LITERAL>\\.	{ put_char(LEXTEXT[0]); put_char(LEXTEXT[1]); }
87 
88  /* Preprocessing directive */
89 <ASM>^[ \t]*\#[ \t]*(import|include|include_next) {
90 		int c;
91 
92 		put_macro(LEXTEXT);
93 		/*
94 		 * #include|   <aaa/bbb.h>|
95 		 *         ~~~~~~~~~~~~~~~~
96 		 */
97 		while ((c = input()) && c != EOF && c != '\n' && isspace(c))
98 			echoc(c);
99 		if (c == EOF)
100 			c = '\n';
101 		if (c == '\n') {
102 			unput(c);
103 		} else if (c) {
104 			char path[MAXPATHLEN], *p = path, *lim = p + MAXPATHLEN - 1;
105 			int sep = 0;
106 
107 			if (c == '"')
108 				sep = c;
109 			else if (c == '<')
110 				sep = '>';
111 			put_char(c);
112 
113 			/* pick up path name */
114 			while ((c = input()) && c != EOF && c != '\n' && c != sep)
115 				if (p < lim)
116 					*p++ = c;
117 			*p = '\0';
118 			if (c == EOF)
119 				c = '\n';
120 			if (c == sep) {
121 				struct data *inc;
122 				const char *basename = locatestring(path, "/", MATCH_LAST);
123 
124 				if (basename)
125 					basename++;
126 				else
127 					basename = path;
128 				inc = get_inc(basename);
129 				if (inc)
130 					put_include_anchor(inc, path);
131 				else
132 					echos(path);
133 				put_char(sep);
134 			} else {
135 				echos(path);
136 				if (c)
137 					unput(c);
138 			}
139 		}
140 	}
141 <ASM>^[ \t]*\#[ \t]*{WORD} {
142 		if ((last_directive = asm_reserved_sharp(LEXTEXT, LEXLENG)) != 0) {
143 			put_macro(LEXTEXT);
144 			yy_push_state(PREPROCESSOR_LINE);
145 		} else {
146 			/*
147 			 * Don't warn about unknown directive.
148 			 * '#' may be used as the start of a comment.
149 			 */
150 			echos(comment_begin);
151 			ECHO;
152 			yy_push_state(SHELL_COMMENT);
153 		}
154 	}
155  /* Null directive */
156 <ASM>^[ \t]*\#	{ put_macro(LEXTEXT); }
157 
158 <ASM,PREPROCESSOR_LINE>{NUMBER}	ECHO;
159 <ASM,PREPROCESSOR_LINE>{WORD} {
160 		if (YY_START == PREPROCESSOR_LINE
161 		    && (last_directive == SHARP_IF || last_directive == SHARP_ELIF)
162 		    && strcmp(LEXTEXT, "defined") == 0)
163 			put_reserved_word(LEXTEXT);
164 		else {
165 			struct anchor *a = anchor_get(LEXTEXT, LEXLENG, 0, LINENO);
166 			if (a) {
167 				put_anchor(gettag(a), a->type, LINENO);
168 				a->done = 1;
169 			} else if (grtags_is_empty) {
170 				put_anchor_force(LEXTEXT, LEXLENG, LINENO);
171 			} else {
172 				ECHO;
173 			}
174 		}
175 	}
176 <ASM,PREPROCESSOR_LINE>[{}]	{ put_brace(LEXTEXT); }
177  /* New line */
178 \n		DEFAULT_END_OF_LINE_ACTION
179 .		{ put_char(LEXTEXT[0]); }
180 
181 %%
182 void
183 asm_parser_init(FILE *ip)
184 {
185 	newline_terminate_string = 1;
186 	DEFAULT_BEGIN_OF_FILE_ACTION
187 	BEGIN ASM;
188 }
189