~ubuntu-branches/ubuntu/hardy/dicelab/hardy

« back to all changes in this revision

Viewing changes to par.y

  • Committer: Bazaar Package Importer
  • Author(s): Robert Lemmen
  • Date: 2007-12-10 17:06:15 UTC
  • Revision ID: james.westby@ubuntu.com-20071210170615-q1av8grz0vjiv397
Tags: upstream-0.5
ImportĀ upstreamĀ versionĀ 0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%{
 
2
#include <stdio.h>
 
3
#include <assert.h>
 
4
#include <stdlib.h>
 
5
 
 
6
#include "util.h"
 
7
#include "tree.h"
 
8
 
 
9
int yylex();
 
10
int yyerror(char *s);
 
11
int yyget_lineno();
 
12
 
 
13
char *filename = "<stdin>";
 
14
 
 
15
extern int cmd_parse_tree;
 
16
extern int cmd_roll;
 
17
extern int cmd_rolleval;
 
18
extern int cmd_calc;
 
19
extern int cmd_count;
 
20
 
 
21
void list_quicksort(struct val_list **data, int start, int end) {
 
22
        if (end > start) {
 
23
                int i=start-1;
 
24
                int j = end;
 
25
                struct val_list *t;
 
26
                for(;;) {
 
27
                        while(data[++i]->values[0] < data[end]->values[0]);
 
28
                        while(data[--j >= 0 ? j : end]->values[0] > data[end]->values[0]);
 
29
                        if (i>=j)
 
30
                                break;
 
31
                        t = data[i];
 
32
                        data[i] = data[j];
 
33
                        data[j] = t;
 
34
 
 
35
                }
 
36
                t = data[i];
 
37
                data[i] = data[end];
 
38
                data[end] = t;
 
39
 
 
40
                list_quicksort(data, start, i-1);
 
41
                list_quicksort(data, i+1, end);
 
42
        }
 
43
}
 
44
 
 
45
struct val_list *list_sort(struct val_list *list) {
 
46
        struct val_list *cl = list;
 
47
        // count the list
 
48
        int count = 0;
 
49
        while (cl) {
 
50
                count++;
 
51
                cl = cl->next;
 
52
        }
 
53
        // create an array
 
54
        struct val_list **hash = (struct val_list**)malloc(sizeof(struct val_list*) * count);
 
55
        int i = 0;
 
56
        cl = list;
 
57
        while (cl) {
 
58
                hash[i] = cl;
 
59
                cl = cl->next;
 
60
                i++;
 
61
        }
 
62
        // now sort the hash
 
63
        list_quicksort(hash, 0, count-1);
 
64
        for (i = 0; i < count-1; i++) {
 
65
                hash[i]->next = hash[i+1];
 
66
        }
 
67
        hash[count-1]->next = NULL;
 
68
        cl = hash[0];
 
69
        free(hash);
 
70
        return cl;
 
71
}
 
72
 
 
73
%}
 
74
%error-verbose
 
75
 
 
76
%union {
 
77
        int ival;
 
78
        char *tval;
 
79
        expression *expr;
 
80
}
 
81
 
 
82
%token <ival> NUMBER
 
83
%token <tval> VARIABLE
 
84
 
 
85
%token IN DO WHILE ELSE
 
86
%token RANGE
 
87
%right ','
 
88
%token EQ NE LT GT LE GE
 
89
%left '+' '-' '.'
 
90
%left '*' '/' '%'
 
91
%token SUM PROD COUNT LOW HIGH
 
92
%right '#'
 
93
%right '^'
 
94
%right DICE
 
95
 
 
96
%token PERM SORT REV DROP KEEP FIRST LAST LET FOREACH IF THEN
 
97
 
 
98
%type <expr> expr
 
99
%type <expr> scalar
 
100
%type <expr> list
 
101
%type <expr> filter
 
102
 
 
103
%%
 
104
 
 
105
input: pexpr
 
106
        | input ';' pexpr
 
107
        | input ';'
 
108
        ;
 
109
 
 
110
pexpr: expr { 
 
111
                if (cmd_parse_tree) {
 
112
                        printtree($1, 0); 
 
113
                }
 
114
                if (cmd_roll) {
 
115
                        int i;
 
116
                        struct symtab *st = NULL;
 
117
                        set_symtab($1, st);
 
118
                        struct roll_value *rv = roll($1);
 
119
                        for (i = 0; i < rv->count; i++) {
 
120
                                printf("%i ", rv->values[i]);
 
121
                        }
 
122
                        printf("\n");
 
123
                        free_roll(rv);
 
124
                }
 
125
                if (cmd_calc) {
 
126
                        struct symtab *st = NULL;
 
127
                        set_symtab($1, st);
 
128
                        set_ordering($1, caring);
 
129
                        struct val_list *vl = eval($1);
 
130
                        struct val_list *cl = vl;
 
131
                        cl = list_sort(cl);
 
132
                        while (cl) {
 
133
                                if (cl->count != 1) {
 
134
                                        yyerror("result is not scalar");
 
135
                                        break;
 
136
                                }
 
137
                                printf("%3i\t%0.6f\t\n", cl->values[0], cl->prob);
 
138
                                cl = cl->next;
 
139
                        }
 
140
                        list_free(vl);
 
141
                }
 
142
                if (cmd_rolleval) {
 
143
                        int i;
 
144
                        struct result_node *rl = NULL;
 
145
                        for (i = 0; i < cmd_count; i++) {
 
146
                                struct symtab *st = NULL;
 
147
                                set_symtab($1, st);
 
148
                                struct roll_value *rv = roll($1);
 
149
                                if (rv->count != 1) {
 
150
                                        yyerror("Result not a single value");
 
151
                                        free_roll(rv);
 
152
                                        break;
 
153
                                }
 
154
                                result_add(&rl, rv->values[0]);
 
155
                                free_roll(rv);
 
156
                        }
 
157
                        
 
158
                        struct result_node *cl = rl;
 
159
                        int sum = 0;
 
160
                        while (cl != NULL) {
 
161
                                sum += cl->prob;
 
162
                                cl = cl->next;
 
163
                        }
 
164
                        cl = rl;
 
165
                        while (cl != NULL) {
 
166
                                float fprob;
 
167
                                fprob = 1.0*cl->prob;
 
168
                                fprob /= sum;
 
169
                                printf("%3i\t%0.6f\n", cl->value, fprob);
 
170
                                cl = cl->next;
 
171
                        }
 
172
                }
 
173
        }
 
174
        ;
 
175
 
 
176
expr: scalar { $$ = $1; } 
 
177
        | list { $$ = $1; } 
 
178
        ;
 
179
 
 
180
scalar: NUMBER { $$ = number_create($1); }
 
181
        | VARIABLE { $$ = variable_create($1); }
 
182
        | '(' scalar ')' { $$ = $2; }
 
183
        | '-' scalar { $$ = negate_create($2); }
 
184
        | scalar '+' scalar { $$ = plus_create($1, $3); }
 
185
        | scalar '-' scalar { $$ = minus_create($1, $3); }
 
186
        | scalar '*' scalar { $$ = multi_create($1, $3); }
 
187
        | scalar '/' scalar { $$ = divi_create($1, $3); }
 
188
        | scalar '%' scalar { $$ = mod_create($1, $3); }
 
189
        | scalar '^' scalar { $$ = expo_create($1, $3); }
 
190
        | scalar '.' scalar { $$ = scat_create($1, $3); }
 
191
        | DICE scalar { $$ = dice_create($2); }
 
192
        | SUM expr { $$ = sum_create($2); }
 
193
        | PROD expr { $$ = prod_create($2); }
 
194
        | COUNT expr { $$ = count_create($2); }
 
195
        ;
 
196
 
 
197
list: scalar '#' expr { $$ = rep_create($1, $3); }
 
198
        | '(' list ')' { $$ = $2; }
 
199
        | '(' ')' { $$ = elist_create(); }
 
200
        | scalar RANGE scalar { $$ = range_create($1, $3); }
 
201
        | expr ',' expr { $$ = lcat_create($1, $3); }
 
202
        | PERM expr { $$ = perm_create($2); }
 
203
        | SORT expr { $$ = sort_create($2); }
 
204
        | REV expr { $$ = rev_create($2); }
 
205
        | filter { $$ = $1; }
 
206
        | IF expr THEN expr ELSE expr { $$ = ifthenelse_create($2, $4, $6); }
 
207
        | LET VARIABLE '=' expr IN expr { $$ = let_create($4, $6, $2); }
 
208
        | WHILE VARIABLE '=' expr DO expr { $$ = whiledo_create($4, $6, $2); }
 
209
        | FOREACH VARIABLE IN expr DO expr { $$ = foreach_create($4, $6, $2); }
 
210
        ;
 
211
 
 
212
filter: DROP FIRST expr expr { $$ = first_create($3, $4, drop); }
 
213
        | KEEP FIRST expr expr { $$ = first_create($3, $4, keep); }
 
214
        | FIRST expr expr { $$ = first_create($2, $3, keep); }
 
215
        | DROP LAST expr expr { $$ = last_create($3, $4, drop); }
 
216
        | KEEP LAST expr expr { $$ = last_create($3, $4, keep); }
 
217
        | LAST expr expr { $$ = last_create($2, $3, keep); }
 
218
        | DROP HIGH expr expr { $$ = high_create($3, $4, drop); }
 
219
        | KEEP HIGH expr expr { $$ = high_create($3, $4, keep); }
 
220
        | HIGH expr expr { $$ = high_create($2, $3, keep); }
 
221
        | DROP LOW expr expr { $$ = low_create($3, $4, drop); }
 
222
        | KEEP LOW expr expr { $$ = low_create($3, $4, keep); }
 
223
        | LOW expr expr { $$ = low_create($2, $3, keep); }
 
224
        | DROP EQ expr expr { $$ = comparison_create($3, $4, drop, eq); }
 
225
        | KEEP EQ expr expr { $$ = comparison_create($3, $4, keep, eq); }
 
226
        | EQ expr expr { $$ = comparison_create($2, $3, keep, eq); }
 
227
        | DROP NE expr expr { $$ = comparison_create($3, $4, drop, ne); }
 
228
        | KEEP NE expr expr { $$ = comparison_create($3, $4, keep, ne); }
 
229
        | NE expr expr { $$ = comparison_create($2, $3, keep, ne); }
 
230
        | DROP GT expr expr { $$ = comparison_create($3, $4, drop, gt); }
 
231
        | KEEP GT expr expr { $$ = comparison_create($3, $4, keep, gt); }
 
232
        | GT expr expr { $$ = comparison_create($2, $3, keep, gt); }
 
233
        | DROP LT expr expr { $$ = comparison_create($3, $4, drop, lt); }
 
234
        | KEEP LT expr expr { $$ = comparison_create($3, $4, keep, lt); }
 
235
        | LT expr expr { $$ = comparison_create($2, $3, keep, lt); }
 
236
        | DROP GE expr expr { $$ = comparison_create($3, $4, drop, ge); }
 
237
        | KEEP GE expr expr { $$ = comparison_create($3, $4, keep, ge); }
 
238
        | GE expr expr { $$ = comparison_create($2, $3, keep, ge); }
 
239
        | DROP LE expr expr { $$ = comparison_create($3, $4, drop, le); }
 
240
        | KEEP LE expr expr { $$ = comparison_create($3, $4, keep, le); }
 
241
        | LE expr expr { $$ = comparison_create($2, $3, keep, le); }
 
242
        ;
 
243
%%
 
244
 
 
245
int yyerror(char *s) {
 
246
        fprintf(stderr, "%s:%li %s\n", yycurrfilename(), yycurrlinenum(), s);
 
247
        return (1);
 
248
}
 
249
 
 
250
long yycurrlinenum() {
 
251
        return yyget_lineno();
 
252
}
 
253
 
 
254
char *yycurrfilename() {
 
255
        return filename;
 
256
}
 
257
 
 
258
void yynodefailed() {
 
259
        exit(1);
 
260
}