aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/LuaSL/LuaSL_lexer.l
diff options
context:
space:
mode:
Diffstat (limited to 'LuaSL/LuaSL_lexer.l')
-rw-r--r--LuaSL/LuaSL_lexer.l164
1 files changed, 164 insertions, 0 deletions
diff --git a/LuaSL/LuaSL_lexer.l b/LuaSL/LuaSL_lexer.l
new file mode 100644
index 0000000..85b2821
--- /dev/null
+++ b/LuaSL/LuaSL_lexer.l
@@ -0,0 +1,164 @@
1%{
2
3#define excludeLexer
4#include "LuaSL.h"
5
6int common(YYSTYPE *lval, char *text, int len, LuaSL_compiler *compiler, boolean checkIgnorable, int type);
7
8%}
9
10%option reentrant never-interactive batch
11%option bison-bridge 8bit
12%option noreject noyymore
13%option backup debug perf-report perf-report verbose warn
14%option align full
15%option extra-type="LuaSL_compiler *"
16
17HEX [[:xdigit:]]
18DECIMAL [[:digit:]]
19 /* LSL has no octal integer type. */
20INTEGER ({DECIMAL}+)|(0[xX]{HEX}+)
21EXPONANT [eE][+-]?{DECIMAL}+
22 /* Floats can be "0." or".0", but "." is not valid. At least in OpenSim. A single dot should be caught by the LSL_Dot rule first anyway.*/
23FLOAT {DECIMAL}*"."{DECIMAL}*{EXPONANT}?[fF]?
24 /* Variable identifiers can have these extra characters at the end or beginning, they will be ignored- #$`'\? */
25 /* Function identifiers can start with $ */
26IDENTIFIER (_|[[:alpha:]])(_|[[:alpha:]]|[[:digit:]])*
27CHAR '(\\.|[^\\'\n])+'
28KEY \"{HEX}{8}-{HEX}{4}-{HEX}{4}-{HEX}{4}-{HEX}{12}\"
29STRING \"(\\.|[^\\"\n])*\"
30
31%%
32
33 /* 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. */
34
35 /* Ignorables. */
36[[:space:]]+ %{ common(yylval, yytext, yyleng, yyextra, FALSE, LSL_SPACE); %}
37 /* Yes I know this will have problems with huge comments, just being simple to get it to work for now. */
38"/*"([^"*/"]*)"*/" %{ common(yylval, yytext, yyleng, yyextra, FALSE, LSL_COMMENT); %}
39"//"[^\n]* %{ common(yylval, yytext, yyleng, yyextra, FALSE, LSL_COMMENT_LINE); %}
40
41 /* Operations. */
42"&&" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BOOL_AND); }
43"||" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BOOL_OR); }
44"|" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BIT_OR); }
45"^" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BIT_XOR); }
46"&" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BIT_AND); }
47"!=" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_NOT_EQUAL); }
48"==" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_EQUAL); }
49">=" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_GREATER_EQUAL); }
50"<=" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_LESS_EQUAL); }
51">" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_GREATER_THAN); }
52"<" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_LESS_THAN); }
53">>" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_RIGHT_SHIFT); }
54"<<" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_LEFT_SHIFT); }
55"+" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_ADD); }
56"-" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_SUBTRACT); }
57"*" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_MULTIPLY); }
58"%" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_MODULO); }
59"/" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_DIVIDE); }
60"!" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BOOL_NOT); }
61"~" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BIT_NOT); }
62"[" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BRACKET_OPEN); }
63"]" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BRACKET_CLOSE); }
64"(" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_PARENTHESIS_OPEN); }
65")" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_PARENTHESIS_CLOSE); }
66"+=" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_ASSIGNMENT_ADD); }
67"-=" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_ASSIGNMENT_SUBTRACT); }
68"*=" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_ASSIGNMENT_MULTIPLY); }
69"%=" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_ASSIGNMENT_MODULO); }
70"/=" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_ASSIGNMENT_DIVIDE); }
71"=" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_ASSIGNMENT_PLAIN); }
72"." { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_DOT); }
73"--" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_DECREMENT_PRE); }
74"++" { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_INCREMENT_PRE); }
75"," { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_COMMA); }
76
77 /* Other symbols. */
78"@" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_LABEL); %}
79"{" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BLOCK_OPEN); %}
80"}" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BLOCK_CLOSE); %}
81";" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_STATEMENT); %}
82
83 /* Type keywords. */
84"float" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_TYPE_FLOAT); %}
85"integer" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_TYPE_INTEGER); %}
86"key" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_TYPE_KEY); %}
87"list" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_TYPE_LIST); %}
88"quaternion" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_TYPE_ROTATION); %}
89"rotation" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_TYPE_ROTATION); %}
90"string" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_TYPE_STRING); %}
91"vector" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_TYPE_VECTOR); %}
92
93 /* Statement keywords. */
94"default" %{ yylval->value.stringValue = eina_stringshare_add_length(yytext, yyleng); return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_DEFAULT); %}
95"do" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_DO); %}
96"for" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_FOR); %}
97"else" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_ELSE); %}
98"if" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_IF); %}
99"else"[[:space:]]+"if" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_ELSEIF); %} /* TODO - deal with people that slap a comment in between them. */
100"jump" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_JUMP); %}
101"return" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_RETURN); %}
102"state" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_STATE_CHANGE); %}
103"while" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_WHILE); %}
104
105{IDENTIFIER} %{ yylval->value.stringValue = eina_stringshare_add_length(yytext, yyleng); return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_IDENTIFIER); %}
106
107 /* Types. */
108{INTEGER} %{ yylval->value.stringValue = eina_stringshare_add_length(yytext, yyleng); return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_INTEGER); %}
109{FLOAT} %{ yylval->value.stringValue = eina_stringshare_add_length(yytext, yyleng); return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_FLOAT); %}
110{KEY} %{ yylval->value.stringValue = eina_stringshare_add_length(yytext, yyleng); return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_KEY); %}
111{STRING} %{ yylval->value.stringValue = eina_stringshare_add_length(yytext, yyleng); return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_STRING); %}
112
113<<EOF>> { return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_SCRIPT); }
114
115 /* Everything else */
116. %{ printf(" unexpected character.\n"); yylval->value.stringValue = eina_stringshare_add_length(yytext, yyleng); common(yylval, yytext, yyleng, yyextra, TRUE, LSL_UNKNOWN); %}
117
118%%
119
120int common(YYSTYPE *lval, char *text, int len, LuaSL_compiler *compiler, boolean checkIgnorable, int type)
121{
122 char *p;
123
124 lval->toKen = tokens[type - lowestToken];
125 lval->line = compiler->line;
126 lval->column = compiler->column;
127 lval->len = len;
128
129 for (p = text; *p; p++)
130 {
131 if ('\n' == *p)
132 {
133 compiler->line++;
134 compiler->column = 1;
135 }
136 else
137 compiler->column++;
138 }
139
140#if LUASL_DIFF_CHECK
141 if (checkIgnorable)
142 {
143 lval->ignorable = compiler->ignorable;
144 compiler->ignorable = eina_strbuf_new();
145 }
146 else
147 eina_strbuf_append_length(compiler->ignorable, text, len);
148#endif
149
150 return type;
151}
152
153int yywrap(yyscan_t yyscanner) // This as actually useless for our needs, as it is called BEFORE the last token is dealt with.
154{
155#ifdef FLEX_SCANNER
156 #ifndef LL_WINDOWS
157 // Get gcc to stop complaining about lack of use of yyunput and input.
158 (void) yyunput;
159 (void) input;
160 #endif
161#endif
162
163 return 1;
164}