~ubuntu-branches/ubuntu/precise/dbacl/precise

« back to all changes in this revision

Viewing changes to src/risk-parser.y

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams
  • Date: 2005-05-07 12:59:53 UTC
  • Revision ID: james.westby@ubuntu.com-20050507125953-xzy2bwkb2qamglwm
Tags: upstream-1.9
ImportĀ upstreamĀ versionĀ 1.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%{
 
2
/* 
 
3
 * Copyright (C) 2002 Laird Breyer
 
4
 *  
 
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.
 
9
 * 
 
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.
 
14
 * 
 
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.
 
18
 * 
 
19
 * Author:   Laird Breyer <laird@lbreyer.com>
 
20
 */
 
21
 
 
22
#define YYDEBUG 0
 
23
#include <stdlib.h>
 
24
#include <stdio.h>
 
25
#include <string.h>
 
26
#include <math.h>
 
27
#include "bayesol.h"
 
28
  extern char *yytext;
 
29
  extern FILE *yyin;
 
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();
 
35
 
 
36
  extern Spec spec;
 
37
 
 
38
  /* defined here */
 
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);
 
42
  int yyerror(char *s);
 
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);
 
46
 
 
47
  category_count_t x, y;
 
48
 
 
49
  %}
 
50
 
 
51
%union {
 
52
  real_value_t numval;
 
53
  char *strval;
 
54
}
 
55
%token tCATEGORIES
 
56
%token tPRIOR
 
57
%token tLOSS
 
58
%token tEXP
 
59
%token tLOG
 
60
%token <numval> tNUMBER
 
61
%token <numval> tMATCH
 
62
%token <numval> tCOMPLEXITY
 
63
%token <strval> tNAME
 
64
%token <strval> tREGEX
 
65
%token <strval> tVEC
 
66
 
 
67
%type <numval> catvec priorvec
 
68
%type <numval> formula
 
69
%type <strval> multivec
 
70
 
 
71
%start spec
 
72
%left '+'
 
73
%left '-'
 
74
%left '*'
 
75
%left '/'
 
76
%right '^'
 
77
 
 
78
%%
 
79
 
 
80
spec:       catlist priorlist lossmat
 
81
          | flist
 
82
;
 
83
 
 
84
catlist:    tCATEGORIES '{' catvec '}'
 
85
;
 
86
 
 
87
catvec:     tNAME                             { add_cat_name($1); }
 
88
          | catvec ',' tNAME                  { add_cat_name($3); }
 
89
;
 
90
 
 
91
priorlist:  tPRIOR '{' priorvec '}' 
 
92
;
 
93
 
 
94
priorvec:   tNUMBER                           { add_prior_weight($1); }
 
95
          | priorvec ',' tNUMBER              { add_prior_weight($3); }
 
96
;
 
97
 
 
98
lossmat:    tLOSS '{' multivec '}'
 
99
;
 
100
 
 
101
multivec:   tREGEX tNAME tVEC                 { attach_cat_vec($2,$1,$3); }
 
102
          | multivec tREGEX tNAME tVEC        { attach_cat_vec($3,$2,$4); }
 
103
;
 
104
 
 
105
flist:      formula                          { set_loss_and_increment($1); }
 
106
          | flist ',' formula                { set_loss_and_increment($3); }
 
107
;
 
108
 
 
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); }
 
120
;
 
121
 
 
122
%%
 
123
 
 
124
void set_loss_and_increment(real_value_t v) {
 
125
  if( isnan(v) ) {
 
126
    fprintf(stderr, "error: negative losses not supported (%s,%s)\n",
 
127
            spec.catname[x], spec.catname[y]);
 
128
    exit(0);
 
129
  } else {
 
130
    spec.loss_matrix[x][y++] = v;
 
131
  }
 
132
}
 
133
 
 
134
 
 
135
int parse_loss_vec(category_count_t i, char *buf) {
 
136
  int result;
 
137
 
 
138
#if YYDEBUG
 
139
  yydebug = 1;
 
140
#endif
 
141
 
 
142
  reset_lexer();
 
143
  x = i;
 
144
  y = 0;
 
145
  lexer_prepare_string(buf);
 
146
  result = yyparse();
 
147
  lexer_free_string();
 
148
  return result;
 
149
}
 
150
 
 
151
 
 
152
int parse_risk_spec(FILE *input) {
 
153
 
 
154
#if YYDEBUG
 
155
  yydebug = 1;
 
156
#endif
 
157
 
 
158
  yyin = input;
 
159
  reset_lexer();
 
160
  return yyparse();
 
161
}
 
162
 
 
163
int yyerror(char *s)
 
164
 
165
  fprintf(stderr, "parse error at line %d before '%s'\n", 
 
166
          current_lineno, yytext); 
 
167
  return 0;
 
168
}
 
169
 
 
170
void add_prior_weight(real_value_t w) {
 
171
  if( w < 0.0 ) {
 
172
    fprintf(stderr, "error: prior can't have negative values (%f)\n", w);
 
173
    exit(0);
 
174
  } else if(spec.num_priors < MAX_CAT) {
 
175
    spec.prior[spec.num_priors++] = log(w);
 
176
  } else {
 
177
    fprintf(stderr, "warning: maximum reached, prior weight ignored\n");
 
178
  }
 
179
}
 
180
 
 
181
void add_cat_name(char *n) {
 
182
  if(spec.num_cats < MAX_CAT) { 
 
183
    spec.catname[spec.num_cats++] = n;
 
184
  } else {
 
185
    fprintf(stderr, "warning: maximum reached, category ignored\n");
 
186
  }            
 
187
}
 
188
 
 
189
void attach_cat_vec(char *n, char *r, char *v) {
 
190
  category_count_t i;
 
191
  LossVector *p, *q;
 
192
 
 
193
  /* see if category name is known */
 
194
  for( i = 0; i < spec.num_cats; i++ ) {
 
195
    if( strcmp(spec.catname[i], n) == 0 ) {
 
196
      break;
 
197
    }
 
198
  }
 
199
 
 
200
  if( i < spec.num_cats ) {
 
201
 
 
202
    /* create a new LossVector */
 
203
    p = malloc(sizeof(LossVector));
 
204
    if( p ) {
 
205
      p->re = r;
 
206
      p->ve = v;
 
207
      p->next = NULL;
 
208
    } else {
 
209
      fprintf(stderr, 
 
210
              "error: couldn't allocate memory needed for loss matrix\n");
 
211
      yyerror(NULL);
 
212
    }
 
213
 
 
214
    /* add this vector spec to the appropriate list */
 
215
    if( spec.loss_list[i] == NULL ) {
 
216
      spec.loss_list[i] = p;
 
217
    } else {
 
218
      for(q = spec.loss_list[i]; q->next != NULL; q = q->next);
 
219
      q->next = p;
 
220
    }
 
221
 
 
222
  } else {
 
223
    fprintf(stderr, "error: encountered unknown category\n");
 
224
    yyerror(NULL);
 
225
  }
 
226
}