real_asmrp.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:11k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) 2002-2004 the xine project
  3.  *
  4.  * This file is part of xine, a free video player.
  5.  *
  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.
  10.  *
  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.
  15.  *
  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
  19.  *
  20.  * $Id: 057e230e7823400e3b022b1621aa8384a4e4671f $
  21.  *
  22.  * a parser for real's asm rules
  23.  *
  24.  * grammar for these rules:
  25.  *
  26.    rule_book  = { rule }
  27.    rule       = ( '#' condition { ',' assignment } | [ assignment {',' assignment} ]) ';'
  28.    assignment = id '=' const
  29.    const      = ( number | string )
  30.    condition  = comp_expr { ( '&&' | '||' ) comp_expr }
  31.    comp_expr  = operand { ( '<' | '<=' | '==' | '>=' | '>' ) operand }
  32.    operand    = ( '$' id | num | '(' condition ')' )
  33.  */
  34. #include "real.h"
  35. #define ASMRP_SYM_NONE         0
  36. #define ASMRP_SYM_EOF          1
  37. #define ASMRP_SYM_NUM          2
  38. #define ASMRP_SYM_ID           3
  39. #define ASMRP_SYM_STRING       4
  40. #define ASMRP_SYM_HASH         10
  41. #define ASMRP_SYM_SEMICOLON    11
  42. #define ASMRP_SYM_COMMA        12
  43. #define ASMRP_SYM_EQUALS       13
  44. #define ASMRP_SYM_AND          14
  45. #define ASMRP_SYM_OR           15
  46. #define ASMRP_SYM_LESS         16
  47. #define ASMRP_SYM_LEQ          17
  48. #define ASMRP_SYM_GEQ          18
  49. #define ASMRP_SYM_GREATER      19
  50. #define ASMRP_SYM_DOLLAR       20
  51. #define ASMRP_SYM_LPAREN       21
  52. #define ASMRP_SYM_RPAREN       22
  53. #define ASMRP_MAX_ID         1024
  54. #define ASMRP_MAX_SYMTAB       10
  55. typedef struct {
  56.   char *id;
  57.   int   v;
  58. } asmrp_sym_t;
  59. typedef struct {
  60.   /* public part */
  61.   int         sym;
  62.   int         num;
  63.  
  64.   char        str[ASMRP_MAX_ID];
  65.   /* private part */
  66.   char       *buf;
  67.   int         pos;
  68.   char        ch;
  69.   asmrp_sym_t sym_tab[ASMRP_MAX_SYMTAB];
  70.   int         sym_tab_num;
  71. } asmrp_t;
  72. static asmrp_t *asmrp_new (void ) {
  73.   asmrp_t *p;
  74.   p = malloc (sizeof (asmrp_t));
  75.   p->sym_tab_num = 0;
  76.   p->sym         = ASMRP_SYM_NONE;
  77.   p->buf         = NULL;
  78.   return p;
  79. }
  80. static void asmrp_dispose (asmrp_t *p) {
  81.   int i;
  82.   for (i=0; i<p->sym_tab_num; i++)
  83.     free (p->sym_tab[i].id);
  84.   free( p->buf );
  85.   free( p );
  86. }
  87. static void asmrp_getch (asmrp_t *p) {
  88.   p->ch = p->buf[p->pos];
  89.   p->pos++;
  90.   lprintf ("%cn", p->ch);
  91. }
  92. static void asmrp_init (asmrp_t *p, const char *str) {
  93.   p->buf = strdup (str);
  94.   p->pos = 0;
  95.  
  96.   asmrp_getch (p);
  97. }
  98. static void asmrp_number (asmrp_t *p) {
  99.   int num;
  100.   num = 0;
  101.   while ( (p->ch>='0') && (p->ch<='9') ) {
  102.     num = num*10 + (p->ch - '0');
  103.     asmrp_getch (p);
  104.   }
  105.   p->sym = ASMRP_SYM_NUM;
  106.   p->num = num;
  107. }
  108. static void asmrp_string (asmrp_t *p) {
  109.   int l;
  110.   l = 0;
  111.   while ( (p->ch!='"') && (p->ch>=32) ) {
  112.     p->str[l] = p->ch;
  113.     l++;
  114.     asmrp_getch (p);
  115.   }
  116.   p->str[l]=0;
  117.  
  118.   if (p->ch=='"')
  119.     asmrp_getch (p);
  120.  
  121.   p->sym = ASMRP_SYM_STRING;
  122. }
  123. static void asmrp_identifier (asmrp_t *p) {
  124.   int l;
  125.   l = 0;
  126.   while ( ((p->ch>='A') && (p->ch<='z'))
  127.       || ((p->ch>='0') && (p->ch<='9'))) {
  128.     p->str[l] = p->ch;
  129.     l++;
  130.     asmrp_getch (p);
  131.   }
  132.   p->str[l]=0;
  133.  
  134.   p->sym = ASMRP_SYM_ID;
  135. }
  136. #ifdef LOG
  137. static void asmrp_print_sym (asmrp_t *p) {
  138.   printf ("symbol: ");
  139.   switch (p->sym) {
  140.   case ASMRP_SYM_NONE:
  141.     printf ("NONEn");
  142.     break;
  143.   case ASMRP_SYM_EOF:
  144.     printf ("EOFn");
  145.     break;
  146.   case ASMRP_SYM_NUM:
  147.     printf ("NUM %dn", p->num);
  148.     break;
  149.   case ASMRP_SYM_ID:
  150.     printf ("ID '%s'n", p->str);
  151.     break;
  152.   case ASMRP_SYM_STRING:
  153.     printf ("STRING "%s"n", p->str);
  154.     break;
  155.   case ASMRP_SYM_HASH:
  156.     printf ("#n");
  157.     break;
  158.   case ASMRP_SYM_SEMICOLON:
  159.     printf (";n");
  160.     break;
  161.   case ASMRP_SYM_COMMA:
  162.     printf (",n");
  163.     break;
  164.   case ASMRP_SYM_EQUALS:
  165.     printf ("==n");
  166.     break;
  167.   case ASMRP_SYM_AND:
  168.     printf ("&&n");
  169.     break;
  170.   case ASMRP_SYM_OR:
  171.     printf ("||n");
  172.     break;
  173.   case ASMRP_SYM_LESS:
  174.     printf ("<n");
  175.     break;
  176.   case ASMRP_SYM_LEQ:
  177.     printf ("<=n");
  178.     break;
  179.   case ASMRP_SYM_GEQ:
  180.     printf (">=n");
  181.     break;
  182.   case ASMRP_SYM_GREATER:
  183.     printf (">n");
  184.     break;
  185.   case ASMRP_SYM_DOLLAR:
  186.     printf ("$n");
  187.     break;
  188.   case ASMRP_SYM_LPAREN:
  189.     printf ("(n");
  190.     break;
  191.   case ASMRP_SYM_RPAREN:
  192.     printf (")n");
  193.     break;
  194.   default:
  195.     printf ("unknown symbol %dn", p->sym);
  196.   }
  197. }
  198. #endif
  199. static void asmrp_get_sym (asmrp_t *p) {
  200.   while (p->ch <= 32) {
  201.     if (p->ch == 0) {
  202.       p->sym = ASMRP_SYM_EOF;
  203.       return;
  204.     }
  205.     asmrp_getch (p);
  206.   }
  207.   if (p->ch == '\')
  208.     asmrp_getch (p);
  209.   switch (p->ch) {
  210.   case '#':
  211.     p->sym = ASMRP_SYM_HASH;
  212.     asmrp_getch (p);
  213.     break;
  214.   case ';':
  215.     p->sym = ASMRP_SYM_SEMICOLON;
  216.     asmrp_getch (p);
  217.     break;
  218.   case ',':
  219.     p->sym = ASMRP_SYM_COMMA;
  220.     asmrp_getch (p);
  221.     break;
  222.   case '=':
  223.     p->sym = ASMRP_SYM_EQUALS;
  224.     asmrp_getch (p);
  225.     if (p->ch=='=')
  226.       asmrp_getch (p);
  227.     break;
  228.   case '&':
  229.     p->sym = ASMRP_SYM_AND;
  230.     asmrp_getch (p);
  231.     if (p->ch=='&')
  232.       asmrp_getch (p);
  233.     break;
  234.   case '|':
  235.     p->sym = ASMRP_SYM_OR;
  236.     asmrp_getch (p);
  237.     if (p->ch=='|')
  238.       asmrp_getch (p);
  239.     break;
  240.   case '<':
  241.     p->sym = ASMRP_SYM_LESS;
  242.     asmrp_getch (p);
  243.     if (p->ch=='=') {
  244.       p->sym = ASMRP_SYM_LEQ;
  245.       asmrp_getch (p);
  246.     }
  247.     break;
  248.   case '>':
  249.     p->sym = ASMRP_SYM_GREATER;
  250.     asmrp_getch (p);
  251.     if (p->ch=='=') {
  252.       p->sym = ASMRP_SYM_GEQ;
  253.       asmrp_getch (p);
  254.     }
  255.     break;
  256.   case '$':
  257.     p->sym = ASMRP_SYM_DOLLAR;
  258.     asmrp_getch (p);
  259.     break;
  260.   case '(':
  261.     p->sym = ASMRP_SYM_LPAREN;
  262.     asmrp_getch (p);
  263.     break;
  264.   case ')':
  265.     p->sym = ASMRP_SYM_RPAREN;
  266.     asmrp_getch (p);
  267.     break;
  268.   case '"':
  269.     asmrp_getch (p);
  270.     asmrp_string (p);
  271.     break;
  272.   case '0': case '1': case '2': case '3': case '4':
  273.   case '5': case '6': case '7': case '8': case '9':
  274.     asmrp_number (p);
  275.     break;
  276.   default:
  277.     asmrp_identifier (p);
  278.   }
  279. #ifdef LOG
  280.   asmrp_print_sym (p);
  281. #endif
  282. }
  283. static int asmrp_find_id (asmrp_t *p, const char *s) {
  284.   int i;
  285.   for (i=0; i<p->sym_tab_num; i++) {
  286.     if (!strcmp (s, p->sym_tab[i].id))
  287.       return i;
  288.   }
  289.   return -1;
  290. }
  291. static int asmrp_set_id (asmrp_t *p, const char *s, int v) {
  292.   int i;
  293.   i = asmrp_find_id (p, s);
  294.   if (i<0) {
  295.     i = p->sym_tab_num;
  296.     p->sym_tab_num++;
  297.     p->sym_tab[i].id = strdup (s);
  298.     lprintf ("new symbol '%s'n", s);
  299.   }
  300.   p->sym_tab[i].v = v;
  301.  
  302.   lprintf ("symbol '%s' assigned %dn", s, v);
  303.   return i;
  304. }
  305. static int asmrp_condition (asmrp_t *p) ;
  306. static int asmrp_operand (asmrp_t *p) {
  307.   int i, ret;
  308.  
  309.   lprintf ("operandn");
  310.   ret = 0;
  311.   switch (p->sym) {
  312.   case ASMRP_SYM_DOLLAR:
  313.     asmrp_get_sym (p);
  314.  
  315.     if (p->sym != ASMRP_SYM_ID) {
  316.       printf ("error: identifier expected.n");
  317.       break;
  318.     }
  319.     i = asmrp_find_id (p, p->str);
  320.     if (i<0) {
  321.       lprintf ("error: unknown identifier %sn", p->str);
  322.     }
  323.     ret = p->sym_tab[i].v;
  324.     asmrp_get_sym (p);
  325.     break;
  326.   case ASMRP_SYM_NUM:
  327.     ret = p->num;
  328.     asmrp_get_sym (p);
  329.     break;
  330.   case ASMRP_SYM_LPAREN:
  331.     asmrp_get_sym (p);
  332.     ret = asmrp_condition (p);
  333.     if (p->sym != ASMRP_SYM_RPAREN) {
  334.       printf ("error: ) expected.n");
  335.       break;
  336.     }
  337.     asmrp_get_sym (p);
  338.     break;
  339.   default:
  340.     lprintf ("syntax error, $ number or ( expectedn");
  341.     break;
  342.   }
  343.   lprintf ("operand done, =%dn", ret);
  344.  
  345.   return ret;
  346. }
  347. static int asmrp_comp_expression (asmrp_t *p) {
  348.   int a;
  349.   lprintf ("comp_expressionn");
  350.   a = asmrp_operand (p);
  351.   while ( (p->sym == ASMRP_SYM_LESS)
  352.       || (p->sym == ASMRP_SYM_LEQ)
  353.       || (p->sym == ASMRP_SYM_EQUALS)
  354.       || (p->sym == ASMRP_SYM_GEQ)
  355.       || (p->sym == ASMRP_SYM_GREATER) ) {
  356.     int op = p->sym;
  357.     int b;
  358.     asmrp_get_sym (p);
  359.     b = asmrp_operand (p);
  360.     switch (op) {
  361.     case ASMRP_SYM_LESS:
  362.       a = a<b;
  363.       break;
  364.     case ASMRP_SYM_LEQ:
  365.       a = a<=b;
  366.       break;
  367.     case ASMRP_SYM_EQUALS:
  368.       a = a==b;
  369.       break;
  370.     case ASMRP_SYM_GEQ:
  371.       a = a>=b;
  372.       break;
  373.     case ASMRP_SYM_GREATER:
  374.       a = a>b;
  375.       break;
  376.     }
  377.   }
  378.   lprintf ("comp_expression done = %dn", a);
  379.   return a;
  380. }
  381. static int asmrp_condition (asmrp_t *p) {
  382.  
  383.   int a;
  384.   lprintf ("conditionn");
  385.   a = asmrp_comp_expression (p);
  386.   while ( (p->sym == ASMRP_SYM_AND) || (p->sym == ASMRP_SYM_OR) ) {
  387.     int op, b;
  388.     op = p->sym;
  389.     asmrp_get_sym (p);
  390.     b = asmrp_comp_expression (p);
  391.     switch (op) {
  392.     case ASMRP_SYM_AND:
  393.       a = a & b;
  394.       break;
  395.     case ASMRP_SYM_OR:
  396.       a = a | b;
  397.       break;
  398.     }
  399.   }
  400.   lprintf ("condition done = %dn", a);
  401.   return a;
  402. }
  403. static void asmrp_assignment (asmrp_t *p) {
  404.   lprintf ("assignmentn");
  405.   if (p->sym == ASMRP_SYM_COMMA || p->sym == ASMRP_SYM_SEMICOLON) {
  406.     lprintf ("empty assignmentn");
  407.     return;
  408.   }
  409.  
  410.   if (p->sym != ASMRP_SYM_ID) {
  411.     printf ("error: identifier expectedn");
  412.     return;
  413.   }
  414.   asmrp_get_sym (p);
  415.   if (p->sym != ASMRP_SYM_EQUALS) {
  416.     printf ("error: = expectedn");
  417.     return;
  418.   }
  419.   asmrp_get_sym (p);
  420.   if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING)
  421.        && (p->sym != ASMRP_SYM_ID)) {
  422.     printf ("error: number or string expectedn");
  423.     return;
  424.   }
  425.   asmrp_get_sym (p);
  426.   lprintf ("assignment donen");
  427. }
  428. static int asmrp_rule (asmrp_t *p) {
  429.  
  430.   int ret;
  431.   lprintf ("rulen");
  432.   ret = 1;
  433.  
  434.   if (p->sym == ASMRP_SYM_HASH) {
  435.     asmrp_get_sym (p);
  436.     ret = asmrp_condition (p);
  437.     while (p->sym == ASMRP_SYM_COMMA) {
  438.  
  439.       asmrp_get_sym (p);
  440.  
  441.       asmrp_assignment (p);
  442.     }
  443.   } else if (p->sym != ASMRP_SYM_SEMICOLON) {
  444.     asmrp_assignment (p);
  445.     while (p->sym == ASMRP_SYM_COMMA) {
  446.       asmrp_get_sym (p);
  447.       asmrp_assignment (p);
  448.     }
  449.   }
  450.   lprintf ("rule done = %dn", ret);
  451.   if (p->sym != ASMRP_SYM_SEMICOLON) {
  452.     printf ("semicolon expected.n");
  453.     return ret;
  454.   }
  455.   asmrp_get_sym (p);
  456.   return ret;
  457. }
  458. static int asmrp_eval (asmrp_t *p, int *matches, int matchsize) {
  459.   int rule_num, num_matches;
  460.   lprintf ("evaln");
  461.   asmrp_get_sym (p);
  462.   rule_num = 0; num_matches = 0;
  463.   while (p->sym != ASMRP_SYM_EOF && num_matches < matchsize - 1) {
  464.     if (asmrp_rule (p)) {
  465.       lprintf ("rule #%d is truen", rule_num);
  466.       matches[num_matches] = rule_num;
  467.       num_matches++;
  468.     }
  469.     rule_num++;
  470.   }
  471.   matches[num_matches] = -1;
  472.   return num_matches;
  473. }
  474. int asmrp_match (const char *rules, int bandwidth, int *matches, int matchsize) {
  475.   asmrp_t *p;
  476.   int      num_matches;
  477.   p = asmrp_new ();
  478.   asmrp_init (p, rules);
  479.   asmrp_set_id (p, "Bandwidth", bandwidth);
  480.   asmrp_set_id (p, "OldPNMPlayer", 0);
  481.   num_matches = asmrp_eval (p, matches, matchsize);
  482.   asmrp_dispose (p);
  483.   return num_matches;
  484. }