1 %top{
2 /*
3  * Copyright (c) 2002, 2004, 2010 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 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #ifdef HAVE_STRING_H
25 #include <string.h>
26 #else
27 #include <strings.h>
28 #endif
29 
30 #define YYLTYPE		int
31 
32 #include "internal.h"
33 #include "asm_parse.h"
34 #include "asm_res.h"
35 #include "die.h"
36 #include "linetable.h"
37 #include "strbuf.h"
38 
39 #define lex_symbol_generation_rule(x) asm_ ## x
40 #define LEXLEX lex_symbol_generation_rule(lex)
41 #define LEXTEXT lex_symbol_generation_rule(text)
42 #define LEXLENG lex_symbol_generation_rule(leng)
43 #define LEXLINENO lex_symbol_generation_rule(lineno)
44 #define LEXRESTART lex_symbol_generation_rule(restart)
45 #define LEXLVAL lex_symbol_generation_rule(lval)
46 #define LEXLLOC lex_symbol_generation_rule(lloc)
47 
48 #define YY_DECL	int LEXLEX(const struct parser_param *param)
49 
50 #define YY_INPUT(buf, result, max_size) do {				\
51 	if ((result = linetable_read(buf, max_size)) == -1)		\
52 		result = YY_NULL;					\
53 } while (0)
54 
55 #define ADD_SYM(tag, lno) do {						\
56 	LEXLVAL = strbuf_getlen(asm_symtable);				\
57 	LEXLLOC = (lno);						\
58 	strbuf_puts0(asm_symtable, tag);				\
59 } while (0)
60 
61 #undef PUT
62 #define PUT(type, tag, lno) do {					\
63 	const char *line_image = linetable_get(lno, NULL);		\
64 	char *nl = strchr(line_image, '\n');				\
65 	if (nl != NULL)							\
66 		*nl = '\0';						\
67 	param->put(type, tag, lno, param->file, line_image, param->arg);\
68 	if (nl != NULL)							\
69 		*nl = '\n';						\
70 } while (0)
71 
72 static int last_directive;
73 
74 }
75 
76 H		0[Xx][0-9A-Fa-f]+
77 N		[0-9]+
78 L		{N}L?
79 D1		{N}\.{N}([Ee][+-]?{N})?
80 D2		\.{N}([Ee][+-]?{N})?
81 NUMBER		-?({L}|{D1}|{D2})
82 ALPHA		[a-zA-Z_\x80-\xff]
83 ALPHANUM	[a-zA-Z_\x80-\xff0-9]
84 WORD		{ALPHA}{ALPHANUM}*
85 
86 %x C_COMMENT CPP_COMMENT STRING LITERAL
87 %s PREPROCESSOR_LINE
88 
89 %option 8bit yylineno stack noyywrap noyy_top_state never-interactive prefix="asm_"
90 
91 %%
92 
93  /* Ignore spaces */
94 [ \f\t\v]+
95 
96  /* C style comment */
97 "/*"		{ yy_push_state(C_COMMENT); }
98 <C_COMMENT>{
99 	[^*\n]*
100 	[^*\n]*\n
101 	"*"+[^*/\n]*
102 	"*"+[^*/\n]*\n
103 	"*"+"/"		{ yy_pop_state(); }
104 	<<EOF>> {
105 		if (param->flags & PARSER_WARNING)
106 			warning("unexpected eof. [+%d %s]", LEXLINENO, param->file);
107 		yyterminate();
108 	}
109 }
110 
111  /* C++ style line comment */
112 "//"		{ yy_push_state(CPP_COMMENT); }
113 <CPP_COMMENT>{
114 	(\\.|[^\\\n])+
115 	\\\n
116 	\n		{ yy_pop_state(); unput('\n'); }
117 }
118 
119  /* String */
120 \"		{ yy_push_state(STRING); }
121 <STRING>{
122 	(\\.|[^\"\\\n])+
123 	\\\n
124 	\n		{ yy_pop_state(); unput('\n'); return ASM_CONST; }
125 	\"		{ yy_pop_state(); return ASM_CONST; }
126 }
127 
128  /* Character */
129 \'		{ yy_push_state(LITERAL); }
130 <LITERAL>{
131 	(\\.|[^\'\\\n])+
132 	\\\n
133 	\n		{ yy_pop_state(); unput('\n'); return ASM_CONST; }
134 	\'		{ yy_pop_state(); return ASM_CONST; }
135 }
136 
137  /* Number */
138 {NUMBER}	{ return ASM_CONST; }
139 
140 <INITIAL>{
141 	^[ \t]*\#[ \t]*{WORD} {
142 		last_directive = asm_reserved_sharp(LEXTEXT, LEXLENG);
143 		switch (last_directive) {
144 		case 0:
145 			yy_push_state(CPP_COMMENT);
146 			break;
147 		case SHARP_DEFINE:
148 			yy_push_state(PREPROCESSOR_LINE);
149 			return ASM_DEFINE;
150 		case SHARP_UNDEF:
151 			yy_push_state(PREPROCESSOR_LINE);
152 			return ASM_UNDEF;
153 		default:
154 			yy_push_state(PREPROCESSOR_LINE);
155 			return ASM_DIRECTIVE;
156 		}
157 	}
158 	^[ \t]*\# {
159 		last_directive = 0;
160 		yy_push_state(PREPROCESSOR_LINE);
161 		return ASM_DIRECTIVE;
162 	}
163 	call|jsr	{ return ASM_CALL; }
164 	\.macro|macro	{ return ASM_MACRO; }
165 	\.equ|equ	{ return ASM_EQU; }
166 	^(ENTRY|ALTENTRY|NENTRY|GLOBAL_ENTRY|JSBENTRY|C_SYMBOL_NAME|C_ENTRY) {
167 		ADD_SYM(LEXTEXT, LEXLINENO);
168 		return ASM_ENTRY;
169 	}
170 	EXT|SYMBOL_NAME|C_LABEL {
171 		ADD_SYM(LEXTEXT, LEXLINENO);
172 		return ASM_EXT;
173 	}
174 	^{WORD}		{ ADD_SYM(LEXTEXT, LEXLINENO); return ASM_LABEL; }
175 }
176 
177 <PREPROCESSOR_LINE>{
178 	{WORD} {
179 		switch (last_directive) {
180 		case SHARP_IF:
181 		case SHARP_ELIF:
182 			if (strcmp(LEXTEXT, "defined") == 0)
183 				break;
184 			/* FALLTHROUGH */
185 		case SHARP_IFDEF:
186 		case SHARP_IFNDEF:
187 			PUT(PARSER_REF_SYM, LEXTEXT, LEXLINENO);
188 			break;
189 		default:
190 			ADD_SYM(LEXTEXT, LEXLINENO);
191 			return ASM_SYMBOL;
192 		}
193 	}
194 	\n		{ yy_pop_state(); return '\n'; }
195 }
196 
197 {WORD}		{ ADD_SYM(LEXTEXT, LEXLINENO); return ASM_SYMBOL; }
198 
199 \\\n
200 \n		{ return '\n'; }
201 .		{ return LEXTEXT[0]; }
202 
203 %%
204 
205 void
206 asm_initscan(void)
207 {
208 	BEGIN(INITIAL);
209 	LEXRESTART(NULL);
210 	LEXLINENO = 1;
211 }
212