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
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 (void ) {
93 p = malloc (sizeof (asmrp_t));
96 p->sym = ASMRP_SYM_NONE;
102 static void asmrp_dispose (asmrp_t *p) {
106 for (i=0; i<p->sym_tab_num; i++)
107 free (p->sym_tab[i].id);
113 static void asmrp_getch (asmrp_t *p) {
114 p->ch = p->buf[p->pos];
117 lprintf ("%c\n", p->ch);
121 static void asmrp_init (asmrp_t *p, const char *str) {
123 p->buf = strdup (str);
129 static void asmrp_number (asmrp_t *p) {
134 while ( (p->ch>='0') && (p->ch<='9') ) {
136 num = num*10 + (p->ch - '0');
141 p->sym = ASMRP_SYM_NUM;
145 static void asmrp_string (asmrp_t *p) {
151 while ( (p->ch!='"') && (p->ch>=32) ) {
163 p->sym = ASMRP_SYM_STRING;
166 static void asmrp_identifier (asmrp_t *p) {
172 while ( ((p->ch>='A') && (p->ch<='z'))
173 || ((p->ch>='0') && (p->ch<='9'))) {
182 p->sym = ASMRP_SYM_ID;
186 static void asmrp_print_sym (asmrp_t *p) {
201 printf ("NUM %d\n", p->num);
205 printf ("ID '%s'\n", p->str);
208 case ASMRP_SYM_STRING:
209 printf ("STRING \"%s\"\n", p->str);
216 case ASMRP_SYM_SEMICOLON:
219 case ASMRP_SYM_COMMA:
222 case ASMRP_SYM_EQUALS:
240 case ASMRP_SYM_GREATER:
243 case ASMRP_SYM_DOLLAR:
246 case ASMRP_SYM_LPAREN:
249 case ASMRP_SYM_RPAREN:
254 printf ("unknown symbol %d\n", p->sym);
259 static void asmrp_get_sym (asmrp_t *p) {
261 while (p->ch <= 32) {
263 p->sym = ASMRP_SYM_EOF;
276 p->sym = ASMRP_SYM_HASH;
280 p->sym = ASMRP_SYM_SEMICOLON;
284 p->sym = ASMRP_SYM_COMMA;
288 p->sym = ASMRP_SYM_EQUALS;
294 p->sym = ASMRP_SYM_AND;
300 p->sym = ASMRP_SYM_OR;
306 p->sym = ASMRP_SYM_LESS;
309 p->sym = ASMRP_SYM_LEQ;
314 p->sym = ASMRP_SYM_GREATER;
317 p->sym = ASMRP_SYM_GEQ;
322 p->sym = ASMRP_SYM_DOLLAR;
326 p->sym = ASMRP_SYM_LPAREN;
330 p->sym = ASMRP_SYM_RPAREN;
339 case '0': case '1': case '2': case '3': case '4':
340 case '5': case '6': case '7': case '8': case '9':
345 asmrp_identifier (p);
354 static int asmrp_find_id (asmrp_t *p, const char *s) {
358 for (i=0; i<p->sym_tab_num; i++) {
359 if (!strcmp (s, p->sym_tab[i].id))
366 static int asmrp_set_id (asmrp_t *p, const char *s, int v) {
370 i = asmrp_find_id (p, s);
375 p->sym_tab[i].id = strdup (s);
377 lprintf ("new symbol '%s'\n", s);
383 lprintf ("symbol '%s' assigned %d\n", s, v);
388 static int asmrp_condition (asmrp_t *p) ;
390 static int asmrp_operand (asmrp_t *p) {
394 lprintf ("operand\n");
400 case ASMRP_SYM_DOLLAR:
404 if (p->sym != ASMRP_SYM_ID) {
405 printf ("error: identifier expected.\n");
409 i = asmrp_find_id (p, p->str);
411 lprintf ("error: unknown identifier %s\n", p->str);
413 ret = p->sym_tab[i].v;
424 case ASMRP_SYM_LPAREN:
427 ret = asmrp_condition (p);
429 if (p->sym != ASMRP_SYM_RPAREN) {
430 printf ("error: ) expected.\n");
438 lprintf ("syntax error, $ number or ( expected\n");
442 lprintf ("operand done, =%d\n", ret);
447 static int asmrp_comp_expression (asmrp_t *p) {
451 lprintf ("comp_expression\n");
453 a = asmrp_operand (p);
455 while ( (p->sym == ASMRP_SYM_LESS)
456 || (p->sym == ASMRP_SYM_LEQ)
457 || (p->sym == ASMRP_SYM_EQUALS)
458 || (p->sym == ASMRP_SYM_GEQ)
459 || (p->sym == ASMRP_SYM_GREATER) ) {
465 b = asmrp_operand (p);
474 case ASMRP_SYM_EQUALS:
480 case ASMRP_SYM_GREATER:
487 lprintf ("comp_expression done = %d\n", a);
492 static int asmrp_condition (asmrp_t *p) {
496 lprintf ("condition\n");
498 a = asmrp_comp_expression (p);
500 while ( (p->sym == ASMRP_SYM_AND) || (p->sym == ASMRP_SYM_OR) ) {
507 b = asmrp_comp_expression (p);
519 lprintf ("condition done = %d\n", a);
524 static void asmrp_assignment (asmrp_t *p) {
526 lprintf ("assignment\n");
528 if (p->sym == ASMRP_SYM_COMMA || p->sym == ASMRP_SYM_SEMICOLON) {
529 lprintf ("empty assignment\n");
533 if (p->sym != ASMRP_SYM_ID) {
534 printf ("error: identifier expected\n");
539 if (p->sym != ASMRP_SYM_EQUALS) {
540 printf ("error: = expected\n");
545 if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING)
546 && (p->sym != ASMRP_SYM_ID)) {
547 printf ("error: number or string expected\n");
552 lprintf ("assignment done\n");
555 static int asmrp_rule (asmrp_t *p) {
563 if (p->sym == ASMRP_SYM_HASH) {
566 ret = asmrp_condition (p);
568 while (p->sym == ASMRP_SYM_COMMA) {
572 asmrp_assignment (p);
575 } else if (p->sym != ASMRP_SYM_SEMICOLON) {
577 asmrp_assignment (p);
579 while (p->sym == ASMRP_SYM_COMMA) {
582 asmrp_assignment (p);
586 lprintf ("rule done = %d\n", ret);
588 if (p->sym != ASMRP_SYM_SEMICOLON) {
589 printf ("semicolon expected.\n");
598 static int asmrp_eval (asmrp_t *p, int *matches, int matchsize) {
600 int rule_num, num_matches;
606 rule_num = 0; num_matches = 0;
607 while (p->sym != ASMRP_SYM_EOF && num_matches < matchsize - 1) {
609 if (asmrp_rule (p)) {
610 lprintf ("rule #%d is true\n", rule_num);
612 matches[num_matches] = rule_num;
619 matches[num_matches] = -1;
623 int asmrp_match (const char *rules, int bandwidth, int *matches, int matchsize) {
630 asmrp_init (p, rules);
632 asmrp_set_id (p, "Bandwidth", bandwidth);
633 asmrp_set_id (p, "OldPNMPlayer", 0);
635 num_matches = asmrp_eval (p, matches, matchsize);