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
|
%{
#define excludeLexer
#include "LuaSL_LSL_tree.h"
#include <stdio.h>
void comment(yyscan_t yyscanner);
void count(char *text);
#ifdef LUASL_DEBUG
#undef ECHO
#define ECHO count(yytext); printf ("[%s]\n", yytext)
#else
#undef ECHO
#define ECHO count(yytext)
#endif
%}
%option reentrant never-interactive batch
%option bison-bridge yylineno 8bit
%option noreject noyymore
%option backup debug perf-report perf-report verbose warn
%option align full
HEX [[:xdigit:]]
INTEGER [[:digit:]]+
EXPONANT [eE][+-]?{INTEGER}
FLOAT {INTEGER}("."{INTEGER})?{EXPONANT}?
CHAR '(\\.|[^\\'\n])+'
STRING \"(\\.|[^\\"\n])*\"
NAME [[:alpha:]](_|[[:alpha:]]|[[:digit:]])*
%%
/* The order here is important, in mysterious ways. The more specific the lower in case of ambiguities like "floats contain integers". I think, not tested that well yet. */
/* White space. */
[[:space:]]+ %{ ECHO; /* yylval->spaceValue = strdup(yytext); return LSL_SPACE; */ %}
"/*" %{ ECHO; comment(yyscanner); %}
"//"[^\n]* %{ ECHO; /* consume //-comment */ %}
/* Operations. */
"&&" { ECHO; return LSL_BOOL_AND; }
"||" { ECHO; return LSL_BOOL_OR; }
"|" { ECHO; return LSL_BIT_OR; }
"^" { ECHO; return LSL_BIT_XOR; }
"&" { ECHO; return LSL_BIT_AND; }
"!=" { ECHO; return LSL_NOT_EQUAL; }
"==" { ECHO; return LSL_EQUAL; }
">=" { ECHO; return LSL_GREATER_EQUAL; }
"<=" { ECHO; return LSL_LESS_EQUAL; }
">" { ECHO; return LSL_GREATER_THAN; }
"<" { ECHO; return LSL_LESS_THAN; }
">>" { ECHO; return LSL_RIGHT_SHIFT; }
"<<" { ECHO; return LSL_LEFT_SHIFT; }
"+" { ECHO; return LSL_ADD; }
"-" { ECHO; return LSL_SUBTRACT; }
"*" { ECHO; return LSL_MULTIPLY; }
"%" { ECHO; return LSL_MODULO; }
"/" { ECHO; return LSL_DIVIDE; }
"!" { ECHO; return LSL_BOOL_NOT; }
"~" { ECHO; return LSL_BIT_NOT; }
/* "<" { ECHO; return LSL_ANGLE_OPEN; } */
/* ">" { ECHO; return LSL_ANGLE_CLOSE; } */
"[" { ECHO; return LSL_BRACKET_OPEN; }
"]" { ECHO; return LSL_BRACKET_CLOSE; }
"(" { ECHO; return LSL_PARENTHESIS_OPEN; }
")" { ECHO; return LSL_PARENTHESIS_CLOSE; }
"+=" { ECHO; return LSL_ASSIGNMENT_ADD; }
"-=" { ECHO; return LSL_ASSIGNMENT_SUBTRACT; }
"*=" { ECHO; return LSL_ASSIGNMENT_MULTIPLY; }
"%=" { ECHO; return LSL_ASSIGNMENT_MODULO; }
"/=" { ECHO; return LSL_ASSIGNMENT_DIVIDE; }
"=" { ECHO; return LSL_ASSIGNMENT_PLAIN; }
"." { ECHO; return LSL_DOT; }
"--" { ECHO; return LSL_DECREMENT_PRE; }
"++" { ECHO; return LSL_INCREMENT_PRE; }
"," { ECHO; return LSL_COMMA; }
/* Types. */
{INTEGER} %{ ECHO; yylval->integerValue = atoi(yytext); return LSL_INTEGER; %}
{FLOAT} %{ ECHO; yylval->floatValue = atof(yytext); return LSL_FLOAT; %}
/* Type keywords. */
"float" %{ ECHO; return LSL_TYPE_FLOAT; %}
"integer" %{ ECHO; return LSL_TYPE_INTEGER; %}
"key" %{ ECHO; return LSL_TYPE_KEY; %}
"list" %{ ECHO; return LSL_TYPE_LIST; %}
"quaternion" %{ ECHO; return LSL_TYPE_ROTATION; %}
"rotation" %{ ECHO; return LSL_TYPE_ROTATION; %}
"string" %{ ECHO; return LSL_TYPE_STRING; %}
"vector" %{ ECHO; return LSL_TYPE_VECTOR; %}
/* Statement keywords. */
"do" %{ ECHO; return LSL_DO; %}
"for" %{ ECHO; return LSL_FOR; %}
"else" %{ ECHO; return LSL_ELSE; %}
"if" %{ ECHO; return LSL_IF; %}
"jump" %{ ECHO; return LSL_JUMP; %}
"return" %{ ECHO; return LSL_RETURN; %}
"state" %{ ECHO; return LSL_STATE_CHANGE; %}
"while" %{ ECHO; return LSL_WHILE; %}
{NAME} %{ ECHO; /* yylval->nameValue = strdup(yytext); return LSL_NAME; */ %}
/* Other symbols. */
"@" %{ ECHO; return LSL_LABEL; %}
"{" %{ ECHO; return LSL_BLOCK_OPEN; %}
"}" %{ ECHO; return LSL_BLOCK_CLOSE; %}
";" { ECHO; return LSL_STATEMENT; }
<<EOF>> { yyterminate(); }
/* Everything else */
. %{ ECHO; printf(" unexpected character.\n"); %}
%%
void comment(yyscan_t yyscanner)
{
char c, prev = 0;
while ((c = input(yyscanner)) != 0) /* (EOF maps to 0) */
{
if (c == '/' && prev == '*')
return;
prev = c;
}
yyerror("unterminated comment");
}
int column = 0;
int line = 0;
void count(char *text)
{
int i;
for (i = 0; text[i] != '\0'; i++)
if (text[i] == '\n')
{
column = 0;
line++;
}
else if (text[i] == '\t')
column += 8 - (column % 8);
else
column++;
}
int yyerror(const char *msg)
{
fprintf(stderr, "Parser error on line %d, column %d: %s\n", line, column, msg);
return 0;
}
int yywrap(yyscan_t yyscanner)
{
#ifdef FLEX_SCANNER
#ifndef LL_WINDOWS
// Get gcc to stop complaining about lack of use of yyunput and input.
(void) yyunput;
#endif
#endif
// TODO - If we are getting files from stdin, or multiple -f arguments, we should loop through them and return 0. Return 1 when there are no more files.
return(1);
}
|