X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Flily-lexer.cc;h=178853fc15b5cf5a9242710437c6e110ebed1184;hb=cd42fab34bab39b166f1e0581670852ee351940d;hp=a5c03cf7364474c2a19bce95ef1424f7b660766c;hpb=b37e3f652677ae0298423db9fa0e552e5fce0c92;p=lilypond.git diff --git a/lily/lily-lexer.cc b/lily/lily-lexer.cc index a5c03cf736..178853fc15 100644 --- a/lily/lily-lexer.cc +++ b/lily/lily-lexer.cc @@ -1,9 +1,20 @@ /* - lily-lexer.cc -- implement Lily_lexer + This file is part of LilyPond, the GNU music typesetter. - source file of the GNU LilyPond music typesetter + Copyright (C) 1997--2010 Han-Wen Nienhuys - (c) 1997--2006 Han-Wen Nienhuys + 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 . */ #include "lily-lexer.hh" @@ -12,6 +23,7 @@ #include using namespace std; +#include "context.hh" // for nested_property_alist #include "international.hh" #include "interval.hh" #include "keyword.hh" @@ -21,15 +33,17 @@ using namespace std; #include "scm-hash.hh" #include "source-file.hh" #include "warn.hh" +#include "program-option.hh" +#include "lily-parser.hh" static Keyword_ent the_key_tab[] = { {"accepts", ACCEPTS}, {"addlyrics", ADDLYRICS}, - {"addquote", ADDQUOTE}, {"alias", ALIAS}, {"alternative", ALTERNATIVE}, {"book", BOOK}, + {"bookpart", BOOKPART}, {"change", CHANGE}, {"chordmode", CHORDMODE}, {"chords", CHORDS}, @@ -52,12 +66,12 @@ static Keyword_ent the_key_tab[] {"lyricsto", LYRICSTO}, {"mark", MARK}, {"markup", MARKUP}, + {"markuplines", MARKUPLINES}, {"midi", MIDI}, {"name", NAME}, {"new", NEWCONTEXT}, {"notemode", NOTEMODE}, {"objectid", OBJECTID}, - {"octave", OCTAVE}, {"once", ONCE}, {"override", OVERRIDE}, {"paper", PAPER}, @@ -76,15 +90,15 @@ static Keyword_ent the_key_tab[] {"time", TIME_T}, {"times", TIMES}, {"transpose", TRANSPOSE}, - {"transposition", TRANSPOSITION}, {"type", TYPE}, {"unset", UNSET}, {"with", WITH}, {0, 0} }; -Lily_lexer::Lily_lexer (Sources *sources) +Lily_lexer::Lily_lexer (Sources *sources, Lily_parser *parser) { + parser_ = parser; keytable_ = new Keyword_table (the_key_tab); chordmodifier_tab_ = SCM_EOL; pitchname_tab_stack_ = SCM_EOL; @@ -93,6 +107,7 @@ Lily_lexer::Lily_lexer (Sources *sources) error_level_ = 0; is_main_input_ = false; start_module_ = SCM_EOL; + chord_repetition_ = Chord_repetition (); smobify_self (); add_scope (ly_make_anonymous_module (false)); @@ -100,14 +115,16 @@ Lily_lexer::Lily_lexer (Sources *sources) chordmodifier_tab_ = scm_make_vector (scm_from_int (1), SCM_EOL); } -Lily_lexer::Lily_lexer (Lily_lexer const &src) +Lily_lexer::Lily_lexer (Lily_lexer const &src, Lily_parser *parser) : Includable_lexer () { + parser_ = parser; keytable_ = (src.keytable_) ? new Keyword_table (*src.keytable_) : 0; chordmodifier_tab_ = src.chordmodifier_tab_; pitchname_tab_stack_ = src.pitchname_tab_stack_; sources_ = src.sources_; start_module_ = SCM_EOL; + chord_repetition_ = src.chord_repetition_; error_level_ = src.error_level_; is_main_input_ = src.is_main_input_; @@ -148,6 +165,11 @@ Lily_lexer::add_scope (SCM module) set_current_scope (); } +bool +Lily_lexer::has_scope () const +{ + return scm_is_pair (scopes_); +} SCM Lily_lexer::remove_scope () @@ -172,11 +194,31 @@ Lily_lexer::set_current_scope () } int -Lily_lexer::lookup_keyword (std::string s) +Lily_lexer::lookup_keyword (string s) { return keytable_->lookup (s.c_str ()); } +SCM +Lily_lexer::keyword_list () const +{ + if (!keytable_) + return SCM_EOL; + + SCM l = SCM_EOL; + SCM *tail = &l; + for (vsize i = 0; i < keytable_->table_.size (); i++) + { + *tail = scm_acons (scm_from_locale_string (keytable_->table_[i].name_), + scm_from_int (keytable_->table_[i].tokcode_), + SCM_EOL); + + tail = SCM_CDRLOC (*tail); + } + + return l; +} + SCM Lily_lexer::lookup_identifier_symbol (SCM sym) { @@ -191,7 +233,7 @@ Lily_lexer::lookup_identifier_symbol (SCM sym) } SCM -Lily_lexer::lookup_identifier (std::string name) +Lily_lexer::lookup_identifier (string name) { return lookup_identifier_symbol (ly_symbol2scm (name.c_str ())); } @@ -199,35 +241,67 @@ Lily_lexer::lookup_identifier (std::string name) void Lily_lexer::start_main_input () { - // yy_flex_debug = 1; - new_input (main_input_name_, sources_); + yy_flex_debug = get_program_option ("debug-lexer"); + parser_->set_yydebug (get_program_option ("debug-parser")); - /* Do not allow \include in --safe-mode */ - allow_includes_b_ = allow_includes_b_ && !be_safe_global; + + new_input (main_input_name_, sources_); scm_module_define (scm_car (scopes_), ly_symbol2scm ("input-file-name"), - scm_makfrom0str (main_input_name_.c_str ())); + ly_string2scm (main_input_name_)); } void -Lily_lexer::set_identifier (SCM name, SCM s) +Lily_lexer::new_input (string str, string d, Sources *ss) { - SCM sym = name; - if (scm_is_string (name)) - sym = scm_string_to_symbol (name); + Includable_lexer::new_input (str, d, ss); +} + +void +Lily_lexer::new_input (string str, Sources *ss) +{ + if (is_main_input_ && be_safe_global) + { + LexerError (_ ("include files are not allowed in safe mode").c_str ()); + return; + } + + Includable_lexer::new_input (str, ss); +} + +// PATH is either a single symbol (or string) or a list of symbols +// giving the path to a nested property. A symbol is treated the same +// as a list of length 1. +void +Lily_lexer::set_identifier (SCM path, SCM val) +{ + SCM sym = path; + if (scm_is_string (path)) + sym = scm_string_to_symbol (path); + else if (scm_is_pair (path)) + { + sym = scm_car (path); + path = scm_cdr (path); + } if (scm_is_symbol (sym)) { if (lookup_keyword (ly_symbol2string (sym)) >= 0) { - std::string symstr = ly_symbol2string (sym); + string symstr = ly_symbol2string (sym); warning (_f ("identifier name is a keyword: `%s'", symstr.c_str ())); } SCM mod = scm_car (scopes_); - scm_module_define (mod, sym, s); + if (scm_is_pair (path)) + { + SCM prev = scm_module_lookup (mod, sym); + if (prev != SCM_UNDEFINED) + val = nested_property_alist (prev, path, val); + } + scm_module_define (mod, sym, val); } else programming_error ("identifier is not a symbol"); @@ -236,7 +310,7 @@ Lily_lexer::set_identifier (SCM name, SCM s) void Lily_lexer::LexerError (char const *s) { - if (include_stack_.is_empty ()) + if (include_stack_.empty ()) message (_f ("error at EOF: %s", s) + "\n"); else { @@ -285,7 +359,7 @@ Lily_lexer::add_lexed_char (int count) char const *start = here_str0 (); lexloc->set (get_source_file (), start, start + count); - char_count_stack_.top () += count; + char_count_stack_.back () += count; } #include "ly-smobs.icc" @@ -297,9 +371,13 @@ IMPLEMENT_DEFAULT_EQUAL_P (Lily_lexer); SCM Lily_lexer::mark_smob (SCM s) { + ASSERT_LIVE_IS_ALLOWED (); + Lily_lexer *lexer = (Lily_lexer *) SCM_CELL_WORD_1 (s); scm_gc_mark (lexer->chordmodifier_tab_); + if (lexer->parser_) + scm_gc_mark (lexer->parser_->self_scm ()); scm_gc_mark (lexer->pitchname_tab_stack_); scm_gc_mark (lexer->start_module_); return lexer->scopes_;