summaryrefslogtreecommitdiff
path: root/interpreter/icscanner.l
blob: 759b18fe016e9b9cc7e0719e3d9063d95ef04b43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/* $Id: icscanner.l 4964 2010-10-18 12:55:39Z potyra $
 * vim:tabstop=8:shiftwidth=8:textwidth=72:encoding=utf8:
 * Scanner for intermediate code.
 *
 * Copyright (C) 2008-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

/* options */
%option case-insensitive
%option noyywrap
%option nounput
%option yylineno
%option noinput

/* start conditions */
/* tokens found in annotations, most will be thrown away */
%x ANNOTATION
/* any specification in the form name=int | name="string" found in
 * annotations */
%x ANNOTATION_SPEC

%{
#include <assert.h>
#include <stdlib.h>
#include "fauhdli_private.h"
#include "icparser.h"
#include "glue-log.h"

#define YY_DECL \
int yylex(\
	const struct fauhdli *instance, \
	const char *filename\
)
%}

char		[a-zA-Z]
id_char		[_a-zA-Z0-9]
digit		[0-9]
pos_number	{digit}{digit}*
number		-?{pos_number}
fraction	\.{pos_number}
integer 	\${number}L
real		\${number}{fraction}?F
identifier	{id_char}*{char}{id_char}*
ref_str		{id_char}*
reference	\"{ref_str}\"
label		{identifier}:
target		@{identifier}
ws_char		[ \t]
whitespace	{ws_char}*
register	%reg_{pos_number}
type_spec_i	i
type_spec_f	f
type_spec_p	p

a_name		{identifier}
a_string	{reference}
a_int		[0-9]+
a_spec_int	{a_name}={a_int}
a_spec_string	{a_name}={a_string}
a_spec		{a_spec_int}|{a_spec_string}

%%
<*>"\n"		{  yylloc.first_line++; }
<*>{whitespace}	{}
<ANNOTATION>"}" {	
			BEGIN(INITIAL);
		}
<ANNOTATION>{a_spec}	{
			BEGIN(ANNOTATION_SPEC);
			yyless(0);
		}
<ANNOTATION_SPEC>"=" {
			return t_AnnotateEqSym;
		}
<ANNOTATION_SPEC>{a_name} {
			yylval.text = strdup(yytext);
			assert(yylval.text != NULL);
			return t_AnnotateName;
		}
<ANNOTATION_SPEC>{a_string} {
			yylval.text = strdup(&yytext[1]);
			assert(yylval.text != NULL);
			yylval.text[strlen(yylval.text) - 1] = '\0';
			BEGIN(ANNOTATION);
			return t_AnnotateString;
		}
<ANNOTATION_SPEC>{a_int} {
			yylval.annotate_int = atoi(yytext);
			BEGIN(ANNOTATION);
			return t_AnnotateInt;
		}
<ANNOTATION>.	{ 	/* anything unmatched is ok in annotations as
			   well, and won't result in a token */
		}
"("		{	return t_LeftParen; }
")"		{	return t_RightParen; }
"["		{	return t_LeftBracket; }
"]"		{	return t_RightBracket; }
","		{ 	return t_Comma; }
":"		{	return t_Colon; }
":="		{ 	return t_ValAssign; }
"->"		{	return t_Arrow; }
;		{ 	return t_Semicolon; }
".registers"	{	return t_Registers; }
".text"		{ 	return t_CodeSegment; }
".stack"	{ 	return t_StackSegment; }
".transfer"	{	return t_TransferSegment; }
".types"	{	return t_TypeSegment; }
"{"		{	
			BEGIN(ANNOTATION);
		}
is		{	return t_IS; }
mov		{ 	return t_MOV; }
abort		{	return t_ABORT; }
add		{ 	return t_ADD; }
sub		{ 	return t_SUB; }
imul		{ 	return t_IMUL; }
div		{	return t_DIV; }
call		{ 	return t_CALL; }
return  	{ 	return t_RETURN; }
proc		{	return t_PROC; }
update  	{ 	return t_UPDATE; }
getsig		{	return t_GETSIG; }
gettime		{	return t_GETSIMTIME; }
jmp		{ 	return t_JMP; }
je		{ 	return t_JE; }
jb		{ 	return t_JB; }
jbe		{ 	return t_JBE; }
jne		{ 	return t_JNE; }
aoffset 	{ 	return t_AOFFSET; }
roffset 	{ 	return t_ROFFSET; }
data		{ 	return t_DATA; }
type		{ 	return t_TYPE; }
container	{ 	return t_CONTAINER; }
signal		{	return t_SIGNAL; }
driver		{ 	return t_DRIVER; }
variable	{	return t_VARIABLE; }
connect		{	return t_CONNECT; }
end		{	return t_END; }
begintr		{	return t_BEGINTRANSFER; }
endtr		{	return t_ENDTRANSFER; }
getparm		{	return t_GETPARAM; }
setparm		{	return t_SETPARAM; }
resolvedby	{	return t_RESOLVEDBY; }
suspend		{	return t_SUSPEND; }
wakeon		{	return t_WAKEON; }
wakeat		{	return t_WAKEAT; }
log		{	return t_LOG; }
{type_spec_i}	{	return t_TypeSpecInt; }
{type_spec_f}	{	return t_TypeSpecFloat; }
{type_spec_p}	{	return t_TypeSpecPointer; }
{register}	{	yylval.number = atol(&yytext[5]);
			return t_Register;
		}
{label}		{	yylval.text = strdup(yytext);
		  	assert(yylval.text != NULL);
			/* drop trailing ":" */
			yylval.text[strlen(yylval.text) - 1] = '\0';
		  	return t_Label; 
		}
{identifier}	{	yylval.text = strdup(yytext);
			assert(yylval.text != NULL);
			return t_Identifier;
		}
{reference}	{	/* remove quotes */
			yylval.text = strdup(&yytext[1]);
			assert(yylval.text != NULL);
			yylval.text[strlen(yylval.text) - 1] = '\0';
			return t_Reference;
		}
{integer}	{	
			yylval.univ_int = atoll(&yytext[1]);
			return t_Int; 
		}
{real}		{	yylval.univ_real = atof(&yytext[1]);
			return t_Float; 
		}
{pos_number}	{	yylval.univ_int = atoll(yytext);
			return t_PosNumber;
		}
{target}	{ 	yylval.text = strdup(&yytext[1]);
		  	assert(yylval.text != NULL);
		  	return t_Target; 
		}
.		{ 	
			instance->callbacks.log(
				FAUHDLI_LOG_ERROR, "fauhdli", "scanner",
				"%s:%d: invalid character '%c' in stream.\n",
				filename, yylineno, yytext[0]);
			return t_Invalid;
		}