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
);