diff options
author | Han-Wen Nienhuys <hanwen@xs4all.nl> | 1996-11-30 12:09:32 +0100 |
---|---|---|
committer | Han-Wen Nienhuys <hanwen@xs4all.nl> | 1996-11-30 12:09:32 +0100 |
commit | cd6fbd39e456ab3ff353c38fc5ae1997e61390f2 (patch) | |
tree | 7b15d4c85e5aa027942420d220fa1dd7c09f22d1 /src/lexer.l | |
parent | fc22f69328fd2d5030bb1feff8d0f6da37e8217d (diff) |
release: 0.0.9
Diffstat (limited to 'src/lexer.l')
-rw-r--r-- | src/lexer.l | 229 |
1 files changed, 229 insertions, 0 deletions
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 <fstream.h> +#include <stdio.h> +#include "glob.hh" +#include "string.hh" + +#include "lexer.hh" +#include "keyword.hh" +#include "vray.hh" +#include "parser.hh" +#include "debug.hh" + +sstack<istream *> 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 '$'; +} + +<notes>{NOTECOMMAND} { + String c = YYText() +1; + int l = lookup_keyword(c); + if (l == -1) { + String e("unknown NOTECOMMAND: \\"); + e += c; + yyerror(e); + } + return l; +} + +<notes>{RESTNAME} { + const char *s = YYText(); + yylval.string = new String (s); + mtor << "rest:"<< yylval.string; + return RESTNAME; +} +<notes>{PITCH} { + const char *s = YYText(); + yylval.string = new String (s); + mtor << "pitch:"<< *yylval.string; + return PITCH; +} +<notes>{DURATION} { + yylval.string = new String (YYText()); + return DURATION; +} +<notes>\| { +} +<notes>[:space:]+ { +} +<notes>[ \t\n]+ { +} +<notes>%.* { + +} +<notes>\$ { + BEGIN(INITIAL); return '$'; +} +<notes>[\[){] { /* parens () are NO mistake */ + yylval.c = YYText()[0]; + return OPEN_REQUEST_PARENS; +} +<notes>[\]()}] { /* parens () are NO mistake */ + yylval.c = YYText()[0]; + return CLOSE_REQUEST_PARENS; +} + +<notes>. { + String s("lexer error: illegal character found: " + String(YYText())); + yyerror(s); +} + +\" { + BEGIN(quote); +} +<quote>[^\"]* { + yylval.string = new String (YYText()); +} +<quote>\" { + BEGIN(INITIAL); + return STRING; +} + +<<EOF>> { + 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" <<c<<"\n"; + return c; +} +[ \t\n]+ { + +} + +%.* { + //ignore +} +. { + error("lexer error: illegal character '"+String(YYText()[0])+ + "' encountered"); + return YYText()[0]; +} + +%% + +yyFlexLexer *lexer=0; + +// 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); + + if (!lexer) { + lexer = new yyFlexLexer; + lexer->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; +} |