X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Flily-lexer.cc;h=1160fe69f6e18b0af582a74789c95eb412b57dc5;hb=c3c7e6c543f040af7883da3ccb89a3b16d8f274b;hp=2b96e09ffbb466da46c5deaaf4b0a117c136ca2d;hpb=843b5cd769205cb24ac30cf179798b487a1173f1;p=lilypond.git diff --git a/lily/lily-lexer.cc b/lily/lily-lexer.cc index 2b96e09ffb..1160fe69f6 100644 --- a/lily/lily-lexer.cc +++ b/lily/lily-lexer.cc @@ -1,68 +1,80 @@ /* - 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--2011 Han-Wen Nienhuys - (c) 1997--2004 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 +#include "lily-lexer.hh" + +#include #include +using namespace std; -#include "lily-proto.hh" -#include "scm-hash.hh" +#include "context.hh" // for nested_property_alist +#include "international.hh" #include "interval.hh" -#include "lily-guile.hh" -#include "parser.hh" #include "keyword.hh" -#include "lily-lexer.hh" -#include "warn.hh" -#include "source-file.hh" #include "main.hh" -#include "input.hh" #include "moment.hh" -#include "ly-module.hh" - +#include "parser.hh" +#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[] = { +static Keyword_ent the_key_tab[] += { {"accepts", ACCEPTS}, - {"addquote", ADDQUOTE}, {"addlyrics", ADDLYRICS}, {"alias", ALIAS}, {"alternative", ALTERNATIVE}, - {"bar", BAR}, {"book", BOOK}, - {"bookpaper", BOOKPAPER}, + {"bookpart", BOOKPART}, {"change", CHANGE}, - {"chords", CHORDS}, {"chordmode", CHORDMODE}, - {"clef", CLEF}, + {"chords", CHORDS}, {"consists", CONSISTS}, {"context", CONTEXT}, {"default", DEFAULT}, + {"defaultchild", DEFAULTCHILD}, {"denies", DENIES}, + {"description", DESCRIPTION}, {"drummode", DRUMMODE}, {"drums", DRUMS}, - {"description", DESCRIPTION}, - {"figures",FIGURES}, - {"figuremode",FIGUREMODE}, + {"figuremode", FIGUREMODE}, + {"figures", FIGURES}, {"grobdescriptions", GROBDESCRIPTIONS}, {"header", HEADER}, {"key", KEY}, + {"layout", LAYOUT}, {"lyricmode", LYRICMODE}, + {"lyrics", LYRICS}, {"lyricsto", LYRICSTO}, {"mark", MARK}, {"markup", MARKUP}, + {"markuplines", MARKUPLINES}, {"midi", MIDI}, {"name", NAME}, {"new", NEWCONTEXT}, {"notemode", NOTEMODE}, - {"octave", OCTAVE}, {"once", ONCE}, {"override", OVERRIDE}, {"paper", PAPER}, {"partial", PARTIAL}, - {"quote", QUOTE}, {"relative", RELATIVE}, {"remove", REMOVE}, {"repeat", REPEAT}, @@ -73,64 +85,64 @@ static Keyword_ent the_key_tab[] = { {"set", SET}, {"simultaneous", SIMULTANEOUS}, {"skip", SKIP}, - {"tag", TAG}, {"tempo", TEMPO}, {"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); - encoding_ = SCM_EOL; chordmodifier_tab_ = SCM_EOL; - pitchname_tab_stack_ = SCM_EOL; + pitchname_tab_stack_ = SCM_EOL; sources_ = sources; scopes_ = SCM_EOL; - error_level_ = 0; - main_input_b_ = false; - + error_level_ = 0; + is_main_input_ = false; + start_module_ = SCM_EOL; + chord_repetition_ = Chord_repetition (); smobify_self (); - - add_scope (ly_make_anonymous_module (false)); + + add_scope (ly_make_module (false)); push_note_state (scm_c_make_hash_table (0)); - chordmodifier_tab_ = scm_make_vector (scm_int2num (1), SCM_EOL); + 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; - encoding_ = src.encoding_; chordmodifier_tab_ = src.chordmodifier_tab_; pitchname_tab_stack_ = src.pitchname_tab_stack_; sources_ = src.sources_; - - error_level_ = src.error_level_; - main_input_b_ = src.main_input_b_; + start_module_ = SCM_EOL; + chord_repetition_ = src.chord_repetition_; + + error_level_ = src.error_level_; + is_main_input_ = src.is_main_input_; scopes_ = SCM_EOL; - + smobify_self (); - + SCM scopes = SCM_EOL; SCM *tail = &scopes; - for (SCM s = src.scopes_; ly_c_pair_p (s); s = ly_cdr (s)) + for (SCM s = src.scopes_; scm_is_pair (s); s = scm_cdr (s)) { - SCM newmod = ly_make_anonymous_module (false); - ly_import_module (newmod, ly_car (s)); + SCM newmod = ly_make_module (false); + ly_module_copy (newmod, scm_car (s)); *tail = scm_cons (newmod, SCM_EOL); tail = SCM_CDRLOC (*tail); } - - scopes_ = scopes; + + scopes_ = scopes; push_note_state (scm_c_make_hash_table (0)); } @@ -139,48 +151,79 @@ Lily_lexer::~Lily_lexer () delete keytable_; } -SCM -Lily_lexer::encoding () const -{ - return encoding_ ; -} - - void Lily_lexer::add_scope (SCM module) { ly_reexport_module (scm_current_module ()); - scm_set_current_module (module); - for (SCM s = scopes_; ly_c_pair_p (s); s = ly_cdr (s)) - { - ly_use_module (module, ly_car (s)); - } + if (!scm_is_pair (scopes_)) + start_module_ = scm_current_module (); + + for (SCM s = scopes_; scm_is_pair (s); s = scm_cdr (s)) + ly_use_module (module, scm_car (s)); scopes_ = scm_cons (module, scopes_); + + set_current_scope (); +} +bool +Lily_lexer::has_scope () const +{ + return scm_is_pair (scopes_); } SCM Lily_lexer::remove_scope () { - SCM sc = ly_car (scopes_); - scopes_ = ly_cdr (scopes_); - scm_set_current_module (ly_car (scopes_)); - + SCM sc = scm_car (scopes_); + scopes_ = scm_cdr (scopes_); + set_current_scope (); return sc; } +SCM +Lily_lexer::set_current_scope () +{ + SCM old = scm_current_module (); + + if (scm_is_pair (scopes_)) + scm_set_current_module (scm_car (scopes_)); + else + scm_set_current_module (start_module_); + + return old; +} int -Lily_lexer::lookup_keyword (String s) +Lily_lexer::lookup_keyword (string s) +{ + return keytable_->lookup (s.c_str ()); +} + +SCM +Lily_lexer::keyword_list () const { - return keytable_->lookup (s.to_str0 ()); + 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) { - for (SCM s = scopes_; ly_c_pair_p (s); s = ly_cdr (s)) + for (SCM s = scopes_; scm_is_pair (s); s = scm_cdr (s)) { - SCM var = ly_module_lookup (ly_car (s), sym); + SCM var = ly_module_lookup (scm_car (s), sym); if (var != SCM_BOOL_F) return scm_variable_ref (var); } @@ -189,59 +232,88 @@ Lily_lexer::lookup_identifier_symbol (SCM sym) } SCM -Lily_lexer::lookup_identifier (String name) +Lily_lexer::lookup_identifier (string name) { - return lookup_identifier_symbol (ly_symbol2scm (name.to_str0 ())); + return lookup_identifier_symbol (ly_symbol2scm (name.c_str ())); } void Lily_lexer::start_main_input () { - // yy_flex_debug = 1; + 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_ && !safe_global_b; - scm_module_define (ly_car (scopes_), + scm_module_define (scm_car (scopes_), ly_symbol2scm ("input-file-name"), - scm_makfrom0str (main_input_name_.to_str0 ())); + 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) { - String symstr = ly_symbol2string (sym); - warning (_f ("Identifier name is a keyword: `%s'", symstr.to_str0())); + string symstr = ly_symbol2string (sym); + warning (_f ("identifier name is a keyword: `%s'", symstr.c_str ())); } - SCM mod = ly_car (scopes_); + SCM mod = scm_car (scopes_); - scm_module_define (mod, sym, s); + if (scm_is_pair (path)) + { + SCM prev = ly_module_lookup (mod, sym); + if (prev != SCM_BOOL_F) + val = nested_property_alist (scm_variable_ref (prev), path, val); + } + scm_module_define (mod, sym, val); } else - { - programming_error ("Identifier is not a symbol."); - } + programming_error ("identifier is not a symbol"); } void Lily_lexer::LexerError (char const *s) { - if (include_stack_.is_empty ()) - progress_indication (_f ("error at EOF: %s", s) + String ("\n")); + if (include_stack_.empty ()) + message (_f ("error at EOF: %s", s) + "\n"); else { error_level_ |= 1; - Input spot (get_source_file (), here_str0 ()); + Input spot (*lexloc_); spot.error (s); } } @@ -266,8 +338,7 @@ Lily_lexer::escaped_char (char c) const Input Lily_lexer::here_input () const { - Source_file * f= get_source_file (); - return Input (f, (char*)here_str0 ()); + return Input (*lexloc_); } void @@ -276,13 +347,17 @@ Lily_lexer::prepare_for_next_token () last_input_ = here_input (); } +/** + Since we don't create the buffer state from the bytes directly, we + don't know about the location of the lexer. Add this as a + YY_USER_ACTION */ void -Lily_lexer::set_encoding (String s) +Lily_lexer::add_lexed_char (int count) { - if (s.length ()) - encoding_ = ly_symbol2scm (s.to_str0 ()); - else - encoding_ = SCM_EOL; + char const *start = here_str0 (); + lexloc_->set (get_source_file (), + start, start + count); + char_count_stack_.back () += count; } #include "ly-smobs.icc" @@ -294,18 +369,31 @@ IMPLEMENT_DEFAULT_EQUAL_P (Lily_lexer); SCM Lily_lexer::mark_smob (SCM s) { - Lily_lexer *lexer = (Lily_lexer*) ly_cdr (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->scopes_); - return lexer->encoding_; + scm_gc_mark (lexer->start_module_); + return lexer->scopes_; } int -Lily_lexer::print_smob (SCM, SCM port, scm_print_state*) +Lily_lexer::print_smob (SCM s, SCM port, scm_print_state*) { + Lily_lexer *lexer = Lily_lexer::unsmob (s); + scm_puts ("#scopes_, port); scm_puts (" >", port); return 1; } + +bool +Lily_lexer::is_clean () const +{ + return include_stack_.empty (); +}