%{ // -*-Fundamental-*-
/*
- lexer.ll -- implement the Flex lexer
+ This file is part of LilyPond, the GNU music typesetter.
- source file of the LilyPond music typesetter
+ Copyright (C) 1996--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ Jan Nieuwenhuizen <janneke@gnu.org>
- (c) 1996--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
- Jan Nieuwenhuizen <janneke@gnu.org>
-*/
+ LilyPond is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ LilyPond 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 LilyPond. If not, see <http://www.gnu.org/licenses/>.
+*/
/*
backup rules
using namespace std;
#include "context-def.hh"
+#include "duration.hh"
#include "identifier-smob.hh"
#include "international.hh"
#include "interval.hh"
#include "lily-guile.hh"
#include "lily-lexer.hh"
+#include "lily-parser.hh"
#include "lilypond-version.hh"
#include "main.hh"
#include "music.hh"
#include "music-function.hh"
#include "parse-scm.hh"
#include "parser.hh"
+#include "pitch.hh"
#include "source-file.hh"
#include "std-string.hh"
#include "string-convert.hh"
yylval.string = new string
#define yylval \
- (*(YYSTYPE*)lexval)
+ (*(YYSTYPE*)lexval_)
#define yylloc \
- (*(YYLTYPE*)lexloc)
+ (*(YYLTYPE*)lexloc_)
#define YY_USER_ACTION add_lexed_char (YYLeng ());
ACCENT \\[`'"^]
NATIONAL [\001-\006\021-\027\031\036]
TEX {AA}|-|{PUNCT}|{ACCENT}|{NATIONAL}
-WORD {A}{AN}*
DASHED_WORD {A}({AN}|-)*
DASHED_KEY_WORD \\{DASHED_WORD}
FRACTION {N}+\/{N}+
INT -?{UNSIGNED}
REAL ({INT}\.{N}*)|(-?\.{N}+)
-KEYWORD \\{WORD}
WHITE [ \n\t\f\r]
HORIZONTALWHITE [ \t]
BLACK [^ \n\t\f\r]
<*>\r {
- // windows-suck-suck-suck
+ // swallow and ignore carriage returns
}
<extratoken>{ANY_CHAR} {
/* Use the trailing context feature. Otherwise, the BOM will not be
found if the file starts with an identifier definition. */
<INITIAL,chords,lyrics,figures,notes>{BOM_UTF8}/.* {
- if (this->lexloc->line_number () != 1 || this->lexloc->column_number () != 0)
+ if (this->lexloc_->line_number () != 1 || this->lexloc_->column_number () != 0)
{
LexerError (_ ("stray UTF-8 BOM encountered").c_str ());
exit (1);
}
- if (be_verbose_global)
- message (_ ("Skipping UTF-8 BOM"));
+ debug_output (_ ("Skipping UTF-8 BOM"));
}
<INITIAL,chords,figures,incl,lyrics,markup,notes>{
"%{" {
yy_push_state (longcomment);
}
- %[^{\n\r].*[\n\r] {
+ %[^{\n\r][^\n\r]*[\n\r] {
}
%[^{\n\r] { // backup rule
}
%[\n\r] {
}
- %[^{\n\r].* {
+ %[^{\n\r][^\n\r]* {
}
{WHITE}+ {
this->here_input ().get_source_file ()->set_line (here_input ().start (), i);
}
-<version>. {
+<version>{ANY_CHAR} {
LexerError (_ ("quoted string expected after \\version").c_str ());
yy_pop_state ();
}
-<sourcefilename>. {
+<sourcefilename>{ANY_CHAR} {
LexerError (_ ("quoted string expected after \\sourcefilename").c_str ());
yy_pop_state ();
}
-<sourcefileline>. {
+<sourcefileline>{ANY_CHAR} {
LexerError (_ ("integer expected after \\sourcefileline").c_str ());
yy_pop_state ();
}
"%"+"}" {
yy_pop_state ();
}
- <<EOF>> {
- LexerError (_ ("EOF found inside a comment").c_str ());
- is_main_input_ = false; // should be safe , can't have \include in --safe.
- if (! close_input ())
- yyterminate (); // can't move this, since it actually rets a YY_NULL
- }
}
new_input (s, sources_);
yy_pop_state ();
}
-<incl>\\{BLACK}*{WHITE} { /* got the include identifier */
+<incl>\\{BLACK}*{WHITE}? { /* got the include identifier */
string s = YYText () + 1;
strip_trailing_white (s);
if (s.length () && (s[s.length () - 1] == ';'))
scm_display (sid, err);
}
}
-<incl>\"[^"]* { // backup rule
+<incl,version,sourcefilename>\"[^"]* { // backup rule
error (_ ("end quote missing"));
exit (1);
}
yylval.scm = unpack_identifier(sval);
return identifier_type (yylval.scm);
}
+
+ for (size_t i = 0; i < pending_string_includes_.size (); i++)
+ new_input ("<included string>", pending_string_includes_[i],
+ parser_->sources_);
+ pending_string_includes_.clear ();
yylval.scm = sval;
return SCM_TOKEN;
yylval.scm = scan_fraction (YYText ());
return FRACTION;
}
-
{DIGIT} {
yylval.i = String_convert::dec2int (string (YYText ()));
return DIGIT;
}
+ {UNSIGNED}/\/[^0-9] { // backup rule
+ yylval.i = String_convert::dec2int (string (YYText ()));
+ return UNSIGNED;
+ }
+ {UNSIGNED}/\/ | // backup rule
{UNSIGNED} {
yylval.i = String_convert::dec2int (string (YYText ()));
return UNSIGNED;
\\{ESCAPED} {
*yylval.string += to_string (escaped_char (YYText ()[1]));
}
- [^\\"]+ {
+ [^\\""]+ {
*yylval.string += YYText ();
}
\" {
yylval.scm = scan_fraction (YYText ());
return FRACTION;
}
+ {UNSIGNED}/\/[^0-9] { // backup rule
+ yylval.i = String_convert::dec2int (string (YYText ()));
+ return UNSIGNED;
+ }
+ {UNSIGNED}/\/ | // backup rule
{UNSIGNED} {
yylval.i = String_convert::dec2int (string (YYText ()));
return UNSIGNED;
yylval.scm = scan_fraction (YYText ());
return FRACTION;
}
+ {UNSIGNED}/\/[^0-9] { // backup rule
+ yylval.i = String_convert::dec2int (string (YYText ()));
+ return UNSIGNED;
+ }
+ {UNSIGNED}/\/ | // backup rule
{UNSIGNED} {
yylval.i = String_convert::dec2int (string (YYText ()));
return UNSIGNED;
}
{MARKUPCOMMAND} {
string str (YYText () + 1);
+
+ int token_type = MARKUP_FUNCTION;
SCM s = lookup_markup_command (str);
- SCM s2 = lookup_markup_list_command (str);
- if (scm_is_pair (s) && scm_is_symbol (scm_cdr (s)) ) {
- yylval.scm = scm_car(s);
- SCM tag = scm_cdr(s);
- if (tag == ly_symbol2scm("markup0"))
- return MARKUP_HEAD_MARKUP0;
- if (tag == ly_symbol2scm("empty"))
- return MARKUP_HEAD_EMPTY;
- else if (tag == ly_symbol2scm ("markup0-markup1"))
- return MARKUP_HEAD_MARKUP0_MARKUP1;
- else if (tag == ly_symbol2scm ("markup-list0"))
- return MARKUP_HEAD_LIST0;
- else if (tag == ly_symbol2scm ("scheme0"))
- return MARKUP_HEAD_SCM0;
- else if (tag == ly_symbol2scm ("scheme0-scheme1"))
- return MARKUP_HEAD_SCM0_SCM1;
- else if (tag == ly_symbol2scm ("scheme0-markup1"))
- return MARKUP_HEAD_SCM0_MARKUP1;
- else if (tag == ly_symbol2scm ("scheme0-scheme1-markup2"))
- return MARKUP_HEAD_SCM0_SCM1_MARKUP2;
- else if (tag == ly_symbol2scm ("scheme0-scheme1-markup2-markup3"))
- return MARKUP_HEAD_SCM0_SCM1_MARKUP2_MARKUP3;
- else if (tag == ly_symbol2scm ("scheme0-markup1-markup2"))
- return MARKUP_HEAD_SCM0_MARKUP1_MARKUP2;
- else if (tag == ly_symbol2scm ("scheme0-scheme1-scheme2"))
- return MARKUP_HEAD_SCM0_SCM1_SCM2;
- else {
- programming_error ("no parser tag defined for this markup signature");
- ly_display_scm (s);
- assert(false);
- }
- } else if (scm_is_pair (s2) && scm_is_symbol (scm_cdr (s2))) {
- yylval.scm = scm_car(s2);
- SCM tag = scm_cdr(s2);
- if (tag == ly_symbol2scm("empty"))
- return MARKUP_LIST_HEAD_EMPTY;
- else if (tag == ly_symbol2scm ("scheme0"))
- return MARKUP_LIST_HEAD_SCM0;
- else if (tag == ly_symbol2scm ("markup-list0"))
- return MARKUP_LIST_HEAD_LIST0;
- else if (tag == ly_symbol2scm ("scheme0-markup-list1"))
- return MARKUP_LIST_HEAD_SCM0_LIST1;
- else if (tag == ly_symbol2scm ("scheme0-scheme1-markup-list2"))
- return MARKUP_LIST_HEAD_SCM0_SCM1_LIST2;
- else {
- programming_error ("no parser tag defined for this markup list signature");
- ly_display_scm (s);
- assert(false);
- }
- } else
- return scan_escaped_word (str);
+
+ // lookup-markup-command returns a pair with the car
+ // being the function to call, and the cdr being the
+ // call signature specified to define-markup-command,
+ // a list of predicates.
+
+ if (!scm_is_pair (s)) {
+ // If lookup-markup-command was not successful, we
+ // try lookup-markup-list-command instead.
+ // If this fails as well, we just scan and return
+ // the escaped word.
+ s = lookup_markup_list_command (str);
+ if (scm_is_pair (s))
+ token_type = MARKUP_LIST_FUNCTION;
+ else
+ return scan_escaped_word (str);
+ }
+
+ // If the list of predicates is, say,
+ // (number? number? markup?), then tokens
+ // EXPECT_MARKUP EXPECT_SCM EXPECT_SCM EXPECT_NO_MORE_ARGS
+ // will be generated. Note that we have to push them
+ // in reverse order, so the first token pushed in the
+ // loop will be EXPECT_NO_MORE_ARGS.
+
+ yylval.scm = scm_car(s);
+
+ // yylval now contains the function to call as token
+ // value (for token type MARKUP_FUNCTION or
+ // MARKUP_LIST_FUNCTION).
+
+ push_extra_token(EXPECT_NO_MORE_ARGS);
+ s = scm_cdr(s);
+ for (; scm_is_pair(s); s = scm_cdr(s)) {
+ SCM predicate = scm_car(s);
+
+ if (predicate == ly_lily_module_constant ("markup-list?"))
+ push_extra_token(EXPECT_MARKUP_LIST);
+ else if (predicate == ly_lily_module_constant ("markup?"))
+ push_extra_token(EXPECT_MARKUP);
+ else
+ push_extra_token(EXPECT_SCM);
+ }
+ return token_type;
}
[{}] {
return YYText ()[0];
}
<*><<EOF>> {
- if (is_main_input_)
+ if (YY_START == longcomment)
+ {
+ LexerError (_ ("EOF found inside a comment").c_str ());
+ is_main_input_ = false; // should be safe , can't have \include in --safe.
+ if (!close_input ())
+ yyterminate (); // can't move this, since it actually rets a YY_NULL
+ }
+ else if (is_main_input_)
{
/* 2 = init.ly + current file.
> because we're before closing, but is_main_input_ should
}
}
-{WORD} {
- return scan_bare_word (YYText ());
-}
-{KEYWORD} {
- return scan_escaped_word (YYText () + 1);
-}
+-{UNSIGNED} | // backup rule
{REAL} {
Real r;
int cnv = sscanf (YYText (), "%lf", &r);
yylval.scm = scm_from_double (r);
return REAL;
}
+-\. { // backup rule
+ yylval.scm = scm_from_double (0.0);
+ return REAL;
+}
{UNSIGNED} {
yylval.i = String_convert::dec2int (string (YYText ()));
push_extra_token (EXPECT_NO_MORE_ARGS);
for (; scm_is_pair (s); s = scm_cdr (s))
{
- if (scm_car (s) == ly_music_p_proc)
+ SCM cs = scm_car (s);
+
+ if (cs == ly_music_p_proc)
push_extra_token (EXPECT_MUSIC);
- else if (scm_car (s) == ly_lily_module_constant ("markup?"))
+ else if (cs == Pitch_type_p_proc)
+ push_extra_token (EXPECT_PITCH);
+ else if (cs == Duration_type_p_proc)
+ push_extra_token (EXPECT_DURATION);
+ else if (cs == ly_lily_module_constant ("markup?"))
push_extra_token (EXPECT_MARKUP);
- else if (ly_is_procedure (scm_car (s)))
+ else if (ly_is_procedure (cs))
push_extra_token (EXPECT_SCM);
else programming_error ("Function parameter without type-checking predicate");
}
yylval.scm = scm_cdr (handle);
return CHORD_MODIFIER;
}
+ if ((chord_repetition_.repetition_symbol_ != SCM_EOL)
+ && to_boolean (scm_equal_p (chord_repetition_.repetition_symbol_, sym)))
+ return CHORD_REPETITION;
}
yylval.scm = ly_string2scm (str);