Bernard Escaillas
/
MidiTee
parse.h@0:71d791204057, 2011-06-07 (annotated)
- Committer:
- Midimetric
- Date:
- Tue Jun 07 13:32:20 2011 +0000
- Revision:
- 0:71d791204057
Version 1.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Midimetric | 0:71d791204057 | 1 | #ifndef PARSE_H |
Midimetric | 0:71d791204057 | 2 | #define PARSE_H |
Midimetric | 0:71d791204057 | 3 | |
Midimetric | 0:71d791204057 | 4 | #include <string.h> |
Midimetric | 0:71d791204057 | 5 | #include <vector> |
Midimetric | 0:71d791204057 | 6 | |
Midimetric | 0:71d791204057 | 7 | void ParseCleanUp( char* s1, char* s2 ) |
Midimetric | 0:71d791204057 | 8 | { |
Midimetric | 0:71d791204057 | 9 | // copy all non blank till ; or 0 |
Midimetric | 0:71d791204057 | 10 | for( int i = 0, j = 0 ; i < 256 ; i++ ) |
Midimetric | 0:71d791204057 | 11 | if( s1[i] != 32 && s1[i] != 13 && s1[i] != 10 && s1[i] != 9 ) |
Midimetric | 0:71d791204057 | 12 | switch( s2[j++] = s1[i] ) { |
Midimetric | 0:71d791204057 | 13 | case ';': s2[j-1] = 0; return; |
Midimetric | 0:71d791204057 | 14 | case 0: return; |
Midimetric | 0:71d791204057 | 15 | } |
Midimetric | 0:71d791204057 | 16 | } |
Midimetric | 0:71d791204057 | 17 | int GetOPIDfromFunction( char * f ) |
Midimetric | 0:71d791204057 | 18 | { |
Midimetric | 0:71d791204057 | 19 | if( strcmp( f, "add" ) == 0 ) return ADD; |
Midimetric | 0:71d791204057 | 20 | if( strcmp( f, "mul" ) == 0 ) return MUL; |
Midimetric | 0:71d791204057 | 21 | if( strcmp( f, "sub" ) == 0 ) return SUB; |
Midimetric | 0:71d791204057 | 22 | if( strcmp( f, "div" ) == 0 ) return DIV; |
Midimetric | 0:71d791204057 | 23 | if( strcmp( f, "i8" ) == 0 ) return E8_; |
Midimetric | 0:71d791204057 | 24 | if( strcmp( f, "i14" ) == 0 ) return E14; |
Midimetric | 0:71d791204057 | 25 | if( strcmp( f, "mod" ) == 0 ) return MOD; |
Midimetric | 0:71d791204057 | 26 | if( strcmp( f, "bit" ) == 0 ) return BIT; |
Midimetric | 0:71d791204057 | 27 | if( strcmp( f, "bor" ) == 0 ) return BOR; |
Midimetric | 0:71d791204057 | 28 | if( strcmp( f, "ban" ) == 0 ) return BAN; |
Midimetric | 0:71d791204057 | 29 | if( strcmp( f, "bno" ) == 0 ) return BNO; |
Midimetric | 0:71d791204057 | 30 | if( strcmp( f, "bsl" ) == 0 ) return BSL; |
Midimetric | 0:71d791204057 | 31 | if( strcmp( f, "bsr" ) == 0 ) return BSR; |
Midimetric | 0:71d791204057 | 32 | if( strcmp( f, "msb" ) == 0 ) return MSB; |
Midimetric | 0:71d791204057 | 33 | if( strcmp( f, "lsb" ) == 0 ) return LSB; |
Midimetric | 0:71d791204057 | 34 | if( strcmp( f, "map" ) == 0 ) return MAP; |
Midimetric | 0:71d791204057 | 35 | if( strcmp( f, "nrpn") == 0 ) return NPN; |
Midimetric | 0:71d791204057 | 36 | if( strcmp( f, "rpn" ) == 0 ) return RPN; |
Midimetric | 0:71d791204057 | 37 | if( strcmp( f, "bank") == 0 ) return BNK; |
Midimetric | 0:71d791204057 | 38 | if( strcmp( f, "nrp8") == 0 ) return NP8; |
Midimetric | 0:71d791204057 | 39 | return 0; |
Midimetric | 0:71d791204057 | 40 | } |
Midimetric | 0:71d791204057 | 41 | |
Midimetric | 0:71d791204057 | 42 | int ParseError = 0; |
Midimetric | 0:71d791204057 | 43 | int ParseLine = 0; |
Midimetric | 0:71d791204057 | 44 | #define abort(x) { ParseError = x; return false; } |
Midimetric | 0:71d791204057 | 45 | |
Midimetric | 0:71d791204057 | 46 | #define PARSE_NOERROR 0 |
Midimetric | 0:71d791204057 | 47 | #define PARSE_NO_FILE 1 |
Midimetric | 0:71d791204057 | 48 | #define PARSE_BAD_NUMBER_DEFINITION 2 |
Midimetric | 0:71d791204057 | 49 | #define PARSE_BAD_MESSAGE_DEFINITION 3 |
Midimetric | 0:71d791204057 | 50 | #define PARSE_BAD_SEQ_SYNTAXE 4 |
Midimetric | 0:71d791204057 | 51 | #define PARSE_BAD_SEQ_HEXA_SIGN 5 |
Midimetric | 0:71d791204057 | 52 | #define PARSE_BAD_SEQ_NUMBER 6 |
Midimetric | 0:71d791204057 | 53 | #define PARSE_BAD_SEQ_IDENTIFIER 7 |
Midimetric | 0:71d791204057 | 54 | #define PARSE_BAD_SEQ_BYTE 8 |
Midimetric | 0:71d791204057 | 55 | #define PARSE_BAD_SEQ_FUNCTION 9 |
Midimetric | 0:71d791204057 | 56 | #define PARSE_BAD_SEQ_TOOLONG 10 |
Midimetric | 0:71d791204057 | 57 | #define PARSE_UNKNWON_ENTRY 11 |
Midimetric | 0:71d791204057 | 58 | #define PARSE_MIN_GREATER_THAN_MAX 12 |
Midimetric | 0:71d791204057 | 59 | |
Midimetric | 0:71d791204057 | 60 | #define TOKEN_END *p == 0 || *p == ',' || *p == ')' |
Midimetric | 0:71d791204057 | 61 | #define TOKEN_NUM *p >= '0' && *p <= '9' |
Midimetric | 0:71d791204057 | 62 | #define TOKEN_LOW *p >= 'a' && *p <= 'z' |
Midimetric | 0:71d791204057 | 63 | #define TOKEN_UPP *p >= 'A' && *p <= 'Z' |
Midimetric | 0:71d791204057 | 64 | #define TOKEN_LOX *p >= 'a' && *p <= 'f' |
Midimetric | 0:71d791204057 | 65 | #define TOKEN_UPX *p >= 'A' && *p <= 'F' |
Midimetric | 0:71d791204057 | 66 | |
Midimetric | 0:71d791204057 | 67 | class ParseEntry |
Midimetric | 0:71d791204057 | 68 | { |
Midimetric | 0:71d791204057 | 69 | public: |
Midimetric | 0:71d791204057 | 70 | char Name[17]; |
Midimetric | 0:71d791204057 | 71 | ParseEntry( char* name ) |
Midimetric | 0:71d791204057 | 72 | { |
Midimetric | 0:71d791204057 | 73 | short i = 0; |
Midimetric | 0:71d791204057 | 74 | for( i = 0 ; i < 16 && name[i] ; i++ ) |
Midimetric | 0:71d791204057 | 75 | { |
Midimetric | 0:71d791204057 | 76 | if( name[i] >= 'A' && name[i]<='Z' ) Name[i] = name[i] + 32; else Name[i] = name[i]; |
Midimetric | 0:71d791204057 | 77 | } |
Midimetric | 0:71d791204057 | 78 | Name[i] = 0; |
Midimetric | 0:71d791204057 | 79 | } |
Midimetric | 0:71d791204057 | 80 | virtual ~ParseEntry() {} |
Midimetric | 0:71d791204057 | 81 | |
Midimetric | 0:71d791204057 | 82 | virtual bool Parse( char* data ){ return true; } |
Midimetric | 0:71d791204057 | 83 | }; |
Midimetric | 0:71d791204057 | 84 | class ParseFlag : public ParseEntry |
Midimetric | 0:71d791204057 | 85 | { |
Midimetric | 0:71d791204057 | 86 | public: |
Midimetric | 0:71d791204057 | 87 | int Flag; |
Midimetric | 0:71d791204057 | 88 | ParseFlag( char* name ) : ParseEntry( name ), Flag(0) {} |
Midimetric | 0:71d791204057 | 89 | virtual ~ParseFlag(){} |
Midimetric | 0:71d791204057 | 90 | virtual bool Parse( char* data ) |
Midimetric | 0:71d791204057 | 91 | { |
Midimetric | 0:71d791204057 | 92 | if( *data == '*' ) |
Midimetric | 0:71d791204057 | 93 | { |
Midimetric | 0:71d791204057 | 94 | Flag = NAKW; |
Midimetric | 0:71d791204057 | 95 | return true; |
Midimetric | 0:71d791204057 | 96 | } |
Midimetric | 0:71d791204057 | 97 | Flag = 0; |
Midimetric | 0:71d791204057 | 98 | for( int i = 0 ; i < 16 ; i++ ) |
Midimetric | 0:71d791204057 | 99 | if( data[i] == 0 ) break; |
Midimetric | 0:71d791204057 | 100 | else if( data[i] != '-' ) Flag |= 1 << i; |
Midimetric | 0:71d791204057 | 101 | return true; |
Midimetric | 0:71d791204057 | 102 | } |
Midimetric | 0:71d791204057 | 103 | }; |
Midimetric | 0:71d791204057 | 104 | class ParseByte : public ParseEntry |
Midimetric | 0:71d791204057 | 105 | { |
Midimetric | 0:71d791204057 | 106 | public: |
Midimetric | 0:71d791204057 | 107 | byte Mini; |
Midimetric | 0:71d791204057 | 108 | byte Maxi; |
Midimetric | 0:71d791204057 | 109 | ParseByte( char* name ) : ParseEntry( name ),Mini(NAKN), Maxi(NAKN) {} |
Midimetric | 0:71d791204057 | 110 | virtual ~ParseByte(){} |
Midimetric | 0:71d791204057 | 111 | virtual bool Parse( char* data ) |
Midimetric | 0:71d791204057 | 112 | { |
Midimetric | 0:71d791204057 | 113 | if( *data == '*' ) |
Midimetric | 0:71d791204057 | 114 | { |
Midimetric | 0:71d791204057 | 115 | Mini = NAKN; |
Midimetric | 0:71d791204057 | 116 | Maxi = NAKN; |
Midimetric | 0:71d791204057 | 117 | return true; |
Midimetric | 0:71d791204057 | 118 | } |
Midimetric | 0:71d791204057 | 119 | |
Midimetric | 0:71d791204057 | 120 | int base = 10; |
Midimetric | 0:71d791204057 | 121 | bool start = true; |
Midimetric | 0:71d791204057 | 122 | int dot = 0; |
Midimetric | 0:71d791204057 | 123 | char set[] = "0123456789ABCDEF$."; |
Midimetric | 0:71d791204057 | 124 | char* p; |
Midimetric | 0:71d791204057 | 125 | bool ok = false; |
Midimetric | 0:71d791204057 | 126 | |
Midimetric | 0:71d791204057 | 127 | Mini = 0; |
Midimetric | 0:71d791204057 | 128 | |
Midimetric | 0:71d791204057 | 129 | while( *data ) |
Midimetric | 0:71d791204057 | 130 | { |
Midimetric | 0:71d791204057 | 131 | ok = false; |
Midimetric | 0:71d791204057 | 132 | p = strchr( set, *data++ ); |
Midimetric | 0:71d791204057 | 133 | if( p ) |
Midimetric | 0:71d791204057 | 134 | { |
Midimetric | 0:71d791204057 | 135 | int index = p - set; |
Midimetric | 0:71d791204057 | 136 | |
Midimetric | 0:71d791204057 | 137 | if( index==16 && start==true ) { start=false; base=16, ok=true; } |
Midimetric | 0:71d791204057 | 138 | else if( index == 17 && dot < 3 ) { dot++; if( dot==3) { start=true; base=10; Maxi = 0; ok=true; } } |
Midimetric | 0:71d791204057 | 139 | else if( index < base ) { if( dot==3 ) { start=false; Maxi = Maxi * base + index; ok=true; } |
Midimetric | 0:71d791204057 | 140 | else { start=false; Mini = Mini * base + index; ok=true; } } |
Midimetric | 0:71d791204057 | 141 | else break; |
Midimetric | 0:71d791204057 | 142 | } |
Midimetric | 0:71d791204057 | 143 | else break; |
Midimetric | 0:71d791204057 | 144 | } |
Midimetric | 0:71d791204057 | 145 | if( ! ok ) abort( PARSE_BAD_NUMBER_DEFINITION ) |
Midimetric | 0:71d791204057 | 146 | if( Maxi != NAKN && Mini > Maxi ) abort( PARSE_MIN_GREATER_THAN_MAX ) |
Midimetric | 0:71d791204057 | 147 | return true; |
Midimetric | 0:71d791204057 | 148 | } |
Midimetric | 0:71d791204057 | 149 | }; |
Midimetric | 0:71d791204057 | 150 | class ParseShort : public ParseEntry |
Midimetric | 0:71d791204057 | 151 | { |
Midimetric | 0:71d791204057 | 152 | public: |
Midimetric | 0:71d791204057 | 153 | short Mini; |
Midimetric | 0:71d791204057 | 154 | short Maxi; |
Midimetric | 0:71d791204057 | 155 | ParseShort( char* name ) : ParseEntry( name ),Mini(NAKW), Maxi(NAKW) {} |
Midimetric | 0:71d791204057 | 156 | virtual ~ParseShort(){} |
Midimetric | 0:71d791204057 | 157 | virtual bool Parse( char* data ) |
Midimetric | 0:71d791204057 | 158 | { |
Midimetric | 0:71d791204057 | 159 | if( *data == '*' ) |
Midimetric | 0:71d791204057 | 160 | { |
Midimetric | 0:71d791204057 | 161 | Mini = NAKW; |
Midimetric | 0:71d791204057 | 162 | Maxi = NAKW; |
Midimetric | 0:71d791204057 | 163 | return true; |
Midimetric | 0:71d791204057 | 164 | } |
Midimetric | 0:71d791204057 | 165 | int base = 10; |
Midimetric | 0:71d791204057 | 166 | bool start = true; |
Midimetric | 0:71d791204057 | 167 | int dot = 0; |
Midimetric | 0:71d791204057 | 168 | char set[] = "0123456789ABCDEF$."; |
Midimetric | 0:71d791204057 | 169 | char* p; |
Midimetric | 0:71d791204057 | 170 | bool ok = false; |
Midimetric | 0:71d791204057 | 171 | |
Midimetric | 0:71d791204057 | 172 | Mini = 0; |
Midimetric | 0:71d791204057 | 173 | |
Midimetric | 0:71d791204057 | 174 | while( *data ) |
Midimetric | 0:71d791204057 | 175 | { |
Midimetric | 0:71d791204057 | 176 | ok = false; |
Midimetric | 0:71d791204057 | 177 | p = strchr( set, *data++ ); |
Midimetric | 0:71d791204057 | 178 | if( p ) |
Midimetric | 0:71d791204057 | 179 | { |
Midimetric | 0:71d791204057 | 180 | int index = p - set; |
Midimetric | 0:71d791204057 | 181 | |
Midimetric | 0:71d791204057 | 182 | if( index==16 && start==true ) { start=false; base=16, ok=true; } |
Midimetric | 0:71d791204057 | 183 | else if( index == 17 && dot < 3 ) { dot++; if( dot==3) { start=true; base=10; Maxi = 0; ok=true; } } |
Midimetric | 0:71d791204057 | 184 | else if( index < base ) { if( dot==3 ) { start=false; Maxi = Maxi * base + index; ok=true; } |
Midimetric | 0:71d791204057 | 185 | else { start=false; Mini = Mini * base + index; ok=true; } } |
Midimetric | 0:71d791204057 | 186 | else break; |
Midimetric | 0:71d791204057 | 187 | } |
Midimetric | 0:71d791204057 | 188 | else break; |
Midimetric | 0:71d791204057 | 189 | } |
Midimetric | 0:71d791204057 | 190 | if( ! ok ) abort( PARSE_BAD_NUMBER_DEFINITION ) |
Midimetric | 0:71d791204057 | 191 | if( Maxi != NAKW && Mini>Maxi ) abort( PARSE_MIN_GREATER_THAN_MAX ) |
Midimetric | 0:71d791204057 | 192 | return true; |
Midimetric | 0:71d791204057 | 193 | } |
Midimetric | 0:71d791204057 | 194 | }; |
Midimetric | 0:71d791204057 | 195 | class ParseMessage : public ParseEntry |
Midimetric | 0:71d791204057 | 196 | { |
Midimetric | 0:71d791204057 | 197 | public: |
Midimetric | 0:71d791204057 | 198 | byte Code; |
Midimetric | 0:71d791204057 | 199 | ParseMessage( char* name ) : ParseEntry( name ),Code(NAKN) {} |
Midimetric | 0:71d791204057 | 200 | virtual ~ParseMessage(){} |
Midimetric | 0:71d791204057 | 201 | virtual bool Parse( char* data ) |
Midimetric | 0:71d791204057 | 202 | { |
Midimetric | 0:71d791204057 | 203 | static char keywords[] = "NOTE;POLA;CTRL;PROG;BANK;DATA;INCR;DECR;RPN_;NRPN;MONA;BEND;SYSX;TCOD;SPOS;SSEL;TUNE;CLOK;STAR;CONT;STOP;SENS;RSET"; |
Midimetric | 0:71d791204057 | 204 | |
Midimetric | 0:71d791204057 | 205 | char* p = strstr( keywords, data ); |
Midimetric | 0:71d791204057 | 206 | if( p == NULL ) abort( PARSE_BAD_MESSAGE_DEFINITION ) |
Midimetric | 0:71d791204057 | 207 | |
Midimetric | 0:71d791204057 | 208 | Code = ( p - keywords ) / 5 + 1; |
Midimetric | 0:71d791204057 | 209 | return true; |
Midimetric | 0:71d791204057 | 210 | } |
Midimetric | 0:71d791204057 | 211 | }; |
Midimetric | 0:71d791204057 | 212 | |
Midimetric | 0:71d791204057 | 213 | #define PUSH(x) Sequence.push_back(x) |
Midimetric | 0:71d791204057 | 214 | |
Midimetric | 0:71d791204057 | 215 | class ParseSequence : public ParseEntry |
Midimetric | 0:71d791204057 | 216 | { |
Midimetric | 0:71d791204057 | 217 | public: |
Midimetric | 0:71d791204057 | 218 | vector<short> Sequence; |
Midimetric | 0:71d791204057 | 219 | ParseSequence( char* name ) : ParseEntry(name) {} |
Midimetric | 0:71d791204057 | 220 | virtual ~ParseSequence() { } |
Midimetric | 0:71d791204057 | 221 | |
Midimetric | 0:71d791204057 | 222 | virtual bool Parse( char* data ) |
Midimetric | 0:71d791204057 | 223 | { |
Midimetric | 0:71d791204057 | 224 | if( *data == '*' ) |
Midimetric | 0:71d791204057 | 225 | { |
Midimetric | 0:71d791204057 | 226 | Sequence = vector<short>( 1, RAW ); |
Midimetric | 0:71d791204057 | 227 | return true; |
Midimetric | 0:71d791204057 | 228 | } |
Midimetric | 0:71d791204057 | 229 | char* p = data; |
Midimetric | 0:71d791204057 | 230 | if( SubParse( p ) ) |
Midimetric | 0:71d791204057 | 231 | { |
Midimetric | 0:71d791204057 | 232 | Sequence.push_back(NOP); |
Midimetric | 0:71d791204057 | 233 | return true; |
Midimetric | 0:71d791204057 | 234 | } |
Midimetric | 0:71d791204057 | 235 | return false; |
Midimetric | 0:71d791204057 | 236 | } |
Midimetric | 0:71d791204057 | 237 | short SubParse( char* &p ) // returns the number of arguments in the sub-sequence |
Midimetric | 0:71d791204057 | 238 | { |
Midimetric | 0:71d791204057 | 239 | static int level = 0; |
Midimetric | 0:71d791204057 | 240 | level++; |
Midimetric | 0:71d791204057 | 241 | |
Midimetric | 0:71d791204057 | 242 | int args = 0; |
Midimetric | 0:71d791204057 | 243 | |
Midimetric | 0:71d791204057 | 244 | while( *p ) |
Midimetric | 0:71d791204057 | 245 | { |
Midimetric | 0:71d791204057 | 246 | int num = 0; |
Midimetric | 0:71d791204057 | 247 | |
Midimetric | 0:71d791204057 | 248 | switch( *p ) |
Midimetric | 0:71d791204057 | 249 | { |
Midimetric | 0:71d791204057 | 250 | case '=': |
Midimetric | 0:71d791204057 | 251 | case ',': p++; break; |
Midimetric | 0:71d791204057 | 252 | case ')': p++; level--; return args; |
Midimetric | 0:71d791204057 | 253 | |
Midimetric | 0:71d791204057 | 254 | case '$': while( 1 ) { |
Midimetric | 0:71d791204057 | 255 | p++; if( TOKEN_END ) { PUSH( num ); break; } |
Midimetric | 0:71d791204057 | 256 | else if( TOKEN_NUM ) num = num * 16 + (*p - 48 ); |
Midimetric | 0:71d791204057 | 257 | else if( TOKEN_UPX ) num = num * 16 + (*p - 55 ); |
Midimetric | 0:71d791204057 | 258 | else if( TOKEN_LOX ) num = num * 16 + (*p - 87 ); |
Midimetric | 0:71d791204057 | 259 | else abort( PARSE_BAD_SEQ_HEXA_SIGN ) |
Midimetric | 0:71d791204057 | 260 | } args++; break; |
Midimetric | 0:71d791204057 | 261 | |
Midimetric | 0:71d791204057 | 262 | case '%': { char fn[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; int i = 0; |
Midimetric | 0:71d791204057 | 263 | while( 1 ) { |
Midimetric | 0:71d791204057 | 264 | p++; if( TOKEN_END ) break; |
Midimetric | 0:71d791204057 | 265 | else if( TOKEN_NUM ) fn[i++] = *p; |
Midimetric | 0:71d791204057 | 266 | else if( TOKEN_UPP ) fn[i++] = *p + 32; |
Midimetric | 0:71d791204057 | 267 | else if( TOKEN_LOW ) fn[i++] = *p; |
Midimetric | 0:71d791204057 | 268 | else abort( PARSE_BAD_SEQ_IDENTIFIER ) |
Midimetric | 0:71d791204057 | 269 | if( i == 16 ) abort( PARSE_BAD_SEQ_TOOLONG ) |
Midimetric | 0:71d791204057 | 270 | } |
Midimetric | 0:71d791204057 | 271 | if( strcmp( fn, "mc") == 0 ) PUSH( VMC ); |
Midimetric | 0:71d791204057 | 272 | else if( strcmp( fn, "m" ) == 0 ) PUSH( VM_ ); |
Midimetric | 0:71d791204057 | 273 | else if( strcmp( fn, "c" ) == 0 ) PUSH( VC_ ); |
Midimetric | 0:71d791204057 | 274 | else if( strcmp( fn, "a" ) == 0 ) PUSH( VA_ ); |
Midimetric | 0:71d791204057 | 275 | else if( strcmp( fn, "b" ) == 0 ) PUSH( VB_ ); |
Midimetric | 0:71d791204057 | 276 | else if( strcmp( fn, "n" ) == 0 ) PUSH( VN_ ); |
Midimetric | 0:71d791204057 | 277 | else if( strcmp( fn, "d" ) == 0 ) PUSH( VD_ ); |
Midimetric | 0:71d791204057 | 278 | else if( strcmp( fn, "k" ) == 0 ) PUSH( VK_ ); |
Midimetric | 0:71d791204057 | 279 | else { |
Midimetric | 0:71d791204057 | 280 | for( int j = 0 ; j < i ; j++ ) |
Midimetric | 0:71d791204057 | 281 | PUSH( CID + fn[j] ); |
Midimetric | 0:71d791204057 | 282 | PUSH( CID ); |
Midimetric | 0:71d791204057 | 283 | } |
Midimetric | 0:71d791204057 | 284 | } args++; break; |
Midimetric | 0:71d791204057 | 285 | |
Midimetric | 0:71d791204057 | 286 | default: if( TOKEN_UPP ) *p += 32; |
Midimetric | 0:71d791204057 | 287 | |
Midimetric | 0:71d791204057 | 288 | if( TOKEN_LOW ) { char fn[] = {*p,0,0,0,0,0,0,0,0,0}; int i = 1; |
Midimetric | 0:71d791204057 | 289 | while( 1 ) { |
Midimetric | 0:71d791204057 | 290 | p++; if( *p == '(' ) break; |
Midimetric | 0:71d791204057 | 291 | else if( TOKEN_UPP ) fn[i++] = *p + 32; |
Midimetric | 0:71d791204057 | 292 | else if( TOKEN_LOW ) fn[i++] = *p; |
Midimetric | 0:71d791204057 | 293 | else if( TOKEN_NUM ) fn[i++] = *p; |
Midimetric | 0:71d791204057 | 294 | else abort(PARSE_BAD_SEQ_FUNCTION) |
Midimetric | 0:71d791204057 | 295 | } |
Midimetric | 0:71d791204057 | 296 | p++; // skip ( |
Midimetric | 0:71d791204057 | 297 | if( level == 1 ) PUSH( SEQ ); |
Midimetric | 0:71d791204057 | 298 | short a = SubParse( p ); |
Midimetric | 0:71d791204057 | 299 | if( a == 0 ) return 0; |
Midimetric | 0:71d791204057 | 300 | int n = GetOPIDfromFunction( fn ); |
Midimetric | 0:71d791204057 | 301 | if( n == 0 ) abort(PARSE_BAD_SEQ_FUNCTION) |
Midimetric | 0:71d791204057 | 302 | if( n == MAP ) PUSH( a ); |
Midimetric | 0:71d791204057 | 303 | PUSH( n ); |
Midimetric | 0:71d791204057 | 304 | if( level==1 && n!=E8_ && n!=E14 && n!=RPN && n!=NPN && n!=BNK && n!=NP8 ) PUSH( E7_ ); |
Midimetric | 0:71d791204057 | 305 | args++; |
Midimetric | 0:71d791204057 | 306 | break; |
Midimetric | 0:71d791204057 | 307 | } |
Midimetric | 0:71d791204057 | 308 | if( TOKEN_NUM ) { |
Midimetric | 0:71d791204057 | 309 | num = *p - 48; |
Midimetric | 0:71d791204057 | 310 | while( 1 ) { |
Midimetric | 0:71d791204057 | 311 | p++; if( TOKEN_END ) { PUSH( num ); break; } |
Midimetric | 0:71d791204057 | 312 | else if( TOKEN_NUM ) num = num * 10 + (*p - 48 ); |
Midimetric | 0:71d791204057 | 313 | else abort( PARSE_BAD_SEQ_NUMBER ) |
Midimetric | 0:71d791204057 | 314 | } args++; break; |
Midimetric | 0:71d791204057 | 315 | } |
Midimetric | 0:71d791204057 | 316 | abort( PARSE_BAD_SEQ_SYNTAXE ) |
Midimetric | 0:71d791204057 | 317 | } |
Midimetric | 0:71d791204057 | 318 | } |
Midimetric | 0:71d791204057 | 319 | level--; |
Midimetric | 0:71d791204057 | 320 | return args; |
Midimetric | 0:71d791204057 | 321 | } |
Midimetric | 0:71d791204057 | 322 | }; |
Midimetric | 0:71d791204057 | 323 | |
Midimetric | 0:71d791204057 | 324 | class ParseRoute |
Midimetric | 0:71d791204057 | 325 | { |
Midimetric | 0:71d791204057 | 326 | public : |
Midimetric | 0:71d791204057 | 327 | byte Inport; |
Midimetric | 0:71d791204057 | 328 | byte Message; |
Midimetric | 0:71d791204057 | 329 | short Channels; |
Midimetric | 0:71d791204057 | 330 | short minA; |
Midimetric | 0:71d791204057 | 331 | short maxA; |
Midimetric | 0:71d791204057 | 332 | short minB; |
Midimetric | 0:71d791204057 | 333 | short maxB; |
Midimetric | 0:71d791204057 | 334 | vector<byte> Head; |
Midimetric | 0:71d791204057 | 335 | vector<short> Sequence1; |
Midimetric | 0:71d791204057 | 336 | vector<short> Sequence2; |
Midimetric | 0:71d791204057 | 337 | vector<short> Sequence3; |
Midimetric | 0:71d791204057 | 338 | vector<Assignment*> Assigns; |
Midimetric | 0:71d791204057 | 339 | |
Midimetric | 0:71d791204057 | 340 | ParseRoute() : Inport(0), Message(NAKN), Channels(NAKW), minA(NAKN), maxA(NAKN), minB(NAKN), maxB(NAKN) {} |
Midimetric | 0:71d791204057 | 341 | ~ParseRoute() |
Midimetric | 0:71d791204057 | 342 | { |
Midimetric | 0:71d791204057 | 343 | } |
Midimetric | 0:71d791204057 | 344 | bool Add( ParseEntry* entry ) |
Midimetric | 0:71d791204057 | 345 | { |
Midimetric | 0:71d791204057 | 346 | ParseMessage* m = (ParseMessage*)entry; |
Midimetric | 0:71d791204057 | 347 | ParseFlag* f = (ParseFlag*)entry; |
Midimetric | 0:71d791204057 | 348 | ParseByte* b = (ParseByte*)entry; |
Midimetric | 0:71d791204057 | 349 | ParseShort* s = (ParseShort*)entry; |
Midimetric | 0:71d791204057 | 350 | ParseSequence* q = (ParseSequence*)entry; |
Midimetric | 0:71d791204057 | 351 | |
Midimetric | 0:71d791204057 | 352 | if( strcmp( entry->Name, "input1" ) == 0 ) { Inport = 0; Message = m->Code; return true; } |
Midimetric | 0:71d791204057 | 353 | else if( strcmp( entry->Name, "input2" ) == 0 ) { Inport = 1; Message = m->Code; return true; } |
Midimetric | 0:71d791204057 | 354 | else if( strcmp( entry->Name, "input3" ) == 0 ) { Inport = 2; Message = m->Code; return true; } |
Midimetric | 0:71d791204057 | 355 | else if( strcmp( entry->Name, "channels" ) == 0 ) { Channels = f->Flag; return true; } |
Midimetric | 0:71d791204057 | 356 | else if( strcmp( entry->Name, "program" ) == 0 ) { minA = b->Mini; maxA = b->Maxi; return true; } |
Midimetric | 0:71d791204057 | 357 | else if( strcmp( entry->Name, "valuea" ) == 0 ) { minA = b->Mini; maxA = b->Maxi; return true; } |
Midimetric | 0:71d791204057 | 358 | else if( strcmp( entry->Name, "valueb" ) == 0 ) { minB = b->Mini; maxB = b->Maxi; return true; } |
Midimetric | 0:71d791204057 | 359 | else if( strcmp( entry->Name, "parameter") == 0 ) { minA = s->Mini; maxA = s->Maxi; return true; } |
Midimetric | 0:71d791204057 | 360 | else if( strcmp( entry->Name, "data" ) == 0 ) { minB = s->Mini; maxB = s->Maxi; return true; } |
Midimetric | 0:71d791204057 | 361 | else if( strcmp( entry->Name, "bank" ) == 0 ) { minA = s->Mini; maxA = s->Maxi; return true; } |
Midimetric | 0:71d791204057 | 362 | else if( strcmp( entry->Name, "output1" ) == 0 ) { Sequence1.insert( Sequence1.end(), q->Sequence.begin(), q->Sequence.end() ); return true; } |
Midimetric | 0:71d791204057 | 363 | else if( strcmp( entry->Name, "output2" ) == 0 ) { Sequence2.insert( Sequence2.end(), q->Sequence.begin(), q->Sequence.end() ); return true; } |
Midimetric | 0:71d791204057 | 364 | else if( strcmp( entry->Name, "output3" ) == 0 ) { Sequence3.insert( Sequence3.end(), q->Sequence.begin(), q->Sequence.end() ); return true; } |
Midimetric | 0:71d791204057 | 365 | else if( strcmp( entry->Name, "header" ) == 0 ) { Head.insert( Head.end(), q->Sequence.begin(), q->Sequence.end() ); return true; } |
Midimetric | 0:71d791204057 | 366 | else if( entry->Name[0] == '%' ) { Assigns.push_back( new Assignment( entry->Name + 1 /* skip the %*/, q->Sequence ) ); return true; } |
Midimetric | 0:71d791204057 | 367 | ParseError = PARSE_UNKNWON_ENTRY; |
Midimetric | 0:71d791204057 | 368 | return false; |
Midimetric | 0:71d791204057 | 369 | } |
Midimetric | 0:71d791204057 | 370 | bool Done() |
Midimetric | 0:71d791204057 | 371 | { |
Midimetric | 0:71d791204057 | 372 | FL.Add( Inport, Message, Channels, minA, maxA, minB, maxB, Head, Sequence1, Sequence2, Sequence3, Assigns ); |
Midimetric | 0:71d791204057 | 373 | return true; |
Midimetric | 0:71d791204057 | 374 | } |
Midimetric | 0:71d791204057 | 375 | }; |
Midimetric | 0:71d791204057 | 376 | |
Midimetric | 0:71d791204057 | 377 | const char keywords_flag[] = "channels"; |
Midimetric | 0:71d791204057 | 378 | const char keywords_nums[] = "valueA valueB program"; |
Midimetric | 0:71d791204057 | 379 | const char keywords_nu14[] = "parameter data bank"; |
Midimetric | 0:71d791204057 | 380 | const char keywords_mess[] = "input1 input2 input3"; |
Midimetric | 0:71d791204057 | 381 | const char keywords_sequ[] = "output1 output2 output3 header"; |
Midimetric | 0:71d791204057 | 382 | |
Midimetric | 0:71d791204057 | 383 | bool Parse() |
Midimetric | 0:71d791204057 | 384 | { |
Midimetric | 0:71d791204057 | 385 | char Line1[256]; |
Midimetric | 0:71d791204057 | 386 | char Line2[256]; |
Midimetric | 0:71d791204057 | 387 | LocalFileSystem local("local"); |
Midimetric | 0:71d791204057 | 388 | FILE* f = fopen( "/local/filter.txt", "r" ); |
Midimetric | 0:71d791204057 | 389 | if( f == NULL ) |
Midimetric | 0:71d791204057 | 390 | { |
Midimetric | 0:71d791204057 | 391 | ParseError = PARSE_NO_FILE; |
Midimetric | 0:71d791204057 | 392 | return false; |
Midimetric | 0:71d791204057 | 393 | } |
Midimetric | 0:71d791204057 | 394 | ParseRoute* pr = NULL; |
Midimetric | 0:71d791204057 | 395 | ParseLine = 0; |
Midimetric | 0:71d791204057 | 396 | while( /* ( ParseLine < 200 ) && */ fgets( Line1, 256, f ) ) |
Midimetric | 0:71d791204057 | 397 | { |
Midimetric | 0:71d791204057 | 398 | ParseLine++; |
Midimetric | 0:71d791204057 | 399 | ParseEntry* sp = NULL; |
Midimetric | 0:71d791204057 | 400 | |
Midimetric | 0:71d791204057 | 401 | ParseCleanUp( Line1, Line2 ); |
Midimetric | 0:71d791204057 | 402 | strtok( Line2, ":" ); |
Midimetric | 0:71d791204057 | 403 | |
Midimetric | 0:71d791204057 | 404 | if( Line2[0] == 0 || Line2[0] == 10 ) continue; |
Midimetric | 0:71d791204057 | 405 | |
Midimetric | 0:71d791204057 | 406 | if( strcmp( Line2, "ROUTE" ) == 0 ) { |
Midimetric | 0:71d791204057 | 407 | if( pr ) if( ! pr->Done() ) goto Bad; |
Midimetric | 0:71d791204057 | 408 | delete pr; |
Midimetric | 0:71d791204057 | 409 | pr = NULL; |
Midimetric | 0:71d791204057 | 410 | int mem = AvailableMemory(); |
Midimetric | 0:71d791204057 | 411 | if( mem < 512 ) { printf("Only %d bytes left for program.\nFilter definitions reading stopped at line %d\n", mem, ParseLine ); break; } |
Midimetric | 0:71d791204057 | 412 | pr = new ParseRoute(); |
Midimetric | 0:71d791204057 | 413 | } |
Midimetric | 0:71d791204057 | 414 | else if( strstr( keywords_flag, Line2 ) ) sp = new ParseFlag( Line2 ); |
Midimetric | 0:71d791204057 | 415 | else if( strstr( keywords_nums, Line2 ) ) sp = new ParseByte( Line2 ); |
Midimetric | 0:71d791204057 | 416 | else if( strstr( keywords_nu14, Line2 ) ) sp = new ParseShort( Line2 ); |
Midimetric | 0:71d791204057 | 417 | else if( strstr( keywords_mess, Line2 ) ) sp = new ParseMessage( Line2 ); |
Midimetric | 0:71d791204057 | 418 | else if( strstr( keywords_sequ, Line2 ) ) sp = new ParseSequence(Line2 ); |
Midimetric | 0:71d791204057 | 419 | else if( Line2[0] == '%' ) sp = new ParseSequence(Line2 ); |
Midimetric | 0:71d791204057 | 420 | else { ParseError = PARSE_UNKNWON_ENTRY; goto Bad; } |
Midimetric | 0:71d791204057 | 421 | |
Midimetric | 0:71d791204057 | 422 | if( sp != NULL ) |
Midimetric | 0:71d791204057 | 423 | { |
Midimetric | 0:71d791204057 | 424 | if( pr == NULL ) goto Bad; |
Midimetric | 0:71d791204057 | 425 | if( ! sp->Parse( strtok( NULL, "\n" ) ) ) goto Bad; |
Midimetric | 0:71d791204057 | 426 | if( ! pr->Add( sp ) ) goto Bad; |
Midimetric | 0:71d791204057 | 427 | delete sp; |
Midimetric | 0:71d791204057 | 428 | } |
Midimetric | 0:71d791204057 | 429 | } |
Midimetric | 0:71d791204057 | 430 | |
Midimetric | 0:71d791204057 | 431 | if( pr ) if( ! pr->Done() ) goto Bad; |
Midimetric | 0:71d791204057 | 432 | |
Midimetric | 0:71d791204057 | 433 | fclose( f ); |
Midimetric | 0:71d791204057 | 434 | return true; |
Midimetric | 0:71d791204057 | 435 | Bad: |
Midimetric | 0:71d791204057 | 436 | if( f != NULL ) fclose(f); |
Midimetric | 0:71d791204057 | 437 | return false; |
Midimetric | 0:71d791204057 | 438 | } |
Midimetric | 0:71d791204057 | 439 | |
Midimetric | 0:71d791204057 | 440 | #undef abort |
Midimetric | 0:71d791204057 | 441 | #undef TOKEN_END |
Midimetric | 0:71d791204057 | 442 | #undef TOKEN_NUM |
Midimetric | 0:71d791204057 | 443 | #undef TOKEN_LOW |
Midimetric | 0:71d791204057 | 444 | #undef TOKEN_UPP |
Midimetric | 0:71d791204057 | 445 | #undef TOKEN_LOX |
Midimetric | 0:71d791204057 | 446 | #undef TOKEN_UPX |
Midimetric | 0:71d791204057 | 447 | |
Midimetric | 0:71d791204057 | 448 | #endif |