X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Flily-lexer.cc;h=6db0e653e5480d224427df3488bd12ae5c1a3bb5;hb=926115ff42def8bc1ce767029e4f03c8072994ba;hp=8d70783cb5989da22c5eede795ac94bcf6f72cc3;hpb=9e69cb84d6ee5b0a861cd97869b10e3bdf0c833c;p=lilypond.git diff --git a/lily/lily-lexer.cc b/lily/lily-lexer.cc index 8d70783cb5..6db0e653e5 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--2015 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" @@ -23,14 +35,17 @@ using namespace std; #include "warn.hh" #include "program-option.hh" #include "lily-parser.hh" +#include "ly-module.hh" static Keyword_ent the_key_tab[] -= { += +{ {"accepts", ACCEPTS}, {"addlyrics", ADDLYRICS}, {"alias", ALIAS}, {"alternative", ALTERNATIVE}, {"book", BOOK}, + {"bookpart", BOOKPART}, {"change", CHANGE}, {"chordmode", CHORDMODE}, {"chords", CHORDS}, @@ -42,27 +57,22 @@ static Keyword_ent the_key_tab[] {"description", DESCRIPTION}, {"drummode", DRUMMODE}, {"drums", DRUMS}, + {"etc", ETC}, {"figuremode", FIGUREMODE}, {"figures", FIGURES}, - {"grobdescriptions", GROBDESCRIPTIONS}, {"header", HEADER}, - {"key", KEY}, {"layout", LAYOUT}, {"lyricmode", LYRICMODE}, {"lyrics", LYRICS}, {"lyricsto", LYRICSTO}, - {"mark", MARK}, {"markup", MARKUP}, + {"markuplist", MARKUPLIST}, {"midi", MIDI}, {"name", NAME}, {"new", NEWCONTEXT}, {"notemode", NOTEMODE}, - {"objectid", OBJECTID}, - {"once", ONCE}, {"override", OVERRIDE}, {"paper", PAPER}, - {"partial", PARTIAL}, - {"relative", RELATIVE}, {"remove", REMOVE}, {"repeat", REPEAT}, {"rest", REST}, @@ -71,11 +81,7 @@ static Keyword_ent the_key_tab[] {"sequential", SEQUENTIAL}, {"set", SET}, {"simultaneous", SIMULTANEOUS}, - {"skip", SKIP}, {"tempo", TEMPO}, - {"time", TIME_T}, - {"times", TIMES}, - {"transpose", TRANSPOSE}, {"type", TYPE}, {"unset", UNSET}, {"with", WITH}, @@ -92,43 +98,39 @@ Lily_lexer::Lily_lexer (Sources *sources, Lily_parser *parser) scopes_ = SCM_EOL; error_level_ = 0; is_main_input_ = false; + main_input_level_ = 0; start_module_ = SCM_EOL; + extra_tokens_ = SCM_EOL; smobify_self (); - add_scope (ly_make_anonymous_module (false)); - push_note_state (scm_c_make_hash_table (0)); + add_scope (ly_make_module (false)); + push_note_state (SCM_EOL); chordmodifier_tab_ = scm_make_vector (scm_from_int (1), SCM_EOL); } -Lily_lexer::Lily_lexer (Lily_lexer const &src, Lily_parser *parser) +Lily_lexer::Lily_lexer (Lily_lexer const &src, Lily_parser *parser, + SCM override_input) : Includable_lexer () { - parser_ = parser; + 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_; + scopes_ = src.scopes_; start_module_ = SCM_EOL; - error_level_ = src.error_level_; + error_level_ = 0; is_main_input_ = src.is_main_input_; + main_input_level_ = 0; - scopes_ = SCM_EOL; + extra_tokens_ = SCM_EOL; + if (unsmob (override_input)) + override_input_ = *unsmob (override_input); smobify_self (); - SCM scopes = SCM_EOL; - SCM *tail = &scopes; - for (SCM s = src.scopes_; scm_is_pair (s); s = scm_cdr (s)) - { - SCM newmod = ly_make_anonymous_module (false); - ly_module_copy (newmod, scm_car (s)); - *tail = scm_cons (newmod, SCM_EOL); - tail = SCM_CDRLOC (*tail); - } - - scopes_ = scopes; - push_note_state (scm_c_make_hash_table (0)); + push_note_state (SCM_EOL); } Lily_lexer::~Lily_lexer () @@ -178,7 +180,7 @@ Lily_lexer::set_current_scope () } int -Lily_lexer::lookup_keyword (string s) +Lily_lexer::lookup_keyword (const string &s) { return keytable_->lookup (s.c_str ()); } @@ -188,16 +190,16 @@ 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_makfrom0str (keytable_->table_[i].name_), - scm_from_int (keytable_->table_[i].tokcode_), - SCM_EOL); + *tail = scm_acons (scm_from_utf8_string (keytable_->table_[i].name_), + scm_from_int (keytable_->table_[i].tokcode_), + SCM_EOL); - tail = SCM_CDRLOC(*tail); + tail = SCM_CDRLOC (*tail); } return l; @@ -209,15 +211,15 @@ Lily_lexer::lookup_identifier_symbol (SCM sym) for (SCM s = scopes_; scm_is_pair (s); s = scm_cdr (s)) { SCM var = ly_module_lookup (scm_car (s), sym); - if (var != SCM_BOOL_F) - return scm_variable_ref (var); + if (scm_is_true (var)) + return scm_variable_ref (var); } return SCM_UNDEFINED; } SCM -Lily_lexer::lookup_identifier (string name) +Lily_lexer::lookup_identifier (const string &name) { return lookup_identifier_symbol (ly_symbol2scm (name.c_str ())); } @@ -228,35 +230,65 @@ Lily_lexer::start_main_input () yy_flex_debug = get_program_option ("debug-lexer"); parser_->set_yydebug (get_program_option ("debug-parser")); - new_input (main_input_name_, sources_); - /* Do not allow \include in --safe-mode */ - allow_includes_b_ = allow_includes_b_ && !be_safe_global; - scm_module_define (scm_car (scopes_), - ly_symbol2scm ("input-file-name"), - scm_makfrom0str (main_input_name_.c_str ())); + ly_symbol2scm ("input-file-name"), + ly_string2scm (main_input_name_)); +} + +void +Lily_lexer::new_input (const string &str, string d, Sources *ss) +{ + Includable_lexer::new_input (str, d, ss); +} + +void +Lily_lexer::new_input (const 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 name, SCM s) +Lily_lexer::set_identifier (SCM path, SCM val) { - SCM sym = name; - if (scm_is_string (name)) - sym = scm_string_to_symbol (name); + 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) - { - string symstr = ly_symbol2string (sym); - warning (_f ("identifier name is a keyword: `%s'", symstr.c_str ())); - } + { + 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 = ly_module_lookup (mod, sym); + if (scm_is_true (prev)) + val = nested_property_alist (scm_variable_ref (prev), path, val); + else + val = nested_create_alist (path, val); + } + scm_module_define (mod, sym, val); } else programming_error ("identifier is not a symbol"); @@ -266,12 +298,24 @@ void Lily_lexer::LexerError (char const *s) { if (include_stack_.empty ()) - message (_f ("error at EOF: %s", s) + "\n"); + non_fatal_error (s, _f ("%s:EOF", s)); else { error_level_ |= 1; - Input spot (*lexloc); - spot.error (s); + Input spot (*lexloc_); + spot.non_fatal_error (s); + } +} + +void +Lily_lexer::LexerWarning (char const *s) +{ + if (include_stack_.empty ()) + warning (s, _f ("%s:EOF", s)); + else + { + Input spot (*lexloc_); + spot.warning (s); } } @@ -295,7 +339,14 @@ Lily_lexer::escaped_char (char c) const Input Lily_lexer::here_input () const { - return Input (*lexloc); + return Input (*lexloc_); +} + +Input const & +Lily_lexer::override_input (Input const &in) const +{ + return override_input_.get_source_file () + ? override_input_ : in; } void @@ -312,39 +363,39 @@ void Lily_lexer::add_lexed_char (int count) { char const *start = here_str0 (); - lexloc->set (get_source_file (), - start, start + count); + lexloc_->set (get_source_file (), + start, start + count); char_count_stack_.back () += count; } -#include "ly-smobs.icc" -IMPLEMENT_SMOBS (Lily_lexer); -IMPLEMENT_TYPE_P (Lily_lexer, "ly:lily-lexer?"); -IMPLEMENT_DEFAULT_EQUAL_P (Lily_lexer); +const char * const Lily_lexer::type_p_name_ = "ly:lily-lexer?"; SCM -Lily_lexer::mark_smob (SCM s) +Lily_lexer::mark_smob () const { - 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_; + ASSERT_LIVE_IS_ALLOWED (self_scm ()); + + scm_gc_mark (chordmodifier_tab_); + if (parser_) + scm_gc_mark (parser_->self_scm ()); + scm_gc_mark (pitchname_tab_stack_); + scm_gc_mark (start_module_); + scm_gc_mark (extra_tokens_); + return scopes_; } int -Lily_lexer::print_smob (SCM s, SCM port, scm_print_state*) +Lily_lexer::print_smob (SCM port, scm_print_state *) const { - Lily_lexer *lexer = Lily_lexer::unsmob (s); - scm_puts ("#scopes_, port); + scm_display (scopes_, port); scm_puts (" >", port); return 1; } + +bool +Lily_lexer::is_clean () const +{ + return include_stack_.empty (); +}