aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/LuaSL/LuaSL_lemon_yaccer.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/LuaSL/LuaSL_lemon_yaccer.y')
-rw-r--r--src/LuaSL/LuaSL_lemon_yaccer.y275
1 files changed, 275 insertions, 0 deletions
diff --git a/src/LuaSL/LuaSL_lemon_yaccer.y b/src/LuaSL/LuaSL_lemon_yaccer.y
new file mode 100644
index 0000000..182789f
--- /dev/null
+++ b/src/LuaSL/LuaSL_lemon_yaccer.y
@@ -0,0 +1,275 @@
1%include
2{
3 #include "LuaSL.h"
4}
5
6%extra_argument {LuaSL_compiler *compiler}
7
8%stack_size 1024
9
10%token_type {LSL_Leaf *}
11%default_type {LSL_Leaf *}
12%token_destructor {burnLeaf($$);}
13%default_destructor {burnLeaf($$);}
14
15// The start symbol, just coz we need one.
16
17// Lemon does not like the start symbol to be on the RHS, so give it a dummy start symbol.
18program ::= script LSL_SCRIPT(A). { if (NULL != A) A->left = compiler->ast; compiler->ast = A; }
19
20// Various forms of "space". The lexer takes care of them for us.
21
22%nonassoc LSL_SPACE LSL_COMMENT LSL_COMMENT_LINE LSL_UNKNOWN.
23
24// Basic script structure.
25
26%nonassoc LSL_SCRIPT.
27script ::= script state(A). { if (NULL != A) A->left = compiler->ast; compiler->ast = A; }
28script ::= script functionBody(A). { if (NULL != A) A->left = compiler->ast; compiler->ast = A; }
29script ::= script statement(A). { if (NULL != A) A->left = compiler->ast; compiler->ast = A; }
30script ::= .
31
32// State definitions.
33
34%nonassoc LSL_BLOCK_OPEN LSL_BLOCK_CLOSE LSL_STATE.
35stateBlock(A) ::= beginBlock(L) functionList(B) LSL_BLOCK_CLOSE(R). { A = addBlock(compiler, L, B, R); }
36state(A) ::= LSL_DEFAULT(I) stateBlock(B). { A = addState(compiler, NULL, I, B); }
37state(A) ::= LSL_STATE_CHANGE(S) LSL_IDENTIFIER(I) stateBlock(B). { A = addState(compiler, S, I, B); }
38
39// Function definitions.
40
41%nonassoc LSL_PARAMETER LSL_PARAMETER_LIST LSL_FUNCTION.
42functionList(A) ::= functionList(B) functionBody(C). { A = collectStatements(compiler, B, C); }
43functionList(A) ::= functionBody(C). { A = collectStatements(compiler, NULL, C); }
44// No such thing as a function list with no functions.
45//functionList(A) ::= . { A = collectStatements(compiler, NULL, NULL); }
46
47functionBody(A) ::= function(F) block(B). { A = addFunctionBody(compiler, F, B); } // addFunctionBody returns an implied addStatement(compiler, NULL, F, NULL, F, NULL, NULL);
48
49parameterList(A) ::= parameterList(B) LSL_COMMA(C) parameter(D). { A = collectParameters(compiler, B, C, D); }
50parameterList(A) ::= parameter(D). { A = collectParameters(compiler, NULL, NULL, D); }
51parameterList(A) ::= . { A = collectParameters(compiler, NULL, NULL, NULL); }
52parameter(A) ::= type(B) LSL_IDENTIFIER(C). { A = addParameter(compiler, B, C); }
53function(A) ::= LSL_IDENTIFIER(C) LSL_PARENTHESIS_OPEN(D) parameterList(E) LSL_PARENTHESIS_CLOSE(F). { A = addFunction(compiler, NULL, C, D, E, F); }
54function(A) ::= type(B) LSL_IDENTIFIER(C) LSL_PARENTHESIS_OPEN(D) parameterList(E) LSL_PARENTHESIS_CLOSE(F). { A = addFunction(compiler, B, C, D, E, F); }
55
56// Blocks.
57
58block(A) ::= beginBlock(L) statementList(B) LSL_BLOCK_CLOSE(R). { A = addBlock(compiler, L, B, R); }
59
60// Various forms of statement.
61
62%nonassoc LSL_STATEMENT.
63statementList(A) ::= statementList(B) statement(C). { A = collectStatements(compiler, B, C); }
64// This causes infinite loops (and about 150 conflicts) with - if () single statement;
65//statementList(A) ::= statement(C). { A = collectStatements(compiler, NULL, C); }
66// Yes, you can have an empty block.
67statementList(A) ::= . { A = collectStatements(compiler, NULL, NULL); }
68
69%nonassoc LSL_DO LSL_FOR LSL_IF LSL_JUMP LSL_RETURN LSL_STATE_CHANGE LSL_WHILE.
70%nonassoc LSL_ELSE LSL_ELSEIF.
71statement(A) ::= LSL_DO(F) block(B) LSL_WHILE(W) LSL_PARENTHESIS_OPEN(L) expr(E) LSL_PARENTHESIS_CLOSE(R) LSL_STATEMENT(S). { A = addStatement(compiler, S, F, L, E, R, B, W); }
72statement(A) ::= LSL_FOR(F) LSL_PARENTHESIS_OPEN(L) expr(E0) LSL_STATEMENT(S0) expr(E1) LSL_STATEMENT(S1) expr(E2) LSL_PARENTHESIS_CLOSE(R) block(B). { A = addFor(compiler, NULL, F, L, E0, S0, E1, S1, E2, R, B); }
73statement(A) ::= LSL_FOR(F) LSL_PARENTHESIS_OPEN(L) expr(E0) LSL_STATEMENT(S0) expr(E1) LSL_STATEMENT(S1) expr(E2) LSL_PARENTHESIS_CLOSE(R) statement(S). { A = addFor(compiler, NULL, F, L, E0, S0, E1, S1, E2, R, S); }
74
75statement(A) ::= ifBlock(B). { A = B; }
76ifBlock(A) ::= ifBlock(B) elseIfBlock(E). { A = addIfElse(compiler, B, E); }
77ifBlock(A) ::= ifBlock(B) elseBlock(E). { A = addIfElse(compiler, B, E); }
78ifBlock(A) ::= LSL_IF(F) LSL_PARENTHESIS_OPEN(L) expr(E) LSL_PARENTHESIS_CLOSE(R) block(B). [LSL_ELSE] { A = addStatement(compiler, NULL, F, L, E, R, B, NULL); }
79ifBlock(A) ::= LSL_IF(F) LSL_PARENTHESIS_OPEN(L) expr(E) LSL_PARENTHESIS_CLOSE(R) statement(S). [LSL_ELSE] { A = addStatement(compiler, NULL, F, L, E, R, S, NULL); }
80elseIfBlock(A) ::= LSL_ELSEIF(F) LSL_PARENTHESIS_OPEN(L) expr(E) LSL_PARENTHESIS_CLOSE(R) block(B). [LSL_ELSEIF] { A = addStatement(compiler, NULL, F, L, E, R, B, NULL); }
81elseIfBlock(A) ::= LSL_ELSEIF(F) LSL_PARENTHESIS_OPEN(L) expr(E) LSL_PARENTHESIS_CLOSE(R) statement(S). [LSL_ELSEIF] { A = addStatement(compiler, NULL, F, L, E, R, S, NULL); }
82elseBlock(A) ::= LSL_ELSE(F) block(B). { A = addStatement(compiler, NULL, F, NULL, NULL, NULL, B, NULL); }
83elseBlock(A) ::= LSL_ELSE(F) statement(S). { A = addStatement(compiler, NULL, F, NULL, NULL, NULL, S, NULL); }
84
85statement(A) ::= LSL_JUMP(F) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, F, NULL, NULL, NULL, NULL, I); }
86statement(A) ::= LSL_RETURN(F) expr(E) LSL_STATEMENT(S). { A = addStatement(compiler, S, F, NULL, E, NULL, NULL, NULL); }
87statement(A) ::= LSL_RETURN(F) LSL_STATEMENT(S). { A = addStatement(compiler, S, F, NULL, NULL, NULL, NULL, NULL); }
88statement(A) ::= LSL_STATE_CHANGE(F) LSL_DEFAULT(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, F, NULL, NULL, NULL, NULL, I); }
89statement(A) ::= LSL_STATE_CHANGE(F) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, F, NULL, NULL, NULL, NULL, I); }
90statement(A) ::= LSL_WHILE(F) LSL_PARENTHESIS_OPEN(L) expr(E) LSL_PARENTHESIS_CLOSE(R) block(B). { A = addStatement(compiler, NULL, F, L, E, R, B, NULL); }
91statement(A) ::= LSL_WHILE(F) LSL_PARENTHESIS_OPEN(L) expr(E) LSL_PARENTHESIS_CLOSE(R) statement(S). { A = addStatement(compiler, NULL, F, L, E, R, S, NULL); }
92
93%nonassoc LSL_LABEL.
94statement(A) ::= LSL_LABEL(F) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, F, NULL, NULL, NULL, NULL, I); }
95
96beginBlock(A) ::= LSL_BLOCK_OPEN(B). { A = beginBlock(compiler, B); }
97
98// This might be bogus, or might be valid LSL, but it lets us test the expression parser by evaluating them.
99statement(A) ::= expr(E) LSL_STATEMENT(S). { A = addStatement(compiler, S, S, NULL, E, NULL, NULL, NULL); }
100
101// Various forms of expression.
102
103// Used for function call params, and list contents.
104exprList(A) ::= exprList(B) LSL_COMMA(C) expr(D). { A = collectArguments(compiler, B, C, D); }
105exprList(A) ::= expr(D). { A = collectArguments(compiler, NULL, NULL, D); }
106exprList(A) ::= . { A = collectArguments(compiler, NULL, NULL, NULL); }
107
108// Assignments and variable declarations.
109
110%right LSL_ASSIGNMENT_CONCATENATE LSL_ASSIGNMENT_ADD LSL_ASSIGNMENT_SUBTRACT LSL_ASSIGNMENT_MULTIPLY LSL_ASSIGNMENT_MODULO LSL_ASSIGNMENT_DIVIDE LSL_ASSIGNMENT_PLAIN.
111// Variables and dealing with them.
112
113expr(A) ::= identifier(B). { A = B; }
114
115// Yes, these can be expressions, and can happen in if statements and such. In Lua they are NOT expressions. sigh
116expr(A) ::= identifier(B) LSL_ASSIGNMENT_CONCATENATE(C) expr(D). { A = addOperation(compiler, B, C, D); }
117expr(A) ::= identifier(B) LSL_ASSIGNMENT_ADD(C) expr(D). { A = addOperation(compiler, B, C, D); }
118expr(A) ::= identifier(B) LSL_ASSIGNMENT_SUBTRACT(C) expr(D). { A = addOperation(compiler, B, C, D); }
119expr(A) ::= identifier(B) LSL_ASSIGNMENT_MULTIPLY(C) expr(D). { A = addOperation(compiler, B, C, D); }
120expr(A) ::= identifier(B) LSL_ASSIGNMENT_MODULO(C) expr(D). { A = addOperation(compiler, B, C, D); }
121expr(A) ::= identifier(B) LSL_ASSIGNMENT_DIVIDE(C) expr(D). { A = addOperation(compiler, B, C, D); }
122expr(A) ::= identifier(B) LSL_ASSIGNMENT_PLAIN(C) expr(D). { A = addOperation(compiler, B, C, D); }
123
124// Hmm think this can have commas seperating the assignment parts, or is that only in C?. If so, best to separate them when converting to Lua, as it uses that syntax for something else.
125// Well, not in OpenSim at least, nor in SL. So we are safe. B-)
126// On the other hand, it might be legal to have comma separated bits in a for loop - for ((i = 1), (j=1); ...
127statement(A) ::= type(T) LSL_IDENTIFIER(I) LSL_ASSIGNMENT_PLAIN(D) expr(E) LSL_STATEMENT(S). { A = addStatement(compiler, S, I, NULL, addVariable(compiler, T, I, D, E), NULL, NULL, I); }
128statement(A) ::= type(T) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, I, NULL, addVariable(compiler, T, I, NULL, NULL), NULL, NULL, I); }
129
130// Basic operators.
131
132%right LSL_BOOL_AND.
133expr(A) ::= expr(B) LSL_BOOL_AND(C) expr(D). { A = addOperation(compiler, B, C, D); }
134%right LSL_BOOL_OR.
135expr(A) ::= expr(B) LSL_BOOL_OR(C) expr(D). { A = addOperation(compiler, B, C, D); }
136
137%left LSL_BIT_AND LSL_BIT_XOR LSL_BIT_OR.
138expr(A) ::= expr(B) LSL_BIT_OR(C) expr(D). { A = addOperation(compiler, B, C, D); }
139expr(A) ::= expr(B) LSL_BIT_XOR(C) expr(D). { A = addOperation(compiler, B, C, D); }
140expr(A) ::= expr(B) LSL_BIT_AND(C) expr(D). { A = addOperation(compiler, B, C, D); }
141
142%right LSL_EQUAL LSL_NOT_EQUAL.
143expr(A) ::= expr(B) LSL_NOT_EQUAL(C) expr(D). { A = addOperation(compiler, B, C, D); }
144expr(A) ::= expr(B) LSL_EQUAL(C) expr(D). { A = addOperation(compiler, B, C, D); }
145%right LSL_LESS_THAN LSL_GREATER_THAN LSL_LESS_EQUAL LSL_GREATER_EQUAL.
146expr(A) ::= expr(B) LSL_GREATER_EQUAL(C) expr(D). { A = addOperation(compiler, B, C, D); }
147expr(A) ::= expr(B) LSL_LESS_EQUAL(C) expr(D). { A = addOperation(compiler, B, C, D); }
148expr(A) ::= expr(B) LSL_GREATER_THAN(C) expr(D). { A = addOperation(compiler, B, C, D); }
149expr(A) ::= expr(B) LSL_LESS_THAN(C) expr(D). { A = addOperation(compiler, B, C, D); }
150
151%left LSL_LEFT_SHIFT LSL_RIGHT_SHIFT.
152expr(A) ::= expr(B) LSL_RIGHT_SHIFT(C) expr(D). { A = addOperation(compiler, B, C, D); }
153expr(A) ::= expr(B) LSL_LEFT_SHIFT(C) expr(D). { A = addOperation(compiler, B, C, D); }
154
155%left LSL_SUBTRACT LSL_ADD LSL_CONCATENATE.
156expr(A) ::= expr(B) LSL_ADD(C) expr(D). { A = addOperation(compiler, B, C, D); }
157expr(A) ::= expr(B) LSL_SUBTRACT(C) expr(D). { A = addOperation(compiler, B, C, D); }
158%left LSL_DIVIDE LSL_MODULO LSL_MULTIPLY LSL_DOT_PRODUCT LSL_CROSS_PRODUCT.
159expr(A) ::= expr(B) LSL_MULTIPLY(C) expr(D). { A = addOperation(compiler, B, C, D); }
160expr(A) ::= expr(B) LSL_MODULO(C) expr(D). { A = addOperation(compiler, B, C, D); }
161expr(A) ::= expr(B) LSL_DIVIDE(C) expr(D). { A = addOperation(compiler, B, C, D); }
162
163%right LSL_BIT_NOT LSL_BOOL_NOT LSL_NEGATION.
164expr(A) ::= LSL_BIT_NOT(B) expr(C). { A = addOperation(compiler, NULL, B, C); }
165expr(A) ::= LSL_BOOL_NOT(B) expr(C). { A = addOperation(compiler, NULL, B, C); }
166expr(A) ::= LSL_SUBTRACT(B) expr(C). [LSL_NEGATION] { A = addOperation(compiler, NULL, B, C); }
167
168// Types, typecasts, and expression reordering.
169
170%right LSL_TYPECAST_OPEN LSL_TYPECAST_CLOSE.
171%nonassoc LSL_TYPE_FLOAT LSL_TYPE_INTEGER LSL_TYPE_KEY LSL_TYPE_LIST LSL_TYPE_ROTATION LSL_TYPE_STRING LSL_TYPE_VECTOR.
172type(A) ::= LSL_TYPE_FLOAT(B). { B->basicType = OT_float; A = B; }
173type(A) ::= LSL_TYPE_INTEGER(B). { B->basicType = OT_integer; A = B; }
174type(A) ::= LSL_TYPE_KEY(B). { B->basicType = OT_key; A = B; }
175type(A) ::= LSL_TYPE_LIST(B). { B->basicType = OT_list; A = B; }
176type(A) ::= LSL_TYPE_ROTATION(B). { B->basicType = OT_rotation; A = B; }
177type(A) ::= LSL_TYPE_STRING(B). { B->basicType = OT_string; A = B; }
178type(A) ::= LSL_TYPE_VECTOR(B). { B->basicType = OT_vector; A = B; }
179
180%left LSL_ANGLE_OPEN LSL_ANGLE_CLOSE.
181%nonassoc LSL_BRACKET_OPEN LSL_BRACKET_CLOSE.
182%nonassoc LSL_PARENTHESIS_OPEN LSL_PARENTHESIS_CLOSE LSL_EXPRESSION.
183
184expr(A) ::= LSL_PARENTHESIS_OPEN(B) expr(C) LSL_PARENTHESIS_CLOSE(D). { A = addParenthesis(B, C, LSL_EXPRESSION, D); }
185expr(A) ::= LSL_PARENTHESIS_OPEN(B) type(C) LSL_PARENTHESIS_CLOSE(D) expr(E). { A = addTypecast(B, C, D, E); }
186
187%right LSL_DOT LSL_IDENTIFIER LSL_FUNCTION_CALL LSL_VARIABLE.
188identifier(A) ::= identifier(I) LSL_DOT(D) LSL_IDENTIFIER(B). { A = checkVariable(compiler, I, D, B); }
189identifier(A) ::= LSL_IDENTIFIER(B). { A = checkVariable(compiler, B, NULL, NULL); }
190
191%right LSL_DECREMENT_PRE LSL_INCREMENT_PRE LSL_DECREMENT_POST LSL_INCREMENT_POST.
192expr(A) ::= identifier(B) LSL_DECREMENT_PRE(C). { A = addCrement(compiler, B, C, LSL_DECREMENT_POST); }
193expr(A) ::= identifier(B) LSL_INCREMENT_PRE(C). { A = addCrement(compiler, B, C, LSL_INCREMENT_POST); }
194expr(A) ::= LSL_DECREMENT_PRE(C) identifier(B). { A = addCrement(compiler, B, C, LSL_DECREMENT_PRE); }
195expr(A) ::= LSL_INCREMENT_PRE(C) identifier(B). { A = addCrement(compiler, B, C, LSL_INCREMENT_PRE); }
196
197// Function call.
198
199// Causes a conflict when exprList is empty with a function definition with no type and no parameters.
200expr(A) ::= LSL_IDENTIFIER(B) LSL_PARENTHESIS_OPEN(C) exprList(D) LSL_PARENTHESIS_CLOSE(E). { A = addFunctionCall(compiler, B, C, D, E); }
201
202%nonassoc LSL_COMMA.
203
204// Values.
205
206%nonassoc LSL_FLOAT.
207expr(A) ::= LSL_FLOAT(B). { A = addNumby(B); }
208%nonassoc LSL_INTEGER.
209expr(A) ::= LSL_INTEGER(B). { A = addNumby(B); }
210%nonassoc LSL_KEY.
211expr(A) ::= LSL_KEY(B). { B->basicType = OT_key; A = B; }
212%nonassoc LSL_LIST.
213expr(A) ::= LSL_BRACKET_OPEN(L) exprList(E) LSL_BRACKET_CLOSE(R). [LSL_BRACKET_OPEN] { A = addList(L, E, R); }
214%nonassoc LSL_ROTATION LSL_VECTOR.
215// Uses the same symbol for less than, greater than, and the rotation / vector delimiters.
216expr(A) ::= LSL_LESS_THAN(L) exprList(E) LSL_GREATER_THAN(R). [LSL_ANGLE_OPEN] { A = addRotVec(L, E, R); }
217%nonassoc LSL_STRING.
218expr(A) ::= LSL_STRING(B). { B->basicType = OT_string; A = B; }
219
220
221// Parser callbacks.
222
223%parse_accept
224{
225// gameGlobals *ourGlobals = compiler->game;
226
227// PI("Parsing complete.");
228}
229
230%parse_failure
231{
232 gameGlobals *ourGlobals = compiler->game;
233
234 compiler->script.bugCount++;
235 PE("Giving up. Parser is hopelessly lost!");
236}
237
238%stack_overflow
239{
240 gameGlobals *ourGlobals = compiler->game;
241
242 compiler->script.bugCount++;
243 PE("Giving up. Parser stack overflow @ line %d, column %d!", yypMinor->yy0->line, yypMinor->yy0->column); // Gotta love consistancy, if it ever happens.
244}
245
246%syntax_error
247{
248 gameGlobals *ourGlobals = compiler->game;
249
250 compiler->script.bugCount++;
251 PE("Syntax error @ line %d, column %d!", yyminor.yy0->line, yyminor.yy0->column);
252}
253
254
255/* Undocumented shit that might be useful later. Pffft
256
257** The next table maps tokens into fallback tokens. If a construct
258** like the following:
259**.
260** %fallback ID X Y Z.
261**
262** appears in the grammar, then ID becomes a fallback token for X, Y,
263** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
264** but it does not parse, the type of the token is changed to ID and
265** the parse is retried before an error is thrown.
266
267%wildcard
268%code
269
270%ifdef
271%endif
272%ifndef
273%endif
274
275*/