00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "real.h"
00038
00039 #define ASMRP_SYM_NONE 0
00040 #define ASMRP_SYM_EOF 1
00041
00042 #define ASMRP_SYM_NUM 2
00043 #define ASMRP_SYM_ID 3
00044 #define ASMRP_SYM_STRING 4
00045
00046 #define ASMRP_SYM_HASH 10
00047 #define ASMRP_SYM_SEMICOLON 11
00048 #define ASMRP_SYM_COMMA 12
00049 #define ASMRP_SYM_EQUALS 13
00050 #define ASMRP_SYM_AND 14
00051 #define ASMRP_SYM_OR 15
00052 #define ASMRP_SYM_LESS 16
00053 #define ASMRP_SYM_LEQ 17
00054 #define ASMRP_SYM_GEQ 18
00055 #define ASMRP_SYM_GREATER 19
00056 #define ASMRP_SYM_DOLLAR 20
00057 #define ASMRP_SYM_LPAREN 21
00058 #define ASMRP_SYM_RPAREN 22
00059
00060 #define ASMRP_MAX_ID 1024
00061
00062 #define ASMRP_MAX_SYMTAB 10
00063
00064 typedef struct {
00065 char *id;
00066 int v;
00067 } asmrp_sym_t;
00068
00069 typedef struct {
00070
00071
00072
00073 int sym;
00074 int num;
00075
00076 char str[ASMRP_MAX_ID];
00077
00078
00079
00080 char *buf;
00081 int pos;
00082 char ch;
00083
00084 asmrp_sym_t sym_tab[ASMRP_MAX_SYMTAB];
00085 int sym_tab_num;
00086
00087 } asmrp_t;
00088
00089 static asmrp_t *asmrp_new () {
00090
00091 asmrp_t *p;
00092
00093 p = malloc (sizeof (asmrp_t));
00094
00095 p->sym_tab_num = 0;
00096 p->sym = ASMRP_SYM_NONE;
00097 p->buf = 0;
00098
00099 return p;
00100 }
00101
00102 static void asmrp_dispose (asmrp_t *p) {
00103
00104 int i;
00105
00106 for (i=0; i<p->sym_tab_num; i++)
00107 free (p->sym_tab[i].id);
00108
00109 if (p->buf) free (p->buf);
00110 free (p);
00111 }
00112
00113 static void asmrp_getch (asmrp_t *p) {
00114 p->ch = p->buf[p->pos];
00115 p->pos++;
00116
00117 lprintf ("%c\n", p->ch);
00118
00119 }
00120
00121 static void asmrp_init (asmrp_t *p, const char *str) {
00122
00123 p->buf = strdup (str);
00124 p->pos = 0;
00125
00126 asmrp_getch (p);
00127 }
00128
00129 static void asmrp_number (asmrp_t *p) {
00130
00131 int num;
00132
00133 num = 0;
00134 while ( (p->ch>='0') && (p->ch<='9') ) {
00135
00136 num = num*10 + (p->ch - '0');
00137
00138 asmrp_getch (p);
00139 }
00140
00141 p->sym = ASMRP_SYM_NUM;
00142 p->num = num;
00143 }
00144
00145 static void asmrp_string (asmrp_t *p) {
00146
00147 int l;
00148
00149 l = 0;
00150
00151 while ( (p->ch!='"') && (p->ch>=32) ) {
00152
00153 p->str[l] = p->ch;
00154
00155 l++;
00156 asmrp_getch (p);
00157 }
00158 p->str[l]=0;
00159
00160 if (p->ch=='"')
00161 asmrp_getch (p);
00162
00163 p->sym = ASMRP_SYM_STRING;
00164 }
00165
00166 static void asmrp_identifier (asmrp_t *p) {
00167
00168 int l;
00169
00170 l = 0;
00171
00172 while ( ((p->ch>='A') && (p->ch<='z'))
00173 || ((p->ch>='0') && (p->ch<='9'))) {
00174
00175 p->str[l] = p->ch;
00176
00177 l++;
00178 asmrp_getch (p);
00179 }
00180 p->str[l]=0;
00181
00182 p->sym = ASMRP_SYM_ID;
00183 }
00184
00185 #ifdef LOG
00186 static void asmrp_print_sym (asmrp_t *p) {
00187
00188 printf ("symbol: ");
00189
00190 switch (p->sym) {
00191
00192 case ASMRP_SYM_NONE:
00193 printf ("NONE\n");
00194 break;
00195
00196 case ASMRP_SYM_EOF:
00197 printf ("EOF\n");
00198 break;
00199
00200 case ASMRP_SYM_NUM:
00201 printf ("NUM %d\n", p->num);
00202 break;
00203
00204 case ASMRP_SYM_ID:
00205 printf ("ID '%s'\n", p->str);
00206 break;
00207
00208 case ASMRP_SYM_STRING:
00209 printf ("STRING \"%s\"\n", p->str);
00210 break;
00211
00212 case ASMRP_SYM_HASH:
00213 printf ("#\n");
00214 break;
00215
00216 case ASMRP_SYM_SEMICOLON:
00217 printf (";\n");
00218 break;
00219 case ASMRP_SYM_COMMA:
00220 printf (",\n");
00221 break;
00222 case ASMRP_SYM_EQUALS:
00223 printf ("==\n");
00224 break;
00225 case ASMRP_SYM_AND:
00226 printf ("&&\n");
00227 break;
00228 case ASMRP_SYM_OR:
00229 printf ("||\n");
00230 break;
00231 case ASMRP_SYM_LESS:
00232 printf ("<\n");
00233 break;
00234 case ASMRP_SYM_LEQ:
00235 printf ("<=\n");
00236 break;
00237 case ASMRP_SYM_GEQ:
00238 printf (">=\n");
00239 break;
00240 case ASMRP_SYM_GREATER:
00241 printf (">\n");
00242 break;
00243 case ASMRP_SYM_DOLLAR:
00244 printf ("$\n");
00245 break;
00246 case ASMRP_SYM_LPAREN:
00247 printf ("(\n");
00248 break;
00249 case ASMRP_SYM_RPAREN:
00250 printf (")\n");
00251 break;
00252
00253 default:
00254 printf ("unknown symbol %d\n", p->sym);
00255 }
00256 }
00257 #endif
00258
00259 static void asmrp_get_sym (asmrp_t *p) {
00260
00261 while (p->ch <= 32) {
00262 if (p->ch == 0) {
00263 p->sym = ASMRP_SYM_EOF;
00264 return;
00265 }
00266
00267 asmrp_getch (p);
00268 }
00269
00270 if (p->ch == '\\')
00271 asmrp_getch (p);
00272
00273 switch (p->ch) {
00274
00275 case '#':
00276 p->sym = ASMRP_SYM_HASH;
00277 asmrp_getch (p);
00278 break;
00279 case ';':
00280 p->sym = ASMRP_SYM_SEMICOLON;
00281 asmrp_getch (p);
00282 break;
00283 case ',':
00284 p->sym = ASMRP_SYM_COMMA;
00285 asmrp_getch (p);
00286 break;
00287 case '=':
00288 p->sym = ASMRP_SYM_EQUALS;
00289 asmrp_getch (p);
00290 if (p->ch=='=')
00291 asmrp_getch (p);
00292 break;
00293 case '&':
00294 p->sym = ASMRP_SYM_AND;
00295 asmrp_getch (p);
00296 if (p->ch=='&')
00297 asmrp_getch (p);
00298 break;
00299 case '|':
00300 p->sym = ASMRP_SYM_OR;
00301 asmrp_getch (p);
00302 if (p->ch=='|')
00303 asmrp_getch (p);
00304 break;
00305 case '<':
00306 p->sym = ASMRP_SYM_LESS;
00307 asmrp_getch (p);
00308 if (p->ch=='=') {
00309 p->sym = ASMRP_SYM_LEQ;
00310 asmrp_getch (p);
00311 }
00312 break;
00313 case '>':
00314 p->sym = ASMRP_SYM_GREATER;
00315 asmrp_getch (p);
00316 if (p->ch=='=') {
00317 p->sym = ASMRP_SYM_GEQ;
00318 asmrp_getch (p);
00319 }
00320 break;
00321 case '$':
00322 p->sym = ASMRP_SYM_DOLLAR;
00323 asmrp_getch (p);
00324 break;
00325 case '(':
00326 p->sym = ASMRP_SYM_LPAREN;
00327 asmrp_getch (p);
00328 break;
00329 case ')':
00330 p->sym = ASMRP_SYM_RPAREN;
00331 asmrp_getch (p);
00332 break;
00333
00334 case '"':
00335 asmrp_getch (p);
00336 asmrp_string (p);
00337 break;
00338
00339 case '0': case '1': case '2': case '3': case '4':
00340 case '5': case '6': case '7': case '8': case '9':
00341 asmrp_number (p);
00342 break;
00343
00344 default:
00345 asmrp_identifier (p);
00346 }
00347
00348 #ifdef LOG
00349 asmrp_print_sym (p);
00350 #endif
00351
00352 }
00353
00354 static int asmrp_find_id (asmrp_t *p, char *s) {
00355
00356 int i;
00357
00358 for (i=0; i<p->sym_tab_num; i++) {
00359 if (!strcmp (s, p->sym_tab[i].id))
00360 return i;
00361 }
00362
00363 return -1;
00364 }
00365
00366 static int asmrp_set_id (asmrp_t *p, char *s, int v) {
00367
00368 int i;
00369
00370 i = asmrp_find_id (p, s);
00371
00372 if (i<0) {
00373 i = p->sym_tab_num;
00374 p->sym_tab_num++;
00375 p->sym_tab[i].id = strdup (s);
00376
00377 lprintf ("new symbol '%s'\n", s);
00378
00379 }
00380
00381 p->sym_tab[i].v = v;
00382
00383 lprintf ("symbol '%s' assigned %d\n", s, v);
00384
00385 return i;
00386 }
00387
00388 static int asmrp_condition (asmrp_t *p) ;
00389
00390 static int asmrp_operand (asmrp_t *p) {
00391
00392 int i, ret;
00393
00394 lprintf ("operand\n");
00395
00396 ret = 0;
00397
00398 switch (p->sym) {
00399
00400 case ASMRP_SYM_DOLLAR:
00401
00402 asmrp_get_sym (p);
00403
00404 if (p->sym != ASMRP_SYM_ID) {
00405 printf ("error: identifier expected.\n");
00406 break;
00407 }
00408
00409 i = asmrp_find_id (p, p->str);
00410 if (i<0) {
00411 lprintf ("error: unknown identifier %s\n", p->str);
00412 }
00413 ret = p->sym_tab[i].v;
00414
00415 asmrp_get_sym (p);
00416 break;
00417
00418 case ASMRP_SYM_NUM:
00419 ret = p->num;
00420
00421 asmrp_get_sym (p);
00422 break;
00423
00424 case ASMRP_SYM_LPAREN:
00425 asmrp_get_sym (p);
00426
00427 ret = asmrp_condition (p);
00428
00429 if (p->sym != ASMRP_SYM_RPAREN) {
00430 printf ("error: ) expected.\n");
00431 break;
00432 }
00433
00434 asmrp_get_sym (p);
00435 break;
00436
00437 default:
00438 lprintf ("syntax error, $ number or ( expected\n");
00439 break;
00440 }
00441
00442 lprintf ("operand done, =%d\n", ret);
00443
00444 return ret;
00445 }
00446
00447 static int asmrp_comp_expression (asmrp_t *p) {
00448
00449 int a;
00450
00451 lprintf ("comp_expression\n");
00452
00453 a = asmrp_operand (p);
00454
00455 while ( (p->sym == ASMRP_SYM_LESS)
00456 || (p->sym == ASMRP_SYM_LEQ)
00457 || (p->sym == ASMRP_SYM_EQUALS)
00458 || (p->sym == ASMRP_SYM_GEQ)
00459 || (p->sym == ASMRP_SYM_GREATER) ) {
00460 int op = p->sym;
00461 int b;
00462
00463 asmrp_get_sym (p);
00464
00465 b = asmrp_operand (p);
00466
00467 switch (op) {
00468 case ASMRP_SYM_LESS:
00469 a = a<b;
00470 break;
00471 case ASMRP_SYM_LEQ:
00472 a = a<=b;
00473 break;
00474 case ASMRP_SYM_EQUALS:
00475 a = a==b;
00476 break;
00477 case ASMRP_SYM_GEQ:
00478 a = a>=b;
00479 break;
00480 case ASMRP_SYM_GREATER:
00481 a = a>b;
00482 break;
00483 }
00484
00485 }
00486
00487 lprintf ("comp_expression done = %d\n", a);
00488
00489 return a;
00490 }
00491
00492 static int asmrp_condition (asmrp_t *p) {
00493
00494 int a;
00495
00496 lprintf ("condition\n");
00497
00498 a = asmrp_comp_expression (p);
00499
00500 while ( (p->sym == ASMRP_SYM_AND) || (p->sym == ASMRP_SYM_OR) ) {
00501 int op, b;
00502
00503 op = p->sym;
00504
00505 asmrp_get_sym (p);
00506
00507 b = asmrp_comp_expression (p);
00508
00509 switch (op) {
00510 case ASMRP_SYM_AND:
00511 a = a & b;
00512 break;
00513 case ASMRP_SYM_OR:
00514 a = a | b;
00515 break;
00516 }
00517 }
00518
00519 lprintf ("condition done = %d\n", a);
00520
00521 return a;
00522 }
00523
00524 static void asmrp_assignment (asmrp_t *p) {
00525
00526 lprintf ("assignment\n");
00527
00528 if (p->sym == ASMRP_SYM_COMMA || p->sym == ASMRP_SYM_SEMICOLON) {
00529 lprintf ("empty assignment\n");
00530 return;
00531 }
00532
00533 if (p->sym != ASMRP_SYM_ID) {
00534 printf ("error: identifier expected\n");
00535 return;
00536 }
00537 asmrp_get_sym (p);
00538
00539 if (p->sym != ASMRP_SYM_EQUALS) {
00540 printf ("error: = expected\n");
00541 return;
00542 }
00543 asmrp_get_sym (p);
00544
00545 if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING)
00546 && (p->sym != ASMRP_SYM_ID)) {
00547 printf ("error: number or string expected\n");
00548 return;
00549 }
00550 asmrp_get_sym (p);
00551
00552 lprintf ("assignment done\n");
00553 }
00554
00555 static int asmrp_rule (asmrp_t *p) {
00556
00557 int ret;
00558
00559 lprintf ("rule\n");
00560
00561 ret = 1;
00562
00563 if (p->sym == ASMRP_SYM_HASH) {
00564
00565 asmrp_get_sym (p);
00566 ret = asmrp_condition (p);
00567
00568 while (p->sym == ASMRP_SYM_COMMA) {
00569
00570 asmrp_get_sym (p);
00571
00572 asmrp_assignment (p);
00573 }
00574
00575 } else if (p->sym != ASMRP_SYM_SEMICOLON) {
00576
00577 asmrp_assignment (p);
00578
00579 while (p->sym == ASMRP_SYM_COMMA) {
00580
00581 asmrp_get_sym (p);
00582 asmrp_assignment (p);
00583 }
00584 }
00585
00586 lprintf ("rule done = %d\n", ret);
00587
00588 if (p->sym != ASMRP_SYM_SEMICOLON) {
00589 printf ("semicolon expected.\n");
00590 return ret;
00591 }
00592
00593 asmrp_get_sym (p);
00594
00595 return ret;
00596 }
00597
00598 static int asmrp_eval (asmrp_t *p, int *matches) {
00599
00600 int rule_num, num_matches;
00601
00602 lprintf ("eval\n");
00603
00604 asmrp_get_sym (p);
00605
00606 rule_num = 0; num_matches = 0;
00607 while (p->sym != ASMRP_SYM_EOF) {
00608
00609 if (asmrp_rule (p)) {
00610 lprintf ("rule #%d is true\n", rule_num);
00611
00612 matches[num_matches] = rule_num;
00613 num_matches++;
00614 }
00615
00616 rule_num++;
00617 }
00618
00619 matches[num_matches] = -1;
00620 return num_matches;
00621 }
00622
00623 int asmrp_match (const char *rules, int bandwidth, int *matches) {
00624
00625 asmrp_t *p;
00626 int num_matches;
00627
00628 p = asmrp_new ();
00629
00630 asmrp_init (p, rules);
00631
00632 asmrp_set_id (p, "Bandwidth", bandwidth);
00633 asmrp_set_id (p, "OldPNMPlayer", 0);
00634
00635 num_matches = asmrp_eval (p, matches);
00636
00637 asmrp_dispose (p);
00638
00639 return num_matches;
00640 }
00641