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 196 197
|
/* $Id$
* vim:tabstop=8 shiftwidth=8 textwidth=72:
* 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"
#include "fauhdlstring.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 = fauhdlstrdup(yytext,
instance->callbacks.malloc);
return t_AnnotateName;
}
<ANNOTATION_SPEC>{a_string} {
yylval.text = fauhdlstrdup(&yytext[1],
instance->callbacks.malloc);
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 = fauhdlstrdup(yytext,
instance->callbacks.malloc);
/* drop trailing ":" */
yylval.text[strlen(yylval.text) - 1] = '\0';
return t_Label;
}
{identifier} { yylval.text = fauhdlstrdup(yytext,
instance->callbacks.malloc);
return t_Identifier;
}
{reference} { /* remove quotes */
yylval.text = fauhdlstrdup(&yytext[1],
instance->callbacks.malloc);
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 = fauhdlstrdup(&yytext[1],
instance->callbacks.malloc);
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;
}
|