#include <stdio.h>
#include "glob.hh"
#include "string.hh"
-
+#include "notename.hh"
#include "lexer.hh"
#include "keyword.hh"
#include "vray.hh"
#include "parser.hh"
#include "debug.hh"
+#include "sstack.hh"
+
+struct Input_file {
+ istream*is;
+ int line;
+ String name;
+
+ Input_file(String);
+ ~Input_file();
+};
+
+/// lexer with provisions for include files.
+struct My_flex_lexer : yyFlexLexer {
+ sstack<Input_file*> include_stack;
+ void new_input(String s);
+ bool close_input();
+};
+
+My_flex_lexer *lexer=0;
-sstack<istream *> include_stack;
static int last_print;
const int DOTPRINT=50; // every 50 lines dots
%}
%x quote
-NOTECOMMAND \\{WORD}
+
+A [a-zA-Z]
+AA {A}|_
+N [0-9]
+AN {AA}|{N}
+
+WORD {A}{AN}*
+ALPHAWORD {A}+
+INT -?{N}+
+REAL {INT}(\.{N}*)?
+
OPTSIGN !?
-NOTENAMEI A|B|C|D|E|F|G|As|Bes|Ces|Des|Es|Fes|Ges|Ais|Bis|Cis|Dis|Eis|Fis|Gis
-NOTENAMEII a|b|c|d|e|f|g|as|bes|ces|des|es|fes|ges|ais|bis|cis|dis|eis|fis|gis
-NOTENAMEIII Ases|Beses|Ceses|Deses|Eses|Feses|Geses|Aisis|Bisis|Cisis|Disis|Eisis|Fisis|Gisis
-NOTENAMEIIII ases|beses|ceses|deses|eses|feses|geses|aisis|bisis|cisis|disis|eisis|fisis|gisis
-RESTNAME r|s
-NOTENAME {NOTENAMEI}|{NOTENAMEII}|{NOTENAMEIII}|{NOTENAMEIIII}
-PITCH ['`]*{OPTSIGN}{NOTENAME}
-DURNAME 1|2|4|8|16|32
-DURATION {DURNAME}\.*
-FULLNOTE {PITCH}{DURATION}?
-WORD [a-zA-Z][a-zA-Z0-9_]+
-REAL -?[0-9]+(\.[0-9]*)?
+PITCHMOD ['`]*{OPTSIGN}
+RESTNAME r|s|p
+NOTECOMMAND \\{WORD}
+NOTENAME {ALPHAWORD}
+DOTS \.+
%%
BEGIN(notes);
}
+<notes>{RESTNAME} {
+ const char *s = YYText();
+ yylval.string = new String (s);
+ mtor << "rest:"<< yylval.string;
+ return RESTNAME;
+}
+
+<notes>{NOTENAME} {
+ int *p=yylval.ii;
+ lookup_notename(p[0], p[1], YYText());
+ mtor << "notename: "<< YYText()<<eol;
+ if (p[0] < 0) {
+ String e("notename does not exist: ");
+ error(e + YYText());
+ }
+ return NOTENAME;
+}
+
<notes>{NOTECOMMAND} {
String c = YYText() +1;
-
+ mtor << "\\word: " << YYText()+1<<eol;
int l = lookup_keyword(c);
if (l != -1)
return l;
return IDENTIFIER;
}
String *sp = new String( c);
- mtor << "new id: " << *sp;
+
yylval.string=sp;
return NEWIDENTIFIER;
}
-<notes>{RESTNAME} {
- const char *s = YYText();
- yylval.string = new String (s);
- mtor << "rest:"<< yylval.string;
- return RESTNAME;
-}
-<notes>{PITCH} {
+<notes>{PITCHMOD} {
const char *s = YYText();
+ mtor << "pitchmod:"<< YYText()<<eol;
yylval.string = new String (s);
- mtor << "pitch:"<< *yylval.string;
- return PITCH;
+ return PITCHMOD;
}
-<notes>{DURATION} {
- yylval.string = new String (YYText());
- return DURATION;
+<notes>{DOTS} {
+ yylval.i = strlen(YYText());
+ return DOTS;
+}
+<notes>{INT} {
+ yylval.i = String(YYText()).value();
+ return INT;
}
<notes>\| {
}
<notes>[:space:]+ {
}
-<notes>[ \t\n]+ {
+<notes>[%#].*\n {
+
}
-<notes>[%#].*$ {
+<notes>[ \t\n]+ {
}
<notes>\$ {
}
<<EOF>> {
- if(!close_input())
- yyterminate();
+ mtor << "<<EOF>>";
+
+ if (! ((My_flex_lexer*) this)->close_input())
+ yyterminate(); // can't move this, since it actually rets a YY_NULL
}
+
{WORD} {
+ mtor << "word: " << YYText()<<eol;
String c = YYText();
int l = lookup_keyword(c);
if (l != -1)
return IDENTIFIER;
}
String *sp = new String( c);
- mtor << "new id: " << *sp;
+ mtor << "new id: " << *sp << eol;
yylval.string=sp;
return NEWIDENTIFIER;
}
Real r;
int cnv=sscanf (YYText(), "%lf", &r);
assert(cnv == 1);
- mtor << "token (REAL)" << r;
+ mtor << "REAL" << r<<'\n';
yylval.real = r;
return REAL;
}
-[\{\}\[\]\(\)] {
+[{}] {
mtor << "parens\n";
return YYText()[0];
%%
-yyFlexLexer *lexer=0;
+int
+yylex() {
+ return lexer->yylex();
+}
+
+void
+yyerror(const char *s)
+{
+ String e;
+ if (lexer->include_stack.empty()) {
+ *mlog << "error at EOF" << s;
+ }else
+ *mlog << lexer->include_stack.top()->name << ": " <<
+ lexer->lineno() << ": error:" << s << '\n';
+ exit(1);
+}
+
bool
busy_parsing()
return lexer;
}
-// set the new input to s, remember old file.
void
-new_input(String s)
-{
- istream *newin ;
-
- if (s=="")
- newin = &cin;
- else
- newin = new ifstream( s ); //
-
- if ( ! *newin)
- error("cant open " + s);
- cout << "["<<s<<flush;
-
- include_stack.push(newin);
+kill_lexer()
+{
+ delete lexer;
+ lexer = 0;
+}
- if (!lexer) {
- lexer = new yyFlexLexer;
- lexer->set_debug( !monitor.silence("Lexer"));
+void
+new_input(String s)
+{
+ if (!lexer) {
+ lexer = new My_flex_lexer;
+ lexer->set_debug( !monitor.silence("Lexer") && check_debug);
}
-
- lexer->switch_streams(newin);
+ lexer->new_input(s);
}
+/****************/
-// pop the inputstack.
-bool
-close_input()
+Input_file::Input_file(String s)
{
-
- istream *closing= include_stack.pop();
- if (closing != &cin)
- delete closing;
-
- cout << "]" << flush;
-
- if (include_stack.empty()) {
- return false ;
- } else
- lexer->switch_streams(include_stack.top());
- return true;
+ name = s;
+ line = 1;
+ if (s=="")
+ is = &cin;
+ else
+ is = new ifstream( s ); //
+
+ if ( ! *is) {
+ String e("cant open " + s);
+ if (lexer)
+ yyerror(e);
+ else
+ error(e);
+ }
+ cout << "["<<s<<flush;
}
-int
-yylex() {
- return lexer->yylex();
+Input_file::~Input_file()
+{
+ if (is != &cin)
+ delete is;
+ cout << "]" << flush;
}
+/****************/
+// set the new input to s, remember old file.
void
-yyerror(const char *s)
-{
- *mlog << "error in line " << lexer->lineno() << ": " << s << '\n';
- exit(1);
+My_flex_lexer::new_input(String s)
+{
+ if (!include_stack.empty())
+ include_stack.top()->line = lineno();
+
+ Input_file *newin = new Input_file(s);
+ include_stack.push(newin);
+ switch_streams(newin->is);
+ yylineno = 1;
}
-void
-kill_lexer()
+// pop the inputstack.
+bool
+My_flex_lexer::close_input()
{
- delete lexer;
- lexer = 0;
+ Input_file *old = include_stack.pop();
+ bool ok = true;
+ if (include_stack.empty()) {
+ ok = false;
+ } else {
+ Input_file *i = include_stack.top();
+ switch_streams(i->is);
+ yylineno = i->line;
+ }
+ delete old;
+ return ok;
}
int default_duration = 4, default_dots=0, default_octave=0;
-void
-parse_duration(const char *a, int &j, int &intdur, int &dots)
-{
- String durstr;
- while (isdigit(a[j]))
- {
- durstr += a[j++];
- }
-
- dots=default_dots;
-
- while (a[j] == '.')
- {
- j++;
- dots++;
- }
-
- intdur = (durstr.len()) ?
- durstr.value():default_duration;
-
- mtor << "dur " << intdur << "dots " << dots<<eol;
-}
-
-
void
parse_octave (const char *a, int &j, int &oct)
{
}
void
-parse_pitch( const char *a, int &j, int &oct, bool & overide_acc,
- int & large, int & small)
+parse_pitchmod( const char *a, int &j, int &oct, bool & overide_acc)
{
// octave
oct =default_octave;
parse_octave(a,j,oct);
-
- mtor << "oct " << oct;
// accidental
overide_acc = false;
j++;
}
-
- // notename.
- String nm;
- while (isalpha(a[j]))
- {
- nm += a[j++];
- }
- if (isupper(nm[0]))
- {
- oct--;
- nm.lower();
- }
-
-
- lookup_notename(large,small,nm);
- mtor << "override: " << overide_acc;
- mtor << "pitch "<< large <<", "<<small<<"\n";
+ mtor << "oct " << oct;
+ mtor << "override: " << overide_acc;
}
Voice_element *
-get_note_element(String pitch, String durstr)
+get_note_element(String pitch, int * notename, int * duration )
{
Voice_element*v = new Voice_element;
int i=0;
- int dur, dots;
- parse_duration(durstr, i, dur, dots);
- i=0;
-
+ int dur = duration[0];
+ int dots=duration[1];
+
Note_req * rq = new Note_req;
if (dur >= 2) {
v->add(st);
}
- int oct, pit, acc;
+ int oct;
bool forceacc;
- parse_pitch(pitch, i, oct, forceacc, pit, acc);
- rq->name =pit;
-
+ parse_pitchmod(pitch, i, oct, forceacc);
+ rq->name =notename[0];
+ rq->accidental = notename[1];
rq->octave = oct;
- rq->accidental = acc;
rq->forceacc = forceacc;
rq->balltype = dur;
rq->dots = dots;
}
Voice_element *
-get_rest_element(String, String durstr)
+get_rest_element(String, int * duration )
{
Voice_element*v = new Voice_element;
- int i=0;
-
- int dur, dots;
- parse_duration(durstr, i, dur, dots);
- i=0;
Rest_req * rq = new Rest_req;
- rq->balltype = dur;
- rq->dots = dots;
+ rq->balltype = duration[0];
+ rq->dots = duration[1];
rq->print();
v->add(rq);
}
void
-set_default_duration(String d)
+get_default_duration(int *p)
{
- int i=0;
- parse_duration(d, i, default_duration, default_dots);
+ *p++ = default_duration;
+ *p = default_dots;
+}
+
+void
+set_default_duration(int *p)
+{
+ default_duration = *p++;
+ default_dots = *p++;
}
void
-set_default_pitch(String d)
+set_default_octave(String d)
{
int i=0;
default_octave=0;