From a4759a89b302ae101da41a9dc8457d04cf5a95d6 Mon Sep 17 00:00:00 2001 From: fred Date: Mon, 11 Nov 1996 23:22:07 +0000 Subject: [PATCH] lilypond-0.0.9 --- src/identifier.cc | 26 +++++ src/lexer.l | 229 ++++++++++++++++++++++++++++++++++++ src/parser.y | 292 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 547 insertions(+) create mode 100644 src/identifier.cc create mode 100644 src/lexer.l create mode 100644 src/parser.y diff --git a/src/identifier.cc b/src/identifier.cc new file mode 100644 index 0000000000..024fe06486 --- /dev/null +++ b/src/identifier.cc @@ -0,0 +1,26 @@ +#include +#include "identifier.hh" +#include "staff.hh" +#include "lexer.hh" + + +Identifier::Identifier(String n) + :name (n) +{ + data = 0; +} + + +Identifier::~Identifier() +{ +} + +Staff_id::~Staff_id() +{ + delete staff(); +} + +Voice_id::~Voice_id() +{ + delete voice(); +} diff --git a/src/lexer.l b/src/lexer.l new file mode 100644 index 0000000000..1e3443e56e --- /dev/null +++ b/src/lexer.l @@ -0,0 +1,229 @@ +%{ // -*-Fundamental-*- + +#include +#include +#include "glob.hh" +#include "string.hh" + +#include "lexer.hh" +#include "keyword.hh" +#include "vray.hh" +#include "parser.hh" +#include "debug.hh" + +sstack include_stack; +static int last_print; +const int DOTPRINT=50; // every 50 lines dots +%} + +%option c++ +%option noyywrap +%option nodefault +%option yylineno +%option debug +%x notes +%x incl +%x quote + + +NOTECOMMAND \\{WORD} +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]*)? + +%% + +\$ { + BEGIN(notes); return '$'; +} + +{NOTECOMMAND} { + String c = YYText() +1; + int l = lookup_keyword(c); + if (l == -1) { + String e("unknown NOTECOMMAND: \\"); + e += c; + yyerror(e); + } + return l; +} + +{RESTNAME} { + const char *s = YYText(); + yylval.string = new String (s); + mtor << "rest:"<< yylval.string; + return RESTNAME; +} +{PITCH} { + const char *s = YYText(); + yylval.string = new String (s); + mtor << "pitch:"<< *yylval.string; + return PITCH; +} +{DURATION} { + yylval.string = new String (YYText()); + return DURATION; +} +\| { +} +[:space:]+ { +} +[ \t\n]+ { +} +%.* { + +} +\$ { + BEGIN(INITIAL); return '$'; +} +[\[){] { /* parens () are NO mistake */ + yylval.c = YYText()[0]; + return OPEN_REQUEST_PARENS; +} +[\]()}] { /* parens () are NO mistake */ + yylval.c = YYText()[0]; + return CLOSE_REQUEST_PARENS; +} + +. { + String s("lexer error: illegal character found: " + String(YYText())); + yyerror(s); +} + +\" { + BEGIN(quote); +} +[^\"]* { + yylval.string = new String (YYText()); +} +\" { + BEGIN(INITIAL); + return STRING; +} + +<> { + if(!close_input()) + yyterminate(); +} +{WORD} { + int l = lookup_keyword(YYText()); + if (l != -1) + return l; + Identifier * id = lookup_identifier(YYText()); + if (id) { + yylval.id = id; + return IDENTIFIER; + } + String *sp = new String( YYText()); + mtor << "new id: " << *sp; + yylval.string=sp; + return NEWIDENTIFIER; +} + +{REAL} { + Real r; + int cnv=sscanf (YYText(), "%lf", &r); + assert(cnv == 1); + mtor << "token (REAL)" << r; + yylval.real = r; + return REAL; +} + +[\{\}\[\]\(\)] { + + mtor << "parens\n"; + return YYText()[0]; +} +[:=] { + char c = YYText()[0]; + mtor << "misc char" <set_debug( !monitor.silence("Lexer")); + } + + lexer->switch_streams(newin); +} + + +// pop the inputstack. +bool +close_input() +{ + + 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; +} + +int +yylex() { + return lexer->yylex(); +} + +void +yyerror(const char *s) +{ + *mlog << "error in line " << lexer->lineno() << ": " << s << '\n'; + exit(1); +} + +void +kill_lexer() +{ + delete lexer; +} diff --git a/src/parser.y b/src/parser.y new file mode 100644 index 0000000000..691d306e78 --- /dev/null +++ b/src/parser.y @@ -0,0 +1,292 @@ +%{ // -*-Fundamental-*- +#include + +#include "lexer.hh" +#include "paper.hh" +#include "staff.hh" +#include "score.hh" +#include "main.hh" +#include "keyword.hh" +#include "scommands.hh" +#include "debug.hh" +#include "parseconstruct.hh" +#include "dimen.hh" +#include "identifier.hh" + +#ifndef NDEBUG +#define YYDEBUG 1 +#endif + +svec pre_reqs, post_reqs; +%} + + +%union { + Real real; + Command *command; + Identifier *id; + Score_commands *scommands; + Voice *voice; + Voice_element *el; + Staff *staff; + String *string; + Score *score; + const char *consstr; + Paperdef *paper; + Request* request; + int i; + char c; +} + +%token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME OUTPUT +%token CM IN PT MM PAPER WIDTH METER UNITSPACE SKIP COMMANDS +%token MELODICSTAFF GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND + +%token IDENTIFIER +%token NEWIDENTIFIER +%token PITCH DURATION RESTNAME +%token REAL +%token STRING +%token OPEN_REQUEST_PARENS CLOSE_REQUEST_PARENS + + +%type unit + +%type declaration +%type paper_block paper_body +%type dim +%type voice_block voice_body voice_elts voice_elts_dollar +%type voice_elt +%type score_command +%type score_block score_body +%type staff_block rhythmstaff_block rhythmstaff_body +%type melodicstaff_block melodicstaff_body staffdecl +%type int +%type score_commands_block score_commands_body +%type post_request pre_request + + +%% + +mudela: /* empty */ + | mudela score_block { + add_score($2); + } + | mudela add_declaration { } + ; + +add_declaration: declaration { + add_identifier($1); + } + ; + +declaration: + NEWIDENTIFIER '=' staff_block { + $$ = new Staff_id(*$1, $3); + delete $1; // this sux + } + | NEWIDENTIFIER '=' voice_block { + $$ = new Voice_id(*$1, $3); + delete $1; + } + ; + + +score_block: SCORE '{' score_body '}' { $$ = $3; } + ; + +score_body: { $$ = new Score; } + | score_body staff_block { $$->add($2); } + | score_body score_commands_block { $$->set($2); } + | score_body paper_block { $$->set($2); } + ; +score_commands_block: + COMMANDS '{' score_commands_body '}' { $$ =$3;} + ; + +score_commands_body: { $$ = new Score_commands; } + | score_commands_body score_command { + $$->parser_add($2); + } + ; + +paper_block: + PAPER '{' paper_body '}' { $$ = $3; } + ; + +paper_body: + /* empty */ { $$ = new Paperdef; } + | paper_body WIDTH dim { $$->linewidth = $3;} + | paper_body OUTPUT STRING { $$->outfile = *$3; + delete $3; + } + | paper_body UNITSPACE dim { $$->whole_width = $3; } + | paper_body GEOMETRIC REAL { $$->geometric_ = $3; } + ; + +dim: + REAL unit { $$ = convert_dimen($1,$2); } + ; + + +unit: CM { $$ = "cm"; } + |IN { $$ = "in"; } + |MM { $$ = "mm"; } + |PT { $$ = "pt"; } + ; + +/* + staff +*/ +staff_block: + staffdecl + | rhythmstaff_block + | melodicstaff_block + ; + +staffdecl: STAFF '{' IDENTIFIER '}' { $$ = $3->staff()->clone(); } + ; + +rhythmstaff_block: + RHYTHMSTAFF '{' rhythmstaff_body '}' { $$ = $3; } + ; + +rhythmstaff_body: + /* empty */ { $$ = get_new_rhythmstaff(); } + | rhythmstaff_body voice_block { $$->add_voice($2); } + ; + +melodicstaff_block: + MELODICSTAFF '{' melodicstaff_body '}' { $$ = $3; } + ; + +melodicstaff_body: + /* empty */ { $$ = get_new_melodicstaff(); } + | melodicstaff_body voice_block { $$->add_voice($2); } + ; + +/* + voice +*/ +voice_block: + VOICE '{' voice_body '}' { $$ = $3; } + ; + + +voice_body: + IDENTIFIER { $$ = new Voice(*$1->voice()); } + | voice_elts_dollar { $$ = $1; } + | voice_body START_T REAL { $$->start = $3; } + ; + + + + +voice_elts_dollar: + '$' voice_elts '$' { $$ = $2; } + ; + +voice_elts: + /* empty */ { + $$ = new Voice; + } + | voice_elts pre_requests voice_elt post_requests { + add_requests($3, pre_reqs); + add_requests($3, post_reqs); + $$->add($3); + } + + | voice_elts voice_command { } + ; + +post_requests: + { + assert(post_reqs.empty()); + } + | post_requests post_request { + post_reqs.add($2); + } + ; + +post_request: + CLOSE_REQUEST_PARENS { $$ = get_request($1); } + ; + +pre_requests: + | pre_requests pre_request { + pre_reqs.add($2); + } + ; + +pre_request: + OPEN_REQUEST_PARENS { $$ = get_request($1); } + ; +/* +*/ +voice_command: + DURATIONCOMMAND DURATION { + set_default_duration(*$2); + delete $2; + } + | OCTAVECOMMAND PITCH { + set_default_pitch(*$2); + delete $2; + } + ; + +voice_elt: + PITCH DURATION { + $$ = get_note_element(*$1, *$2); + delete $1; + delete $2; + } + | RESTNAME DURATION { + $$ = get_rest_element(*$1, *$2); + delete $1; + delete $2; + } + | PITCH { $$ = get_note_element(*$1, ""); + delete $1; + } + | RESTNAME { $$ = get_rest_element(*$1, ""); + delete $1; + } + ; + +score_command: + SKIP int ':' REAL { + $$ = get_skip_command($2, $4); + } + | METER int int { + $$ = get_meterchange_command($2, $3); + } +/* | PARTIALMEASURE REAL { + $$ = get_partial_command($2); + }*/ + ; + + +int: + REAL { + $$ = int($1); + if (ABS($1-Real(int($$))) > 1e-8) + yyerror("expecting integer number"); + + } + ; + +%% + +void +parse_file(String s) +{ + *mlog << "Parsing ... "; +#ifdef YYDEBUG + yydebug = !monitor.silence("Parser"); +#endif + new_input(s); + yyparse(); + delete_identifiers(); + kill_lexer(); + *mlog << "\n"; +} -- 2.39.5