#include #include namespace Music { void Scanner::init(const String &chordSymbol) { remove(); mIndex=0; mLength=chordSymbol.length(); if(!mLength)return; mSymbol=chordSymbol; } char Scanner::peekChar(void) { if(mIndex>=mLength)return -1; return mSymbol.charAt(mIndex); } char Scanner::nextChar() { if(mIndex+1>mLength)return -1; return mSymbol.charAt(mIndex++); } void Scanner::pushBack(void) { if(!mIndex)return; mIndex--; } bool Scanner::scan(const String &chordSymbol) { char symbol; init(chordSymbol); while(-1!=(symbol=nextChar())) { if(isInflection(symbol)) scanInflection(symbol); else if('/'==symbol) scanSlash(); else if(isdigit(symbol)) scanDegree(symbol); else if('^'==symbol||'-'==symbol) scanMnemonic(symbol); else if(isalpha(symbol)) scanAlpha(symbol); else return false; } emit(ScanSymbols::Stop1); if(size()<=1)return false; return true; } void Scanner::scanAlpha(char symbol) { char nextChar; if(isNote(symbol)) { emit(ScanSymbols::Note1,Byte(symbol)); } else if(isalpha(symbol)&&!isInflection(symbol)&&!isHalfDiminished(symbol)&&!isDiminished(symbol)) { string verb; verb+=tolower(symbol); while(-1!=(nextChar=this->nextChar())) { if(!isalpha(nextChar)||isInflection(nextChar)) { pushBack(); break; } verb+=tolower(nextChar); } emit(ScanSymbols::Verb1,verb); } else if(isalpha(symbol)&&isInflection(symbol)) { string verb; emit(ScanSymbols::Note1,Byte(symbol)); symbol=this->nextChar(); scanInflection(symbol); while(-1!=(nextChar=this->nextChar())) { if(!isalpha(nextChar)||isInflection(nextChar)) { pushBack(); break; } verb+=tolower(nextChar); } emit(ScanSymbols::Verb1,verb); } else if(isalpha(symbol)&&isHalfDiminished(symbol)) { emit(ScanSymbols::HalfDiminished1); } else if(isalpha(symbol)&&isDiminished(symbol)) { emit(ScanSymbols::Diminished1); } else emit(ScanSymbols::Note1,Byte(symbol)); } bool Scanner::isNote(char symbol) { if('A'==symbol||'B'==symbol||'C'==symbol||'D'==symbol||'E'==symbol||'F'==symbol||'G'==symbol)return true; return false; } bool Scanner::isInflection(char symbol) { if('b'==symbol||'#'==symbol)return true; return false; } bool Scanner::isHalfDiminished(char symbol) { if('h'==symbol)return true; return false; } bool Scanner::isDiminished(char symbol) { if('o'==symbol)return true; return false; } void Scanner::scanDegree(char symbol) { String str; str+=symbol; while(-1!=(symbol=peekChar())&&isdigit(symbol)) { symbol=nextChar(); str+=symbol; } emit(ScanSymbols::Degree1,Byte(str.toInt())); } void Scanner::scanMnemonic(char symbol) { char nextSymbol; nextSymbol=peekChar(); if(symbol=='-' && nextSymbol=='^') { emit(ScanSymbols::MinorMajor71); nextChar(); } else if(symbol=='^')emit(ScanSymbols::Major71); else if(symbol=='-')emit(ScanSymbols::Minor1); } void Scanner::scanInflection(char symbol) { if('b'==symbol)emit(ScanSymbols::Alter1,Byte(ScanSymbols::Flat1)); else if('#'==symbol)emit(ScanSymbols::Alter1,Byte(ScanSymbols::Sharp1)); } void Scanner::scanSlash() { emit(ScanSymbols::Slash1); } String Scanner::toString(void)const { return Emitter::toString(); } };