~ubuntu-branches/ubuntu/raring/chemeq/raring

« back to all changes in this revision

Viewing changes to src/chemeq.y

  • Committer: Bazaar Package Importer
  • Author(s): Georges Khaznadar
  • Date: 2003-04-14 12:04:35 UTC
  • Revision ID: james.westby@ubuntu.com-20030414120435-osewh7q6iw8pqx3g
Tags: 1.2-1
* added the -M switch; features molecular weights calculation
* corrected the references to endl (using std::endl instead)
  closes: Bug#188906
  other incorrect references to cin, cout and cerr are due to a bad
  behavior of flex when used in c++ mode.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%{
 
2
/* inclusions, d�finition */
 
3
#include <string.h>
 
4
#include <stdlib.h>
 
5
#include <stdio.h>
 
6
#include <unistd.h>
 
7
#include <math.h>
 
8
#include "chemeq.h"
 
9
 
 
10
  int yylex();
 
11
  int yyerror(char * msg);
 
12
 
 
13
typedef struct{
 
14
  int i, d; /* integer numerator, denominator */
 
15
  double r;
 
16
  AtomeListe * al;
 
17
  Molec * m;
 
18
  Chemeq * cq;
 
19
  Membre * mb;
 
20
  char symb[4];
 
21
  moltype t;
 
22
  std::string s;
 
23
} yystype;
 
24
 
 
25
#define YYSTYPE yystype 
 
26
 
 
27
/* variables globales */
 
28
 
 
29
 yystype result;
 
30
 extern char * yytext;
 
31
 extern int position;
 
32
 int isequation;
 
33
 
 
34
%}
 
35
 
 
36
%token Atome
 
37
%token SpcPlus
 
38
%token Plus
 
39
%token Moins
 
40
%token Fleche
 
41
%token Int
 
42
%token Charge
 
43
%token Frac
 
44
%token Real
 
45
%token SpcLpar
 
46
%token Lpar
 
47
%token Rpar
 
48
%token Lsq
 
49
%token Rsq
 
50
%token Haut
 
51
%token Spc
 
52
%token Sol
 
53
%token Gas
 
54
%token Aqueous
 
55
%token Egal
 
56
 
 
57
%%
 
58
 
 
59
/* les r�gles */
 
60
but : chemeq cste{
 
61
  result=$1;
 
62
  result.cq->constante($2.s);
 
63
  result.cq->valeur($2.r);
 
64
  isequation=1;
 
65
}
 
66
| molec {
 
67
  result=$1;
 
68
  isequation=0;
 
69
}
 
70
;
 
71
 
 
72
cste : /* rien */ {$$.s = ""; $$.r = -1.0; /* valeur n�gative : non d�fini */}
 
73
| SpcLpar cste1 Rpar {$$ = $2;}
 
74
;
 
75
 
 
76
cste1 : spc01 nombre volt{$$.s = ""; $$.r = $2.r;}
 
77
| spc01 id spc01 Egal spc01 nombre volt{$$.s = $2.s; $$.r = $6.r;}
 
78
;
 
79
 
 
80
nombre : Real {$$.r=$1.r;}
 
81
| Int {$$.r=1.0*$1.i;}
 
82
| Plus spc01 Real{$$.r=$3.r;}
 
83
| Moins spc01 Real{$$.r=-$3.r;}
 
84
| Plus spc01 Int{$$.r=1.0*$3.i;}
 
85
| Moins spc01 Int{$$.r=-1.0*$3.i;}
 
86
;
 
87
 
 
88
volt : /* rien */
 
89
| spc01 Atome {if ($2.s != std::string("V")) yyerror ("only 'V' allowed as unit"); }
 
90
;
 
91
 
 
92
id : Atome {/* $$.s contient le nom */}
 
93
;
 
94
 
 
95
chemeq : membre Spc Fleche spc01 membre{
 
96
  $$.cq = new Chemeq($1.mb,$5.mb);
 
97
}
 
98
;
 
99
 
 
100
membre : membre SpcPlus spc01 molecs {
 
101
  $$.mb->push_back($4.m);
 
102
}
 
103
| molecs {
 
104
  $$.mb = new Membre;
 
105
  $$.mb->push_back($1.m);
 
106
}
 
107
;
 
108
 
 
109
molecs : Int spc01 molec {
 
110
  $$ = $3;
 
111
  $$.m->nombre($1.i);
 
112
}
 
113
| Frac spc01 molec {
 
114
  $$ = $3;
 
115
  $$.m->nombre($1.i,$1.d);
 
116
}
 
117
| molec{
 
118
  $$ = $1; 
 
119
}
 
120
;
 
121
 
 
122
spc01 : /*rien*/
 
123
| Spc
 
124
;
 
125
 
 
126
molec : composition0 typage{
 
127
  $$.m = new Molec($1.al,0); $$.m->typage($2.t);
 
128
}
 
129
| composition0 charge typage{
 
130
  $$.m = new Molec($1.al,$2.i);$$.m->typage($3.t);
 
131
}
 
132
;
 
133
 
 
134
 
 
135
composition0 : composition {$$.al=$1.al;}
 
136
| Lsq spc01 composition spc01 Rsq {$$.al=$3.al; $$.al->sq(1);}
 
137
;
 
138
 
 
139
typage : /* rien */ {$$.t = aqueous;}
 
140
| Aqueous {$$.t = aqueous;}
 
141
| Sol {$$.t = sol;}
 
142
| Gas {$$.t = gas;}
 
143
;
 
144
 
 
145
charge : Plus {$$.i=1;}
 
146
| Haut Plus {$$.i=1;}
 
147
| Haut Charge {$$.i=$2.i;}
 
148
| Moins{$$.i=-1;}
 
149
| Haut  Moins{$$.i=-1;}
 
150
;
 
151
 
 
152
groupe : Lpar composition Rpar {
 
153
  $$=$2; 
 
154
}
 
155
;
 
156
 
 
157
atome_general : groupe {
 
158
  $$.al = new AtomeListe("",0,0,$1.al);
 
159
}
 
160
| Atome{
 
161
  char buffer[25];
 
162
  if ($1.i==-2) { /* ce n'est pas un atome recens� */
 
163
    sprintf(buffer,"nonexistent atom : %s", $1.symb);
 
164
    yyerror(buffer);
 
165
  }
 
166
  $$.al = new AtomeListe($1.symb,$1.i);
 
167
}
 
168
;
 
169
 
 
170
composition : atome_general molecularite composition {
 
171
  $$ = $1;
 
172
  $$.al->setmolecularite($2.i);
 
173
  $$.al->setsuivant($3.al);
 
174
}
 
175
| atome_general molecularite{
 
176
  $$.al = $1.al;
 
177
  $$.al->setmolecularite($2.i);
 
178
}
 
179
;
 
180
 
 
181
molecularite : /*rien*/{
 
182
  $$.i=1;
 
183
}
 
184
| Int {
 
185
  $$=$1; 
 
186
}
 
187
;
 
188
 
 
189
%%
 
190
#include "chemlex.cc"
 
191
 
 
192
yyFlexLexer lexer;
 
193
 
 
194
int yylex(){
 
195
  return lexer.yylex();
 
196
}
 
197
 
 
198
/* le programme lui-m�me */
 
199
 
 
200
inline int yyerror(char * msg){
 
201
  fprintf(stderr, "ERROR %s at %d\n ", msg, position);
 
202
  exit(1);
 
203
}
 
204
 
 
205
void printHelp(){
 
206
  std::cout << "Usage : chemeq [-m] [-l] [-c] [-w] [-n] [-h]" << std::endl;
 
207
  std::cout << "        default is equivalent to 'chemeq -mlcwn'" << std::endl;
 
208
  std::cout << "        chemeq reads its standard input which must be a standard" << std::endl;
 
209
  std::cout << "        chemical equation. It outputs many strings useful for chemical" << std::endl;
 
210
  std::cout << "        calculations." << std::endl;
 
211
  std::cout << "        As an example you can try the following command :" << std::endl;
 
212
  std::cout << "        echo \"Fes -> Fe^2+ + 2 e- (0.44 V)\" | chemeq" << std::endl;
 
213
}
 
214
 
 
215
int main(int argc, char * argv[]){
 
216
  char * optstr = "mMlcwnh";
 
217
  int ch;
 
218
  bool nooption=1;
 
219
 
 
220
  if (argc>1 && !strcmp(argv[1],"-h")){
 
221
    printHelp(); return 0;
 
222
  }
 
223
  yyparse();
 
224
  if (isequation) {
 
225
    while (-1 != (ch=getopt(argc,argv,optstr))){
 
226
      switch(ch){
 
227
      case 'm': nooption=0;
 
228
        result.cq->printnorm(std::cout); std::cout << std::endl;
 
229
        break;
 
230
      case 'M': nooption=0;
 
231
        result.cq->printweight(std::cout);
 
232
        std::cout <<  std::endl;
 
233
        break;
 
234
      case 'l': nooption=0;
 
235
        std::cout << *result.cq << std::endl;
 
236
        break;
 
237
      case 'c': nooption=0;
 
238
        std::cout << result.cq->equilibre() << std::endl;
 
239
        break;
 
240
      case 'w': nooption=0;
 
241
        result.cq->printNernst(std::cout); std::cout << std::endl;
 
242
        break;
 
243
      case 'n': nooption=0;
 
244
        result.cq->normalise();
 
245
        result.cq->printnorm(std::cout); std::cout << std::endl;
 
246
        break;
 
247
      case 'h':
 
248
        printHelp();
 
249
        break;
 
250
      }
 
251
    }
 
252
    if (nooption){
 
253
      result.cq->printnorm(std::cout); std::cout << std::endl;
 
254
      std::cout << *result.cq << std::endl;
 
255
      std::cout << result.cq->equilibre() << std::endl;
 
256
      result.cq->printNernst(std::cout); std::cout << std::endl;
 
257
      result.cq->normalise();
 
258
      result.cq->printnorm(std::cout); std::cout << std::endl;
 
259
    }
 
260
  }
 
261
  else { /* ce n'est pas une �quation */
 
262
    while (-1 != (ch=getopt(argc,argv,optstr))){
 
263
      switch(ch){
 
264
      case 'M': nooption=0;
 
265
        std::cout << result.m->weight();
 
266
        std::cout <<  std::endl;
 
267
        break;
 
268
      }
 
269
    }
 
270
    if (nooption){
 
271
      std::cout << *result.m;
 
272
    }
 
273
  }
 
274
  return 0;
 
275
}