//============================================================================= // BWW to MusicXML converter // Part of MusE Score // Linux Music Score Editor // $Id: lexer.cpp 3793 2010-12-22 21:54:17Z lvinken $ // // Copyright (C) 2010 Werner Schweer and others // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //============================================================================= /** \file BWW file lexical analysis. Loosely based on BWW file format - BNF specification by tjm found in http://forums.bobdunsire.com/forums/showthread.php?t=123219 */ #include #include #include "lexer.h" namespace Bww { /** Lexer constructor, \a inDevice is the input. */ Lexer::Lexer(QIODevice *inDevice) : in(inDevice), lineNumber(-1), value(NONE) { qDebug() << "Lexer::Lexer() begin"; getSym(); qDebug() << "Lexer::Lexer() end"; } /** Get the next symbol, update type and value. */ void Lexer::getSym() { qDebug() << "Lexer::getSym()"; // if unparsed words remaining, use these if (list.size() > 0) { categorizeWord(list.at(0)); list.removeFirst(); return; } // read the next non-empty line do { line = in.readLine(); ++lineNumber; if (line.isNull()) { // end of file qDebug() << "-> end of file"; type = NONE; value = ""; return; } } while (line == ""); qDebug() << "getSym: read line" << line; QRegExp rHeaderIgnore("^Bagpipe Reader|^MIDINoteMappings|^FrequencyMappings" "|^InstrumentMappings|^GracenoteDurations|^FontSizes" "|^TuneFormat"); QRegExp rTuneTempo("^TuneTempo"); if (rHeaderIgnore.indexIn(line) == 0) { type = COMMENT; value = ""; qDebug() << "-> header ignore," << "type:" << symbolToString(type) << "value:" << value ; line = ""; return; } else if (rTuneTempo.indexIn(line) == 0) { type = TEMPO; value = line; qDebug() << "-> tempo," << "type:" << symbolToString(type) << "value:" << value ; line = ""; return; } else if (line.at(0) == '"') { type = STRING; value = line; qDebug() << "-> quoted string," << "type:" << symbolToString(type) << "value:" << value ; line = ""; } else { // split line into space-separated words list = line.trimmed().split(QRegExp("\\s+")); qDebug() << "-> words" << list ; categorizeWord(list.at(0)); list.removeFirst(); } line = ""; } /** Return the current symbols type. */ Symbol Lexer::symType() const { return type; } /** Return the current symbols value. */ QString Lexer::symValue() const { return value; } /** Determine the symbol type for \a word. */ void Lexer::categorizeWord(QString word) { qDebug() << "Lexer::categorizeWord(" << word << ")"; // default values type = NONE; value = word; QRegExp rClef("&"); QRegExp rKey("sharp[cf]"); QRegExp rTSig("\\d+_(1|2|4|8|16|32)"); QRegExp rPart("I!''|I!|''!I|!I|'intro|[2-9]|'[12]|_'"); QRegExp rBar("!|!t|!!t"); QRegExp rNote("(LG|LA|[B-F]|HG|HA)[lr]?_(1|2|4|8|16|32)"); QRegExp rTie("\\^t[es]"); QRegExp rTriplet("\\^3[es]"); QRegExp rDot("'([hl][ag]|[b-f])"); QRegExp rSingleGrace("[a-gt]g"); QRegExp rStrike("str([hl][ag]|[b-f])"); QRegExp rDoubling("db([hl][ag]|[b-f])"); QRegExp rHalfDoubling("hdb([hl][ag]|[b-f])"); QRegExp rThumbDoubling("thdb(l[ag]|[b-f]|hg)"); QRegExp rSlur("l?gstd"); QRegExp rThrow("thrd"); QRegExp rBirl("abr|brl|gbrl|tbrl"); QRegExp rGrip("grp"); QRegExp rTaorluath("tar"); if (rClef.exactMatch(word)) type = CLEF; else if (rKey.exactMatch(word)) type = KEY; else if (rTSig.exactMatch(word)) type = TSIG; else if (rPart.exactMatch(word)) type = PART; else if (rBar.exactMatch(word)) type = BAR; else if (rNote.exactMatch(word)) type = NOTE; else if (rTie.exactMatch(word)) type = TIE; else if (rTriplet.exactMatch(word)) type = TRIPLET; else if (rDot.exactMatch(word)) type = DOT; else if (rSingleGrace.exactMatch(word)) type = SINGLEGRACE; else if (rStrike.exactMatch(word)) type = STRIKE; else if (rDoubling.exactMatch(word)) type = DOUBLING; else if (rHalfDoubling.exactMatch(word)) type = HALFDOUBLING; else if (rThumbDoubling.exactMatch(word)) type = THUMBDOUBLING; else if (rSlur.exactMatch(word)) type = SLUR; else if (rThrow.exactMatch(word)) type = THROW; else if (rBirl.exactMatch(word)) type = BIRL; else if (rGrip.exactMatch(word)) type = GRIP; else if (rTaorluath.exactMatch(word)) type = TAORLUATH; else type = UNKNOWN; qDebug() << " type: " << qPrintable(symbolToString(type)) << " value: '" << qPrintable(value) << "'" ; } } // namespace Bww