2 * Copyright (C) 2002-2004 the xine project
4 * This file is part of xine, a free video player.
6 * xine is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * xine is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 * $Id: asmrp.c,v 1.8 2004/08/27 18:34:16 miguelfreitas Exp $
22 * a parser for real's asm rules
24 * grammar for these rules:
28 rule = ( '#' condition { ',' assignment } | [ assignment {',' assignment} ]) ';'
29 assignment = id '=' const
30 const = ( number | string )
31 condition = comp_expr { ( '&&' | '||' ) comp_expr }
32 comp_expr = operand { ( '<' | '<=' | '==' | '>=' | '>' ) operand }
33 operand = ( '$' id | num | '(' condition ')' )
39 #define ASMRP_SYM_NONE 0
40 #define ASMRP_SYM_EOF 1
42 #define ASMRP_SYM_NUM 2
43 #define ASMRP_SYM_ID 3
44 #define ASMRP_SYM_STRING 4
46 #define ASMRP_SYM_HASH 10
47 #define ASMRP_SYM_SEMICOLON 11
48 #define ASMRP_SYM_COMMA 12
49 #define ASMRP_SYM_EQUALS 13
50 #define ASMRP_SYM_AND 14
51 #define ASMRP_SYM_OR 15
52 #define ASMRP_SYM_LESS 16
53 #define ASMRP_SYM_LEQ 17
54 #define ASMRP_SYM_GEQ 18
55 #define ASMRP_SYM_GREATER 19
56 #define ASMRP_SYM_DOLLAR 20
57 #define ASMRP_SYM_LPAREN 21
58 #define ASMRP_SYM_RPAREN 22
60 #define ASMRP_MAX_ID 1024
62 #define ASMRP_MAX_SYMTAB 10
76 char str[ASMRP_MAX_ID];
84 asmrp_sym_t sym_tab[ASMRP_MAX_SYMTAB];
89 static asmrp_t *asmrp_new () {
93 p = malloc (sizeof (asmrp_t));
96 p->sym = ASMRP_SYM_NONE;
101 static void asmrp_dispose (asmrp_t *p) {
105 for (i=0; i<p->sym_tab_num; i++)
106 free (p->sym_tab[i].id);
111 static void asmrp_getch (asmrp_t *p) {
112 p->ch = p->buf[p->pos];
115 lprintf ("%c\n", p->ch);
119 static void asmrp_init (asmrp_t *p, const char *str) {
121 p->buf = strdup (str);
127 static void asmrp_number (asmrp_t *p) {
132 while ( (p->ch>='0') && (p->ch<='9') ) {
134 num = num*10 + (p->ch - '0');
139 p->sym = ASMRP_SYM_NUM;
143 static void asmrp_string (asmrp_t *p) {
149 while ( (p->ch!='"') && (p->ch>=32) ) {
161 p->sym = ASMRP_SYM_STRING;
164 static void asmrp_identifier (asmrp_t *p) {
170 while ( ((p->ch>='A') && (p->ch<='z'))
171 || ((p->ch>='0') && (p->ch<='9'))) {
180 p->sym = ASMRP_SYM_ID;
184 static void asmrp_print_sym (asmrp_t *p) {
199 printf ("NUM %d\n", p->num);
203 printf ("ID '%s'\n", p->str);
206 case ASMRP_SYM_STRING:
207 printf ("STRING \"%s\"\n", p->str);
214 case ASMRP_SYM_SEMICOLON:
217 case ASMRP_SYM_COMMA:
220 case ASMRP_SYM_EQUALS:
238 case ASMRP_SYM_GREATER:
241 case ASMRP_SYM_DOLLAR:
244 case ASMRP_SYM_LPAREN:
247 case ASMRP_SYM_RPAREN:
252 printf ("unknown symbol %d\n", p->sym);
257 static void asmrp_get_sym (asmrp_t *p) {
259 while (p->ch <= 32) {
261 p->sym = ASMRP_SYM_EOF;
274 p->sym = ASMRP_SYM_HASH;
278 p->sym = ASMRP_SYM_SEMICOLON;
282 p->sym = ASMRP_SYM_COMMA;
286 p->sym = ASMRP_SYM_EQUALS;
292 p->sym = ASMRP_SYM_AND;
298 p->sym = ASMRP_SYM_OR;
304 p->sym = ASMRP_SYM_LESS;
307 p->sym = ASMRP_SYM_LEQ;
312 p->sym = ASMRP_SYM_GREATER;
315 p->sym = ASMRP_SYM_GEQ;
320 p->sym = ASMRP_SYM_DOLLAR;
324 p->sym = ASMRP_SYM_LPAREN;
328 p->sym = ASMRP_SYM_RPAREN;
337 case '0': case '1': case '2': case '3': case '4':
338 case '5': case '6': case '7': case '8': case '9':
343 asmrp_identifier (p);
352 static int asmrp_find_id (asmrp_t *p, char *s) {
356 for (i=0; i<p->sym_tab_num; i++) {
357 if (!strcmp (s, p->sym_tab[i].id))
364 static int asmrp_set_id (asmrp_t *p, char *s, int v) {
368 i = asmrp_find_id (p, s);
373 p->sym_tab[i].id = strdup (s);
375 lprintf ("new symbol '%s'\n", s);
381 lprintf ("symbol '%s' assigned %d\n", s, v);
386 static int asmrp_condition (asmrp_t *p) ;
388 static int asmrp_operand (asmrp_t *p) {
392 lprintf ("operand\n");
398 case ASMRP_SYM_DOLLAR:
402 if (p->sym != ASMRP_SYM_ID) {
403 printf ("error: identifier expected.\n");
407 i = asmrp_find_id (p, p->str);
409 lprintf ("error: unknown identifier %s\n", p->str);
411 ret = p->sym_tab[i].v;
422 case ASMRP_SYM_LPAREN:
425 ret = asmrp_condition (p);
427 if (p->sym != ASMRP_SYM_RPAREN) {
428 printf ("error: ) expected.\n");
436 lprintf ("syntax error, $ number or ( expected\n");
440 lprintf ("operand done, =%d\n", ret);
445 static int asmrp_comp_expression (asmrp_t *p) {
449 lprintf ("comp_expression\n");
451 a = asmrp_operand (p);
453 while ( (p->sym == ASMRP_SYM_LESS)
454 || (p->sym == ASMRP_SYM_LEQ)
455 || (p->sym == ASMRP_SYM_EQUALS)
456 || (p->sym == ASMRP_SYM_GEQ)
457 || (p->sym == ASMRP_SYM_GREATER) ) {
463 b = asmrp_operand (p);
472 case ASMRP_SYM_EQUALS:
478 case ASMRP_SYM_GREATER:
485 lprintf ("comp_expression done = %d\n", a);
490 static int asmrp_condition (asmrp_t *p) {
494 lprintf ("condition\n");
496 a = asmrp_comp_expression (p);
498 while ( (p->sym == ASMRP_SYM_AND) || (p->sym == ASMRP_SYM_OR) ) {
505 b = asmrp_comp_expression (p);
517 lprintf ("condition done = %d\n", a);
522 static void asmrp_assignment (asmrp_t *p) {
524 lprintf ("assignment\n");
526 if (p->sym == ASMRP_SYM_COMMA || p->sym == ASMRP_SYM_SEMICOLON) {
527 lprintf ("empty assignment\n");
531 if (p->sym != ASMRP_SYM_ID) {
532 printf ("error: identifier expected\n");
537 if (p->sym != ASMRP_SYM_EQUALS) {
538 printf ("error: = expected\n");
543 if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING)
544 && (p->sym != ASMRP_SYM_ID)) {
545 printf ("error: number or string expected\n");
550 lprintf ("assignment done\n");
553 static int asmrp_rule (asmrp_t *p) {
561 if (p->sym == ASMRP_SYM_HASH) {
564 ret = asmrp_condition (p);
566 while (p->sym == ASMRP_SYM_COMMA) {
570 asmrp_assignment (p);
573 } else if (p->sym != ASMRP_SYM_SEMICOLON) {
575 asmrp_assignment (p);
577 while (p->sym == ASMRP_SYM_COMMA) {
580 asmrp_assignment (p);
584 lprintf ("rule done = %d\n", ret);
586 if (p->sym != ASMRP_SYM_SEMICOLON) {
587 printf ("semicolon expected.\n");
596 static int asmrp_eval (asmrp_t *p, int *matches) {
598 int rule_num, num_matches;
604 rule_num = 0; num_matches = 0;
605 while (p->sym != ASMRP_SYM_EOF) {
607 if (asmrp_rule (p)) {
608 lprintf ("rule #%d is true\n", rule_num);
610 matches[num_matches] = rule_num;
617 matches[num_matches] = -1;
621 int asmrp_match (const char *rules, int bandwidth, int *matches) {
628 asmrp_init (p, rules);
630 asmrp_set_id (p, "Bandwidth", bandwidth);
631 asmrp_set_id (p, "OldPNMPlayer", 0);
633 num_matches = asmrp_eval (p, matches);