static int asmrp_operand (asmrp_t *p) { int i, ret; #ifdef LOG printf ("operand\n"); #endif ret = 0; switch (p->sym) { case ASMRP_SYM_DOLLAR: asmrp_get_sym (p); if (p->sym != ASMRP_SYM_ID) { printf ("error: identifier expected.\n"); abort(); } i = asmrp_find_id (p, p->str); if (i<0) { printf ("error: unknown identifier %s\n", p->str); } ret = p->sym_tab[i].v; asmrp_get_sym (p); break; case ASMRP_SYM_NUM: ret = p->num; asmrp_get_sym (p); break; case ASMRP_SYM_LPAREN: asmrp_get_sym (p); ret = asmrp_condition (p); if (p->sym != ASMRP_SYM_RPAREN) { printf ("error: ) expected.\n"); abort(); } asmrp_get_sym (p); break; default: printf ("syntax error, $ number or ( expected\n"); abort(); } #ifdef LOG printf ("operand done, =%d\n", ret); #endif return ret; }
static int asmrp_eval (asmrp_t *p, int *matches) { int rule_num, num_matches; #ifdef LOG printf ("eval\n"); #endif asmrp_get_sym (p); rule_num = 0; num_matches = 0; while (p->sym != ASMRP_SYM_EOF) { if (asmrp_rule (p)) { #ifdef LOG printf ("rule #%d is true\n", rule_num); #endif matches[num_matches] = rule_num; num_matches++; } rule_num++; } matches[num_matches] = -1; return num_matches; }
static int asmrp_condition (asmrp_t *p) { int a; #ifdef LOG printf ("condition\n"); #endif a = asmrp_comp_expression (p); while ( (p->sym == ASMRP_SYM_AND) || (p->sym == ASMRP_SYM_OR) ) { int op, b; op = p->sym; asmrp_get_sym (p); b = asmrp_comp_expression (p); switch (op) { case ASMRP_SYM_AND: a = a & b; break; case ASMRP_SYM_OR: a = a | b; break; } } #ifdef LOG printf ("condition done = %d\n", a); #endif return a; }
static int asmrp_eval (asmrp_t *p, int *matches) { int rule_num, num_matches; #ifdef LOG printf ("eval\n"); #endif asmrp_get_sym (p); rule_num = 0; num_matches = 0; while (p->sym != ASMRP_SYM_EOF) { if (asmrp_rule (p)) { #ifdef LOG printf ("rule #%d is true\n", rule_num); #endif if(num_matches < MAX_RULEMATCHES - 1) matches[num_matches++] = rule_num; else mp_msg(MSGT_STREAM, MSGL_ERR, "Ignoring matched asm rule %d, too many matched rules.\n", rule_num); } rule_num++; } matches[num_matches] = -1; return num_matches; }
static int asmrp_rule (asmrp_t *p) { int ret; #ifdef LOG printf ("rule\n"); #endif ret = 1; if (p->sym == ASMRP_SYM_HASH) { asmrp_get_sym (p); ret = asmrp_condition (p); while (p->sym == ASMRP_SYM_COMMA) { asmrp_get_sym (p); asmrp_assignment (p); } } else if (p->sym != ASMRP_SYM_SEMICOLON) { asmrp_assignment (p); while (p->sym == ASMRP_SYM_COMMA) { asmrp_get_sym (p); asmrp_assignment (p); } } #ifdef LOG printf ("rule done = %d\n", ret); #endif if (p->sym != ASMRP_SYM_SEMICOLON) { printf ("semicolon expected.\n"); abort (); } asmrp_get_sym (p); return ret; }
static void asmrp_assignment (asmrp_t *p) { #ifdef LOG printf ("assignment\n"); #endif if (p->sym == ASMRP_SYM_COMMA || p->sym == ASMRP_SYM_SEMICOLON) { #ifdef LOG printf ("empty assignment\n"); #endif return; } if (p->sym != ASMRP_SYM_ID) { printf ("error: identifier expected\n"); abort (); } asmrp_get_sym (p); if (p->sym != ASMRP_SYM_EQUALS) { printf ("error: = expected\n"); abort (); } asmrp_get_sym (p); if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING) && (p->sym != ASMRP_SYM_ID)) { printf ("error: number or string expected\n"); abort (); } asmrp_get_sym (p); #ifdef LOG printf ("assignment done\n"); #endif }
static int asmrp_comp_expression (asmrp_t *p) { int a; #ifdef LOG printf ("comp_expression\n"); #endif a = asmrp_operand (p); while ( (p->sym == ASMRP_SYM_LESS) || (p->sym == ASMRP_SYM_LEQ) || (p->sym == ASMRP_SYM_EQUALS) || (p->sym == ASMRP_SYM_GEQ) || (p->sym == ASMRP_SYM_GREATER) ) { int op = p->sym; int b; asmrp_get_sym (p); b = asmrp_operand (p); switch (op) { case ASMRP_SYM_LESS: a = a<b; break; case ASMRP_SYM_LEQ: a = a<=b; break; case ASMRP_SYM_EQUALS: a = a==b; break; case ASMRP_SYM_GEQ: a = a>=b; break; case ASMRP_SYM_GREATER: a = a>b; break; } } #ifdef LOG printf ("comp_expression done = %d\n", a); #endif return a; }