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
|
%include {
#include "LuaSL_LSL_tree.h"
}
%extra_argument {LuaSL_yyparseParam *param}
%stack_size 256
%token_type {LSL_Leaf *}
%default_type {LSL_Leaf *}
%token_destructor {burnLeaf($$);}
program ::= script LSL_SCRIPT(A). { A->left = param->ast; param->ast = A; } // Lemon does not like the start symbol to be on the RHS, so give it a dummy one.
%right LSL_BOOL_AND.
expr(A) ::= expr(B) LSL_BOOL_AND(C) expr(D). { A = addOperation(B, C, D); }
%right LSL_BOOL_OR.
expr(A) ::= expr(B) LSL_BOOL_OR(C) expr(D). { A = addOperation(B, C, D); }
%left LSL_BIT_AND LSL_BIT_XOR LSL_BIT_OR.
expr(A) ::= expr(B) LSL_BIT_OR(C) expr(D). { A = addOperation(B, C, D); }
expr(A) ::= expr(B) LSL_BIT_XOR(C) expr(D). { A = addOperation(B, C, D); }
expr(A) ::= expr(B) LSL_BIT_AND(C) expr(D). { A = addOperation(B, C, D); }
%right LSL_EQUAL LSL_NOT_EQUAL.
expr(A) ::= expr(B) LSL_NOT_EQUAL(C) expr(D). { A = addOperation(B, C, D); }
expr(A) ::= expr(B) LSL_EQUAL(C) expr(D). { A = addOperation(B, C, D); }
%right LSL_LESS_THAN LSL_GREATER_THAN LSL_LESS_EQUAL LSL_GREATER_EQUAL.
expr(A) ::= expr(B) LSL_GREATER_EQUAL(C) expr(D). { A = addOperation(B, C, D); }
expr(A) ::= expr(B) LSL_LESS_EQUAL(C) expr(D). { A = addOperation(B, C, D); }
expr(A) ::= expr(B) LSL_GREATER_THAN(C) expr(D). { A = addOperation(B, C, D); }
expr(A) ::= expr(B) LSL_LESS_THAN(C) expr(D). { A = addOperation(B, C, D); }
%left LSL_LEFT_SHIFT LSL_RIGHT_SHIFT.
expr(A) ::= expr(B) LSL_RIGHT_SHIFT(C) expr(D). { A = addOperation(B, C, D); }
expr(A) ::= expr(B) LSL_LEFT_SHIFT(C) expr(D). { A = addOperation(B, C, D); }
%left LSL_SUBTRACT LSL_ADD LSL_CONCATENATE.
expr(A) ::= expr(B) LSL_ADD(C) expr(D). { A = addOperation(B, C, D); }
expr(A) ::= expr(B) LSL_SUBTRACT(C) expr(D). { A = addOperation(B, C, D); }
%left LSL_DIVIDE LSL_MODULO LSL_MULTIPLY LSL_DOT_PRODUCT LSL_CROSS_PRODUCT.
expr(A) ::= expr(B) LSL_MULTIPLY(C) expr(D). { A = addOperation(B, C, D); }
expr(A) ::= expr(B) LSL_MODULO(C) expr(D). { A = addOperation(B, C, D); }
expr(A) ::= expr(B) LSL_DIVIDE(C) expr(D). { A = addOperation(B, C, D); }
%right LSL_BIT_NOT LSL_BOOL_NOT LSL_NEGATION.
expr(A) ::= LSL_BIT_NOT(B) expr(C). { A = addOperation(NULL, B, C); }
expr(A) ::= LSL_BOOL_NOT(B) expr(C). { A = addOperation(NULL, B, C); }
expr(A) ::= LSL_SUBTRACT(B) expr(C). [LSL_NEGATION] { A = addOperation(NULL, B, C); }
%right LSL_TYPECAST_OPEN LSL_TYPECAST_CLOSE.
%nonassoc LSL_TYPE_FLOAT LSL_TYPE_INTEGER LSL_TYPE_KEY LSL_TYPE_LIST LSL_TYPE_ROTATION LSL_TYPE_STRING LSL_TYPE_VECTOR.
%left LSL_ANGLE_OPEN LSL_ANGLE_CLOSE.
%nonassoc LSL_BRACKET_OPEN LSL_BRACKET_CLOSE.
%nonassoc LSL_PARENTHESIS_OPEN LSL_PARENTHESIS_CLOSE LSL_EXPRESSION.
expr(A) ::= LSL_PARENTHESIS_OPEN(B) expr(C) LSL_PARENTHESIS_CLOSE(D). { A = addParenthesis(B, C, D); }
expr(A) ::= LSL_PARENTHESIS_OPEN(B) LSL_TYPE_FLOAT(C) LSL_PARENTHESIS_CLOSE(D). { A = addTypecast(B, C, D); }
expr(A) ::= LSL_PARENTHESIS_OPEN(B) LSL_TYPE_INTEGER(C) LSL_PARENTHESIS_CLOSE(D). { A = addTypecast(B, C, D); }
expr(A) ::= LSL_PARENTHESIS_OPEN(B) LSL_TYPE_KEY(C) LSL_PARENTHESIS_CLOSE(D). { A = addTypecast(B, C, D); }
expr(A) ::= LSL_PARENTHESIS_OPEN(B) LSL_TYPE_LIST(C) LSL_PARENTHESIS_CLOSE(D). { A = addTypecast(B, C, D); }
expr(A) ::= LSL_PARENTHESIS_OPEN(B) LSL_TYPE_ROTATION(C) LSL_PARENTHESIS_CLOSE(D). { A = addTypecast(B, C, D); }
expr(A) ::= LSL_PARENTHESIS_OPEN(B) LSL_TYPE_STRING(C) LSL_PARENTHESIS_CLOSE(D). { A = addTypecast(B, C, D); }
expr(A) ::= LSL_PARENTHESIS_OPEN(B) LSL_TYPE_VECTOR(C) LSL_PARENTHESIS_CLOSE(D). { A = addTypecast(B, C, D); }
%right LSL_ASSIGNMENT_CONCATENATE LSL_ASSIGNMENT_ADD LSL_ASSIGNMENT_SUBTRACT LSL_ASSIGNMENT_MULTIPLY LSL_ASSIGNMENT_MODULO LSL_ASSIGNMENT_DIVIDE LSL_ASSIGNMENT_PLAIN.
%right LSL_DOT.
%right LSL_DECREMENT_PRE LSL_INCREMENT_PRE LSL_DECREMENT_POST LSL_INCREMENT_POST.
%nonassoc LSL_COMMA.
%nonassoc LSL_FLOAT.
expr(A) ::= LSL_FLOAT(B). { B->basicType = OT_float; A = B; }
%nonassoc LSL_INTEGER.
expr(A) ::= LSL_INTEGER(B). { B->basicType = OT_integer; A = B; }
%nonassoc LSL_KEY.
%nonassoc LSL_LIST.
%nonassoc LSL_ROTATION.
%nonassoc LSL_STRING.
%nonassoc LSL_VECTOR.
%nonassoc LSL_DO LSL_FOR LSL_ELSE LSL_ELSE_IF LSL_IF LSL_JUMP LSL_RETURN LSL_STATE_CHANGE LSL_WHILE.
%nonassoc LSL_LABEL.
%nonassoc LSL_STATEMENT.
statement(A) ::= expr(B) LSL_STATEMENT(D). { A = addStatement(D, LSL_EXPRESSION, B); }
%nonassoc LSL_IDENTIFIER LSL_SCRIPT.
script ::= script statement(A). { A->left = param->ast; param->ast = A; }
script ::= statement(A). { A->left = param->ast; param->ast = A; }
%nonassoc LSL_BLOCK_OPEN LSL_BLOCK_CLOSE.
%nonassoc LSL_PARAMETER LSL_FUNCTION LSL_STATE.
%nonassoc LSL_SPACE LSL_COMMENT LSL_COMMENT_LINE LSL_UNKNOWN.
%parse_accept {printf("Parsing complete.\n");}
%parse_failure {fprintf(stderr,"Giving up. Parser is hopelessly lost!\n");}
%stack_overflow {fprintf(stderr,"Giving up. Parser stack overflow @ line %04d column %04d\n", yypMinor->yy0->line, yypMinor->yy0->column);} // Gotta love consistancy, if it ever happens.
%syntax_error {fprintf(stderr,"Syntax error @ line %04d column %04d\n", yyminor.yy0->line, yyminor.yy0->column);}
/* Undocumented shit that might be useful later. Pffft
** The next table maps tokens into fallback tokens. If a construct
** like the following:
**.
** %fallback ID X Y Z.
**
** appears in the grammar, then ID becomes a fallback token for X, Y,
** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
** but it does not parse, the type of the token is changed to ID and
** the parse is retried before an error is thrown.
*/
|