3
* Copyright (C) 2002 Laird Breyer
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
* Author: Laird Breyer <laird@lbreyer.com>
30
extern int current_lineno;
31
extern int yylex(void);
32
extern void reset_lexer();
33
extern void lexer_prepare_string(char *buf);
34
extern void lexer_free_string();
39
void set_loss_and_increment(real_value_t v);
40
int parse_loss_vec(category_count_t i, char *buf);
41
int parse_risk_spec(FILE *input);
43
void add_prior_weight(real_value_t w);
44
void add_cat_name(char *n);
45
void attach_cat_vec(char *n, char *r, char *v);
47
category_count_t x, y;
60
%token <numval> tNUMBER
61
%token <numval> tMATCH
62
%token <numval> tCOMPLEXITY
64
%token <strval> tREGEX
67
%type <numval> catvec priorvec
68
%type <numval> formula
69
%type <strval> multivec
80
spec: catlist priorlist lossmat
84
catlist: tCATEGORIES '{' catvec '}'
87
catvec: tNAME { add_cat_name($1); }
88
| catvec ',' tNAME { add_cat_name($3); }
91
priorlist: tPRIOR '{' priorvec '}'
94
priorvec: tNUMBER { add_prior_weight($1); }
95
| priorvec ',' tNUMBER { add_prior_weight($3); }
98
lossmat: tLOSS '{' multivec '}'
101
multivec: tREGEX tNAME tVEC { attach_cat_vec($2,$1,$3); }
102
| multivec tREGEX tNAME tVEC { attach_cat_vec($3,$2,$4); }
105
flist: formula { set_loss_and_increment($1); }
106
| flist ',' formula { set_loss_and_increment($3); }
109
formula: tNUMBER { $$ = log($1); }
110
| tMATCH { $$ = log(spec.loss_list[x]->sm[(int)$1]); }
111
| tCOMPLEXITY { $$ = log(spec.complexity[x]); }
112
| formula '+' formula { $$ = log(exp($1) + exp($3)); }
113
| formula '-' formula { $$ = log(exp($1) - exp($3)); }
114
| formula '*' formula { $$ = $1 + $3; }
115
| formula '/' formula { $$ = $1 - $3; }
116
| formula '^' formula { $$ = $1 * exp($3); }
117
| '(' formula ')' { $$ = $2; }
118
| tEXP '(' formula ')' { $$ = exp($3); }
119
| tLOG '(' formula ')' { $$ = log($3); }
124
void set_loss_and_increment(real_value_t v) {
126
fprintf(stderr, "error: negative losses not supported (%s,%s)\n",
127
spec.catname[x], spec.catname[y]);
130
spec.loss_matrix[x][y++] = v;
135
int parse_loss_vec(category_count_t i, char *buf) {
145
lexer_prepare_string(buf);
152
int parse_risk_spec(FILE *input) {
165
fprintf(stderr, "parse error at line %d before '%s'\n",
166
current_lineno, yytext);
170
void add_prior_weight(real_value_t w) {
172
fprintf(stderr, "error: prior can't have negative values (%f)\n", w);
174
} else if(spec.num_priors < MAX_CAT) {
175
spec.prior[spec.num_priors++] = log(w);
177
fprintf(stderr, "warning: maximum reached, prior weight ignored\n");
181
void add_cat_name(char *n) {
182
if(spec.num_cats < MAX_CAT) {
183
spec.catname[spec.num_cats++] = n;
185
fprintf(stderr, "warning: maximum reached, category ignored\n");
189
void attach_cat_vec(char *n, char *r, char *v) {
193
/* see if category name is known */
194
for( i = 0; i < spec.num_cats; i++ ) {
195
if( strcmp(spec.catname[i], n) == 0 ) {
200
if( i < spec.num_cats ) {
202
/* create a new LossVector */
203
p = malloc(sizeof(LossVector));
210
"error: couldn't allocate memory needed for loss matrix\n");
214
/* add this vector spec to the appropriate list */
215
if( spec.loss_list[i] == NULL ) {
216
spec.loss_list[i] = p;
218
for(q = spec.loss_list[i]; q->next != NULL; q = q->next);
223
fprintf(stderr, "error: encountered unknown category\n");