]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/include/input.hh (class Input): new `end_' slot for end of
authorNicolas Sceaux <nicolas.sceaux@free.fr>
Mon, 10 Jan 2005 22:05:06 +0000 (22:05 +0000)
committerNicolas Sceaux <nicolas.sceaux@free.fr>
Mon, 10 Jan 2005 22:05:06 +0000 (22:05 +0000)
input. Renamed defined_str0_ to start_.

* lily/input.cc (Input): Add Input::Input (Input const &) and
remove Input::Input (Source_file*, char const *). Use the new
slots.
(set_location): method used by bison to propagate input
locations (YYLLOC_DEFAULT).
(end_line_number, end_column_number, step_forward): new methods

* lily/input-scheme.cc (ly:input-both-locations): new function,
similar to ly:input-location, but also return the end line and
column.

* lily/include/includable-lexer.hh:
* lily/includable-lexer.cc:
* lily/include/lily-lexer.hh (class Lily_lexer):
* lily/lily-lexer.cc (add_lexed_char): Move add_lexed_char from
Includable_lexer to Lily_lexer, in order to update lexloc (the
yylloc), a new slot of Lily_lexer.
(here_input, LexerError): simplify by using the lexloc slot (aka
yylloc)

* lily/lexer.ll: #define yylloc to use input locations (it may
be useless here?). Fixed the #embedded_scm rule (step the location
forward in order to skip the sharp sign before parsing the scheme
expression)

* lily/include/lily-parser.hh (class Lily_parser):
* lily/lily-parser.cc: Remove push_spot(), pop_spot() and
here_input()
(parser_error): overload for more precise locations of errors.

* lily/parser.yy (YYLTYPE): set location type to Input
(YYLLOC_DEFAULT): use Input::set_location()
(yylex): add the YYLTYPE* location parameter.
Clean push_spot()/pop_spot()/here_input(), and use @$, @1, etc.
Give an Input parameter to THIS->parser-error() for more accurate
messages.

16 files changed:
ChangeLog
configure.in
lily/includable-lexer.cc
lily/include/includable-lexer.hh
lily/include/input.hh
lily/include/lily-lexer.hh
lily/include/lily-parser.hh
lily/include/music.hh
lily/input-scheme.cc
lily/input.cc
lily/lexer.ll
lily/lily-lexer.cc
lily/lily-parser.cc
lily/parse-scm.cc
lily/parser.yy
lily/source-file.cc

index 26c28781d101eaf7192e195ae4396769e45a4d19..99b7d155b834305461f94a53575da916959143f1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2005-01-11  Nicolas Sceaux  <nicolas.sceaux@free.fr>
+
+       * lily/include/input.hh (class Input): new `end_' slot for end of
+       input. Renamed defined_str0_ to start_.
+
+       * lily/input.cc (Input): Add Input::Input (Input const &) and
+       remove Input::Input (Source_file*, char const *). Use the new
+       slots.
+       (set_location): method used by bison to propagate input
+       locations (YYLLOC_DEFAULT).
+       (end_line_number, end_column_number, step_forward): new methods
+       
+       * lily/input-scheme.cc (ly:input-both-locations): new function,
+       similar to ly:input-location, but also return the end line and
+       column.
+
+       * lily/include/includable-lexer.hh: 
+       * lily/includable-lexer.cc: 
+       * lily/include/lily-lexer.hh (class Lily_lexer): 
+       * lily/lily-lexer.cc (add_lexed_char): Move add_lexed_char from
+       Includable_lexer to Lily_lexer, in order to update lexloc (the
+       yylloc), a new slot of Lily_lexer.
+       (here_input, LexerError): simplify by using the lexloc slot (aka
+       yylloc)
+
+       * lily/lexer.ll: #define yylloc to use input locations (it may
+       be useless here?). Fixed the #embedded_scm rule (step the location
+       forward in order to skip the sharp sign before parsing the scheme
+       expression)
+
+       * lily/include/lily-parser.hh (class Lily_parser): 
+       * lily/lily-parser.cc: Remove push_spot(), pop_spot() and
+       here_input()
+       (parser_error): overload for more precise locations of errors.
+
+       * lily/parser.yy (YYLTYPE): set location type to Input
+       (YYLLOC_DEFAULT): use Input::set_location()
+       (yylex): add the YYLTYPE* location parameter.
+       Clean push_spot()/pop_spot()/here_input(), and use @$, @1, etc.
+       Give an Input parameter to THIS->parser-error() for more accurate
+       messages.
+
 2005-01-10  Han-Wen Nienhuys  <hanwen@xs4all.nl>
 
        * stepmake/aclocal.m4: do NDEBUG for optimizing builds.
index 64daff2952767ae88e19f0e36c8e1c934ab5c875..d2b8289cad50bfff78f58adee652cf439ce5b417 100644 (file)
@@ -37,7 +37,8 @@ STEPMAKE_GXX(REQUIRED, 3.0.5)
 STEPMAKE_CXXTEMPLATE
 STEPMAKE_LIB(REQUIRED)
 # Do not use bison 1.50 and 1.75.
-STEPMAKE_BISON(REQUIRED, 1.25)
+# 1.29 is required fr %locations, but I'm not sure it's enough --ns
+STEPMAKE_BISON(REQUIRED, 1.29)
 STEPMAKE_FLEX(REQUIRED)
 STEPMAKE_FLEXLEXER(REQUIRED)
 AC_LANG_C
index a87da4a2ed73b13c8e8a555a01f8c9e44c7fff7f..9064f8739354d5e95f0867944320180d16647e18 100644 (file)
@@ -138,15 +138,6 @@ Includable_lexer::~Includable_lexer ()
       close_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
-Includable_lexer::add_lexed_char (int count)
-{
-  char_count_stack_.top () += count;
-}
 
 Source_file*
 Includable_lexer::get_source_file () const
index fef7ca0ae6be751070cedea6ed160a1e291fe169..cc9ba99ec5b537dc4c2512865b983502efef943b 100644 (file)
@@ -46,7 +46,6 @@ public:
   void new_input (String s, Sources*);
   void new_input (String name, String data, Sources*);
 
-  void add_lexed_char (int);
   char const * here_str0 () const;
 };
 
index 710d6b97d8cdc0cae946e990a1c6ca4394db482d..c7dcbe1231eabac1f36585a1ecfb5a547a1a50c4 100644 (file)
@@ -16,7 +16,8 @@
  */
 class Input {
 public:
-  char const *defined_str0_ ;
+  char const *start_;
+  char const *end_;
   Source_file * source_file_;
     
   void warning (String) const; // should use member func?
@@ -24,6 +25,8 @@ public:
   void error (String) const;
   void message (String) const;
   void set_spot (Input const &);
+  void step_forward ();
+  void set_location (Input const &, Input const &);
   Input spot () const;
   String location_string () const;
   String line_number_string () const;
@@ -32,9 +35,11 @@ public:
   String file_string ()const;
   int line_number ()const;
   int column_number ()const;
+  int end_line_number ()const;
+  int end_column_number ()const;
 
   
-  Input (Source_file*, char const*);
+  Input (Input const &i);
   Input ();
 };
 
index e9f2d6d914aa08caa87c231fce39e4ed7afc3788..0e42719912c893717dac5e0e3e8d24ea63e0f3b1 100644 (file)
@@ -34,9 +34,11 @@ private:
   char escaped_char (char) const;
 
   Keyword_table *keytable_;
+
 public:
   String main_input_name_;
   void *lexval;
+  Input *lexloc;
   bool main_input_b_;
   
   Sources *sources_; 
@@ -52,6 +54,8 @@ public:
   Lily_lexer (Lily_lexer const&);
   int yylex ();
 
+  void add_lexed_char (int);
+
   void prepare_for_next_token ();
   int try_special_identifiers (SCM* ,SCM);
   Input here_input () const;
index 131c7783625447d66e737210b0a5e0a60cd4c533..6e325fcf185a55f4cb1572414f7312056de65614 100644 (file)
@@ -54,15 +54,13 @@ public:
 
   DECLARE_SCHEME_CALLBACK (layout_description, ());
 
-  Input here_input () const;
-  Input pop_spot ();
   void beam_check (SCM); 
   void do_init_file ();
   void do_yyparse ();
   void parse_file (String init, String name, String out_name);
   void parse_string (String ly_code);
   void parser_error (String);
-  void push_spot ();
+  void parser_error (Input const&, String);
   void set_yydebug (bool);
 };
 
index b59114eafb086dfbedcc7041ab0b2f60e7877373..60baeb72e83478d13dca8e0a2687d22a72bb3b56 100644 (file)
@@ -36,7 +36,7 @@ public:
   VIRTUAL_COPY_CONSTRUCTOR (Music, Music);
 
   Input *origin () const; 
-  void set_spot (Input);  
+  void set_spot (Input);
 
   SCM internal_get_property (SCM) const;
   void internal_set_property (SCM , SCM val);
index 2478bc95915d885fbad4ed82ec25c1cfe474e1b5..c9f257c5b68ba345cdde822acfc1ad81187f1973 100644 (file)
@@ -45,3 +45,15 @@ LY_DEFINE (ly_input_location, "ly:input-location", 1, 0, 0, (SCM sip),
                     scm_int2num (ip->line_number ()),
                     scm_int2num (ip->column_number ()));
 }
+
+LY_DEFINE (ly_input_both_locations, "ly:input-both-locations", 1, 0, 0, (SCM sip),
+         "Return input location in @var{sip} as (file-name first-line first-column last-line last-column).")
+{
+  Input *ip = unsmob_input (sip);
+  SCM_ASSERT_TYPE (ip, sip, SCM_ARG1, __FUNCTION__, "input location");
+  return scm_list_5 (scm_makfrom0str (ip->file_string ().to_str0 ()),
+                    scm_int2num (ip->line_number ()),
+                    scm_int2num (ip->column_number ()),
+                    scm_int2num (ip->end_line_number ()),
+                    scm_int2num (ip->end_column_number ()));
+}
index 972807983768f7d3edf8221b33898484abee0f97..d0e048b5206a859a3ba69bb6a8c267fc65e9332c 100644 (file)
 #include "source.hh"
 #include "source-file.hh"
 
-Input::Input (Source_file*s, char const *cl)
+Input::Input (Input const &i)
 {
-  source_file_ = s;
-  defined_str0_ = cl;
+  source_file_ = i.source_file_;
+  start_ = i.start_;
+  end_ = i.end_;
 }
 
 Input::Input ()
 {
   source_file_ = 0;
-  defined_str0_ = 0;
+  start_ = 0;
+  end_ = 0;
 }
 
 Input
@@ -37,6 +39,22 @@ Input::set_spot (Input const &i)
   *this = i;
 }
 
+void
+Input::step_forward ()
+{
+  if (end_ == start_)
+    end_ ++;
+  start_ ++;
+}
+
+void
+Input::set_location (Input const &i_start, Input const &i_end)
+{
+  source_file_ = i_start.source_file_;
+  start_ = i_start.start_;
+  end_ = i_end.end_;
+}
+
 /*
   Produce GNU-compliant error message.  Correcting lilypond source is
   such a breeze if you ('re edidor) know (s) the error column too
@@ -75,7 +93,7 @@ Input::message (String message_string) const
   if (source_file_)
    {
     str += ":\n";
-    str += source_file_->error_string (defined_str0_);
+    str += source_file_->error_string (start_);
    }
   fprintf (stderr, "%s\n", str.to_str0 ());
   fflush (stderr);
@@ -101,7 +119,7 @@ String
 Input::location_string () const
 {
   if (source_file_)
-    return source_file_->file_line_column_string (defined_str0_);
+    return source_file_->file_line_column_string (start_);
   else
     return " (" + _ ("position unknown") + ")";
 }
@@ -110,7 +128,7 @@ String
 Input::line_number_string () const
 {
   if (source_file_)
-    return to_string (source_file_->get_line (defined_str0_));
+    return to_string (source_file_->get_line (start_));
   else
     return "?";
 }
@@ -129,7 +147,7 @@ int
 Input::line_number () const
 {
   if (source_file_)
-    return source_file_->get_line (defined_str0_);
+    return source_file_->get_line (start_);
   else
     return 0;
 
@@ -139,7 +157,27 @@ int
 Input::column_number () const
 {
   if (source_file_)
-    return source_file_->get_column (defined_str0_);
+    return source_file_->get_column (start_);
+  else
+    return 0;
+
+}
+
+int
+Input::end_line_number () const
+{
+  if (source_file_)
+    return source_file_->get_line (end_);
+  else
+    return 0;
+
+}
+
+int
+Input::end_column_number () const
+{
+  if (source_file_)
+    return source_file_->get_column (end_);
   else
     return 0;
 
index 0a209abf20761e78d73683c511a51f205f14e6f0..2e4d96401ef029c1881a2e09e8d3f9713d4ff53f 100644 (file)
@@ -76,6 +76,9 @@ bool is_valid_version (String s);
 #define yylval \
        (*(YYSTYPE*)lexval)
 
+#define yylloc \
+       (*(YYLTYPE*)lexloc)
+
 #define YY_USER_ACTION add_lexed_char (YYLeng ());
 /*
 
@@ -272,10 +275,10 @@ HYPHEN            --
        return MULTI_MEASURE_REST;
 }
 <INITIAL,markup,chords,lyrics,notes,figures>#  { //embedded scm
-       //char const* s = YYText () + 1;
-       char const* s = here_str0 ();
        int n = 0;
-       SCM sval = ly_parse_scm (s, &n, here_input (),
+       Input hi = here_input();
+       hi.step_forward ();
+       SCM sval = ly_parse_scm (hi.start_, &n, hi,
                be_safe_global && main_input_b_);
 
        if (sval == SCM_UNDEFINED)
index 4fdfcd508823adb05ada55ad8275d6343af2e942..de95f11f44375b05181e885af8fd5d028df0c509 100644 (file)
@@ -134,8 +134,6 @@ Lily_lexer::~Lily_lexer ()
   delete keytable_;
 }
 
-
-
 void
 Lily_lexer::add_scope (SCM module)
 {
@@ -231,7 +229,7 @@ Lily_lexer::LexerError (char const *s)
   else
     {
       error_level_ |= 1;
-      Input spot (get_source_file (), here_str0 ());
+      Input spot (*lexloc);
       spot.error (s);
     }
 }
@@ -256,8 +254,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
@@ -266,6 +263,20 @@ 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::add_lexed_char (int count)
+{
+  lexloc->source_file_ = get_source_file ();
+  lexloc->start_ = here_str0 ();
+  lexloc->end_ = lexloc->start_ + count;
+  char_count_stack_.top () += count;
+}
+
+
 #include "ly-smobs.icc"
 
 IMPLEMENT_SMOBS (Lily_lexer);
index 09781267035ec2fe422cf54c3d09bcd1cdc6854e..3eb14cd13e13d27c40882d845159eb4a3eb656d8 100644 (file)
@@ -161,12 +161,6 @@ Lily_parser::parse_string (String ly_code)
   lexer_ = 0;
 }
 
-void
-Lily_parser::push_spot ()
-{
-  define_spots_.push (here_input ());
-}
-
 char const *
 Lily_parser::here_str0 () const
 {
@@ -176,42 +170,17 @@ Lily_parser::here_str0 () const
 void
 Lily_parser::parser_error (String s)
 {
-  here_input ().error (s);
+  lexer_->here_input ().error (s);
   error_level_ = 1;
 }
 
-Input
-Lily_parser::pop_spot ()
-{
-  return define_spots_.pop ();
-}
-
-Input
-Lily_parser::here_input () const
+void
+Lily_parser::parser_error (Input const& i, String s)
 {
-  /*
-    Parsing looks ahead , so we really want the previous location of the
-    lexer, not lexer_->here_input ().
-  */
-  
-  /*
-    Actually, that gets very icky when there are white space, because
-    the line-numbers are all wrong.  Let's try the character before
-    the current token. That gets the right result for note/duration
-    stuff, but doesn't mess up for errors in the 1st token of the
-    line.
-  */
-  Input hi (lexer_->here_input ());
-
-  char const * bla = hi.defined_str0_;
-  if (hi.line_number () > 1
-      || hi.column_number () > 1)
-    bla --;
-  
-  return Input (hi.source_file_, bla);
+  i.error (s);
+  error_level_ = 1;
 }
 
-
 /****************************************************************/
 
 
index f40d10abbab8fa3cc3ec6dfa53378e4e4926f395..878dac48b99f86836fe7a33b3428a93e11376ed0 100644 (file)
@@ -24,7 +24,7 @@ internal_ly_parse_scm (Parse_start * ps)
   Source_file *sf = ps->start_location_.source_file_;
   SCM port = sf->get_port ();
 
-  int off = ps->start_location_.defined_str0_ - sf->to_str0 ();
+  int off = ps->start_location_.start_ - sf->to_str0 ();
   
   scm_seek (port, scm_long2num (off), scm_long2num (SEEK_SET));
   SCM from = scm_ftell (port);
index 82ff06d3b8f75059a46b8a8d8d624b8701beaba4..15760b48af39728dcc4862a13c62c91f715f263c 100644 (file)
@@ -64,6 +64,12 @@ SCM get_next_unique_lyrics_context_id ();
 
 #define yyerror THIS->parser_error
 
+/* We use custom location type: Input objects */
+#define YYLTYPE Input
+#define YYLLOC_DEFAULT(Current,Rhs,N) \
+       ((Current).set_location ((Rhs)[1], (Rhs)[N]))
+
+
 /* Add symbols to the TAGS field of a music object.  */
 
 void
@@ -213,12 +219,13 @@ of the parse stack onto the heap. */
 %{
 
 int
-yylex (YYSTYPE *s, void *v)
+yylex (YYSTYPE *s, YYLTYPE *l, void *v)
 {
        Lily_parser *pars = (Lily_parser*) v;
        Lily_lexer *lex = pars->lexer_;
 
        lex->lexval = (void*) s;
+       lex->lexloc = l;
        lex->prepare_for_next_token ();
        return lex->yylex ();
 }
@@ -255,6 +262,7 @@ or
 
 
 %pure_parser
+%locations
 
 %token ACCEPTS
 %token ADDQUOTE
@@ -549,22 +557,13 @@ lilypond_header:
        DECLARATIONS
 */
 assignment:
-       STRING {
-               THIS->push_spot ();
-       }
-       /* cont */ '=' identifier_init  {
-
-       /*
-               Should find generic way of associating input with objects.
-       */
-               Input ip = THIS->pop_spot ();
-
+       STRING '=' identifier_init  {
                if (! is_regular_identifier ($1))
                {
-                       ip.warning (_ ("Identifier should have alphabetic characters only"));
+                       @1.warning (_ ("Identifier should have alphabetic characters only"));
                }
 
-               THIS->lexer_->set_identifier ($1, $4);
+               THIS->lexer_->set_identifier ($1, $3);
 
 /*
  TODO: devise standard for protection in parser.
@@ -625,11 +624,11 @@ context_def_spec_block:
 context_def_spec_body:
        /**/ {
                $$ = Context_def::make_scm ();
-               unsmob_context_def ($$)->set_spot (THIS->here_input ());
+               unsmob_context_def ($$)->set_spot (@$);
        }
        | CONTEXT_DEF_IDENTIFIER {
                $$ = $1;
-               unsmob_context_def ($$)->set_spot (THIS->here_input ());
+               unsmob_context_def ($$)->set_spot (@$);
        }
        | context_def_spec_body GROBDESCRIPTIONS embedded_scm {
                Context_def*td = unsmob_context_def ($$);
@@ -650,12 +649,8 @@ context_def_spec_body:
 
 
 book_block:
-       BOOK {
-               THIS->push_spot ();
-       }
-       /*cont*/ '{' book_body '}'      {
-               THIS->pop_spot ();
-               $$ = $4;
+       BOOK '{' book_body '}'  {
+               $$ = $3;
        }
        ;
 
@@ -665,7 +660,7 @@ book_block:
 book_body:
        {
                $$ = new Book;
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
                $$->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (THIS->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
                scm_gc_unprotect_object ($$->paper_->self_scm ());
                $$->header_ = THIS->lexer_->lookup_identifier ("$globalheader"); 
@@ -691,24 +686,19 @@ book_body:
        ;
 
 score_block:
-       SCORE {
-               THIS->push_spot ();
-       }
-       /*cont*/ '{' score_body '}'     {
-               THIS->pop_spot ();
-               $$ = $4;
+       SCORE '{' score_body '}'        {
+               $$ = $3;
        }
        ;
 
 score_body:
        /**/    {
                $$ = new Score;
-       
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
        }
        | SCORE_IDENTIFIER {
                $$ = new Score ( *unsmob_score ($1));
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
        }
        | score_body object_id_setting {
                $$->user_key_ = ly_scm2string ($2);
@@ -724,7 +714,7 @@ score_body:
        | score_body output_def {
                if ($2->lookup_variable (ly_symbol2scm ("is-paper")) == SCM_BOOL_T)
                {
-                       THIS->parser_error (_("\\paper cannot be in \\score. Use \\layout instead"));
+                       THIS->parser_error (@2, _("\\paper cannot be in \\score. Use \\layout instead"));
                
                }
                else
@@ -748,7 +738,7 @@ paper_block:
                $$ = $1;
                if ($$->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
                {
-                       THIS->parser_error (_("Need \\paper for paper block."));
+                       THIS->parser_error (@1, _("Need \\paper for paper block."));
                        $$ = get_paper (THIS);
                }
        }
@@ -767,7 +757,7 @@ output_def:
 output_def_head:
        PAPER {
                $$ = get_paper (THIS);
-               $$->input_origin_ = THIS->here_input ();
+               $$->input_origin_ = @$;
                THIS->lexer_->add_scope ($$->scope_);
        }
        | MIDI    {
@@ -787,13 +777,13 @@ output_def_head:
 output_def_body:
        output_def_head '{' {
                $$ = $1;
-               $$->input_origin_.set_spot (THIS->here_input ());
+               $$->input_origin_.set_spot (@$);
                THIS->lexer_->push_initial_state ();
        }
        | output_def_head '{' OUTPUT_DEF_IDENTIFIER     {
                scm_gc_unprotect_object ($1->self_scm ());
                Output_def *o = unsmob_output_def ($3);
-               o->input_origin_.set_spot (THIS->here_input ());
+               o->input_origin_.set_spot (@$);
                $$ = o;
                THIS->lexer_->remove_scope ();
                THIS->lexer_->add_scope (o->scope_);
@@ -947,12 +937,12 @@ Sequential_music:
        SEQUENTIAL '{' Music_list '}'           {
                $$ = MY_MAKE_MUSIC ("SequentialMusic");
                $$->set_property ("elements", scm_car ($3));
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
        }
        | '{' Music_list '}'            {
                $$ = MY_MAKE_MUSIC ("SequentialMusic");
                $$->set_property ("elements", scm_car ($2));
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
        }
        ;
 
@@ -960,13 +950,13 @@ Simultaneous_music:
        SIMULTANEOUS '{' Music_list '}'{
                $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
                $$->set_property ("elements", scm_car ($3));
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
 
        }
        | simul_open Music_list simul_close     {
                $$ = MY_MAKE_MUSIC ("SimultaneousMusic");
                $$->set_property ("elements", scm_car ($2));
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
        }
        ;
 
@@ -1010,72 +1000,48 @@ Grouped_music_list:
 
 Generic_prefix_music_scm:
        MUSIC_FUNCTION {
-               $$ = scm_list_2 ($1, make_input (THIS->here_input ()));
-       }
-       | MUSIC_FUNCTION_SCM {
-               THIS->push_spot ();
-       } embedded_scm {
-               $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3);
-       }
-       | MUSIC_FUNCTION_MARKUP {
-               THIS->push_spot ();
-       } full_markup {
-               $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3);
-       }
-       | MUSIC_FUNCTION_MUSIC {
-               THIS->push_spot (); 
-       } Music {
-               $$ = scm_list_3 ($1, make_input (THIS->pop_spot ()), $3->self_scm ());
-               scm_gc_unprotect_object ($3->self_scm ());
+               $$ = scm_list_2 ($1, make_input (@$));
        }
-       | MUSIC_FUNCTION_SCM_MUSIC {
-               THIS->push_spot (); 
-       }  embedded_scm Music {
-               $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3, $4->self_scm ());
-               scm_gc_unprotect_object ($4->self_scm ());
+       | MUSIC_FUNCTION_SCM embedded_scm {
+               $$ = scm_list_3 ($1, make_input (@$), $2);
        }
-       | MUSIC_FUNCTION_SCM_SCM {
-               THIS->push_spot (); 
-       }  embedded_scm embedded_scm {
-               $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3, $4);
+       | MUSIC_FUNCTION_MARKUP full_markup {
+               $$ = scm_list_3 ($1, make_input (@$), $2);
        }
-       | MUSIC_FUNCTION_SCM_SCM_MUSIC {
-               THIS->push_spot (); 
-       }  embedded_scm embedded_scm Music {
-               $$ = scm_list_5 ($1, make_input (THIS->pop_spot ()), $3, $4, $5->self_scm ());
+       | MUSIC_FUNCTION_MUSIC Music {
+               $$ = scm_list_3 ($1, make_input (@$), $2->self_scm ());
+               scm_gc_unprotect_object ($2->self_scm ());
        }
-       | MUSIC_FUNCTION_MARKUP_MUSIC {
-               THIS->push_spot (); 
-       }  full_markup Music {
-               $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3, $4->self_scm ());
-               scm_gc_unprotect_object ($4->self_scm ());
+       | MUSIC_FUNCTION_SCM_MUSIC embedded_scm Music {
+               $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
+               scm_gc_unprotect_object ($3->self_scm ());
        }
-       | MUSIC_FUNCTION_MARKUP_MARKUP {
-               THIS->push_spot (); 
-       }  full_markup full_markup {
-               $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3, $4);
+       | MUSIC_FUNCTION_SCM_SCM embedded_scm embedded_scm {
+               $$ = scm_list_4 ($1, make_input (@$), $2, $3);
        }
-       | MUSIC_FUNCTION_MUSIC_MUSIC {
-               THIS->push_spot (); 
-       }  Music  Music {
-               $$ = scm_list_4 ($1, make_input (THIS->pop_spot ()), $3->self_scm (), $4->self_scm ());
+       | MUSIC_FUNCTION_SCM_SCM_MUSIC embedded_scm embedded_scm Music {
+               $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4->self_scm ());
+       }
+       | MUSIC_FUNCTION_MARKUP_MUSIC full_markup Music {
+               $$ = scm_list_4 ($1, make_input (@$), $2, $3->self_scm ());
                scm_gc_unprotect_object ($3->self_scm ());
-               scm_gc_unprotect_object ($4->self_scm ());
        }
-       | MUSIC_FUNCTION_SCM_MUSIC_MUSIC {
-               THIS->push_spot (); 
-       } embedded_scm Music Music {
-               $$ = scm_list_5 ($1, make_input (THIS->pop_spot ()),
-                       $3, $4->self_scm (), $5->self_scm ());
-               scm_gc_unprotect_object ($5->self_scm ());
+       | MUSIC_FUNCTION_MARKUP_MARKUP full_markup full_markup {
+               $$ = scm_list_4 ($1, make_input (@$), $2, $3);
+       }
+       | MUSIC_FUNCTION_MUSIC_MUSIC Music Music {
+               $$ = scm_list_4 ($1, make_input (@$), $2->self_scm (), $3->self_scm ());
+               scm_gc_unprotect_object ($2->self_scm ());
+               scm_gc_unprotect_object ($3->self_scm ());
+       }
+       | MUSIC_FUNCTION_SCM_MUSIC_MUSIC embedded_scm Music Music {
+               $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
                scm_gc_unprotect_object ($4->self_scm ());
+               scm_gc_unprotect_object ($3->self_scm ());
        }
-       | MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC {
-               THIS->push_spot (); 
-       } full_markup Music Music {
-               $$ = scm_list_5 ($1, make_input (THIS->pop_spot ()),
-                       $3, $4->self_scm (), $5->self_scm ());
-               scm_gc_unprotect_object ($5->self_scm ());
+       | MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC full_markup Music Music {
+               $$ = scm_list_5 ($1, make_input (@$), $2, $3->self_scm (), $4->self_scm ());
+               scm_gc_unprotect_object ($3->self_scm ());
                scm_gc_unprotect_object ($4->self_scm ());
        }
        ;
@@ -1133,18 +1099,14 @@ Prefix_composite_music:
                        $3);
        }
 
-       | TIMES {
-               THIS->push_spot ();
-       }
-       /* CONTINUED */
-               fraction Music  
+       | TIMES fraction Music  
 
        {
-               int n = scm_to_int (scm_car ($3)); int d = scm_to_int (scm_cdr ($3));
-               Music *mp = $4;
+               int n = scm_to_int (scm_car ($2)); int d = scm_to_int (scm_cdr ($2));
+               Music *mp = $3;
 
                $$= MY_MAKE_MUSIC ("TimeScaledMusic");
-               $$->set_spot (THIS->pop_spot ());
+               $$->set_spot (@$);
 
                $$->set_property ("element", mp->self_scm ());
                scm_gc_unprotect_object (mp->self_scm ());
@@ -1193,7 +1155,7 @@ Prefix_composite_music:
        | relative_music        { $$ = $1; }
        | re_rhythmed_music     { $$ = $1; }
        | TAG embedded_scm Music {
-               tag_music ($3, $2, THIS->here_input ());
+               tag_music ($3, $2, @$);
                $$ = $3;
        }
        ;
@@ -1338,7 +1300,7 @@ context_change:
                t-> set_property ("change-to-id", $4);
 
                $$ = t;
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
        }
        ;
 
@@ -1385,7 +1347,7 @@ context_prop_spec:
        simple_string {
                if (!is_regular_identifier ($1))
                {
-                       THIS->here_input ().error (_("Grob name should be alphanumeric"));
+                       @$.error (_("Grob name should be alphanumeric"));
                }
 
                $$ = scm_list_2 (ly_symbol2scm ("Bottom"),
@@ -1494,9 +1456,7 @@ nevertheless, this is not very clean, and we should find a different
 solution.
 
 */
-pre_events: {
-               THIS->push_spot ();
-       }
+pre_events: /* empty */
        ;
 
 event_chord:
@@ -1506,6 +1466,11 @@ event_chord:
                elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
 
                $2->set_property ("elements", elts);
+               /* why is this giving wrong start location? -ns
+                * $2->set_spot (@$); */
+               Input i;
+               i.set_location (@2, @3);
+               $2->set_spot (i);
                $$ = $2;
        }
        | command_element
@@ -1525,6 +1490,7 @@ note_chord_element:
                es = ly_append2 (es, postevs);
 
                $1-> set_property ("elements", es);
+               $1->set_spot (@$);
                $$ = $1;
        }
        ;
@@ -1545,6 +1511,7 @@ chord_body:
        chord_open chord_body_elements chord_close
        {
                $$ = MY_MAKE_MUSIC ("EventChord");
+               $$->set_spot (@$);
                $$->set_property ("elements",
                        scm_reverse_x ($2, SCM_EOL));
        }
@@ -1559,7 +1526,7 @@ chord_body_elements:
        ;
 
 chord_body_element:
-       pitch  exclamations questions octave_check post_events
+       pitch exclamations questions octave_check post_events
        {
                int q = $3;
                int ex = $2;
@@ -1568,6 +1535,7 @@ chord_body_element:
 
                Music *n = MY_MAKE_MUSIC ("NoteEvent");
                n->set_property ("pitch", $1);
+               n->set_spot (@$);
                if (q % 2)
                        n->set_property ("cautionary", SCM_BOOL_T);
                if (ex % 2 || q % 2)
@@ -1590,7 +1558,7 @@ chord_body_element:
                Music *n = MY_MAKE_MUSIC ("NoteEvent");
                n->set_property ("duration", $2);
                n->set_property ("drum-type", $1);
-               n->set_spot (THIS->here_input ());
+               n->set_spot (@$);
 
                if (scm_is_pair ($2)) {
                        SCM arts = scm_reverse_x ($2, SCM_EOL);
@@ -1615,45 +1583,44 @@ command_element:
                $$->set_property ("elements", scm_cons ($1->self_scm (), SCM_EOL));
                scm_gc_unprotect_object ($1->self_scm ());
 
-               $$-> set_spot (THIS->here_input ());
-               $1-> set_spot (THIS->here_input ());
+               $$-> set_spot (@$);
+               $1-> set_spot (@$);
        }
        | SKIP duration_length {
                Music *skip = MY_MAKE_MUSIC ("SkipMusic");
                skip->set_property ("duration", $2);
-
+               skip->set_spot (@$);
                $$ = skip;
        }
-       | OCTAVE { THIS->push_spot (); }
-         pitch {
+       | OCTAVE pitch {
                Music *m = MY_MAKE_MUSIC ("RelativeOctaveCheck");
                $$ = m;
-               $$->set_spot (THIS->pop_spot ());
-               $$->set_property ("pitch", $3);
+               $$->set_spot (@$);
+               $$->set_property ("pitch", $2);
        }
        | E_LEFTSQUARE {
                Music *m = MY_MAKE_MUSIC ("LigatureEvent");
                m->set_property ("span-direction", scm_int2num (START));
-               m->set_spot (THIS->here_input ());
+               m->set_spot (@$);
 
                $$ = MY_MAKE_MUSIC ("EventChord");
                $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
                scm_gc_unprotect_object (m->self_scm ());
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
        }
        | E_RIGHTSQUARE {
                Music *m = MY_MAKE_MUSIC ("LigatureEvent");
                m->set_property ("span-direction", scm_int2num (STOP));
-               m->set_spot (THIS->here_input ());
+               m->set_spot (@$);
 
                $$ = MY_MAKE_MUSIC ("EventChord");
                $$->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
                scm_gc_unprotect_object (m->self_scm ());
        }
        | E_BACKSLASH {
                $$ = MY_MAKE_MUSIC ("VoiceSeparator");
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
        }
        | '|'      {
                SCM pipe = THIS->lexer_->lookup_identifier ("pipeSymbol");
@@ -1663,14 +1630,14 @@ command_element:
                else
                        $$ = MY_MAKE_MUSIC ("BarCheck");
 
-               $$->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
        }
        | TRANSPOSITION pitch {
                Pitch middle_c;
                Pitch sounds_as_c = pitch_interval (*unsmob_pitch ($2), middle_c);
                $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
                                         sounds_as_c.smobbed_copy());
-               $$->set_spot (THIS-> here_input ());
+               $$->set_spot (@$);
                $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
                        $$, SCM_EOL);
        }
@@ -1680,13 +1647,13 @@ command_element:
                Music *csm = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
                                        t, SCM_EOL);
                $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED, csm, SCM_EOL);
-               $$->set_spot (THIS->here_input ());
-               t->set_spot (THIS->here_input ());
+               $$->set_spot (@$);
+               t->set_spot (@$);
        }
        | PARTIAL duration_length       {
                Moment m = - unsmob_duration ($2)->get_length ();
                Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
-               p->set_spot (THIS->here_input ());
+               p->set_spot (@$);
                p = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
                                        p, SCM_EOL);
                p = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
@@ -1740,24 +1707,25 @@ command_req:
                        key->set_property ("tonic", Pitch (0,0,0).smobbed_copy ());
                        key->transpose (* unsmob_pitch ($2));
                } else {
-                       THIS->parser_error (_ ("Second argument must be pitch list."));
+                       THIS->parser_error (@3, _ ("Second argument must be pitch list."));
                }
 
                $$ = key;
        }
        ;
 
+
 post_events:
        /* empty */ {
                $$ = SCM_EOL;
        }
        | post_events post_event {
-               $2->set_spot (THIS->here_input ());
+               $2->set_spot (@2);
                $$ = scm_cons ($2->self_scm (), $$);
                scm_gc_unprotect_object ($2->self_scm ());
        }
        | post_events tagged_post_event {
-               $2 -> set_spot (THIS->here_input ());
+               $2 -> set_spot (@2);
                $$ = scm_cons ($2->self_scm (), $$);
                scm_gc_unprotect_object ($2->self_scm ());
        }
@@ -1766,23 +1734,24 @@ post_events:
 
 tagged_post_event:
        '-' TAG embedded_scm post_event {
-               tag_music ($4, $3, THIS->here_input ());
+               tag_music ($4, $3, @$);
                $$ = $4;
        }
        ;
 
+
 post_event:
        direction_less_event {
                $$ = $1;
        }
        | HYPHEN {
                if (!THIS->lexer_->is_lyric_state ())
-                       THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
+                       THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
                $$ = MY_MAKE_MUSIC ("HyphenEvent");
        }
        | EXTENDER {
                if (!THIS->lexer_->is_lyric_state ())
-                       THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
+                       THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
                $$ = MY_MAKE_MUSIC ("ExtenderEvent");
        }
        | script_dir direction_reqd_event {
@@ -1802,7 +1771,7 @@ string_number_event:
        E_UNSIGNED {
                Music *s = MY_MAKE_MUSIC ("StringNumberEvent");
                s->set_property ("string-number", scm_int2num ($1));
-               s->set_spot (THIS->here_input ());
+               s->set_spot (@$);
                $$ = s;
        }
        ;
@@ -1852,7 +1821,7 @@ direction_less_event:
                {
                        m = MY_MAKE_MUSIC ("Music");
                }
-               m->set_spot (THIS->here_input ());
+               m->set_spot (@$);
                $$ = m;         
        }
        | EVENT_IDENTIFIER      {
@@ -1860,7 +1829,7 @@ direction_less_event:
        }
        | tremolo_type  {
                Music *a = MY_MAKE_MUSIC ("TremoloEvent");
-               a->set_spot (THIS->here_input ());
+               a->set_spot (@$);
                a->set_property ("tremolo-type", scm_int2num ($1));
                $$ = a;
         }
@@ -1875,7 +1844,7 @@ direction_reqd_event:
                Music *a = MY_MAKE_MUSIC ("ArticulationEvent");
                if (scm_is_string (s))
                        a->set_property ("articulation-type", s);
-               else THIS->parser_error (_ ("Expecting string as script definition"));
+               else THIS->parser_error (@1, _ ("Expecting string as script definition"));
                $$ = a;
        }
        ;
@@ -1957,21 +1926,21 @@ gen_text_def:
        full_markup {
                Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
                t->set_property ("text", $1);
-               t->set_spot (THIS->here_input ());
+               t->set_spot (@$);
                $$ = t; 
        }
        | string {
                Music *t = MY_MAKE_MUSIC ("TextScriptEvent");
                t->set_property ("text",
                        make_simple_markup ($1));
-               t->set_spot (THIS->here_input ());
+               t->set_spot (@$);
                $$ = t;
        
        }
        | DIGIT {
                Music *t = MY_MAKE_MUSIC ("FingerEvent");
                t->set_property ("digit", scm_int2num ($1));
-               t->set_spot (THIS->here_input ());
+               t->set_spot (@$);
                $$ = t;
        }
        ;
@@ -2038,7 +2007,7 @@ steno_duration:
        bare_unsigned dots              {
                int len = 0;
                if (!is_duration ($1))
-                       THIS->parser_error (_f ("not a duration: %d", $1));
+                       THIS->parser_error (@1, _f ("not a duration: %d", $1));
                else
                        len = intlog2 ($1);
 
@@ -2088,7 +2057,7 @@ tremolo_type:
        }
        | ':' bare_unsigned {
                if (!is_duration ($2))
-                       THIS->parser_error (_f ("not a duration: %d", $2));
+                       THIS->parser_error (@2, _f ("not a duration: %d", $2));
                $$ = $2;
        }
        ;
@@ -2180,10 +2149,8 @@ optional_rest:
 
 simple_element:
        pitch exclamations questions octave_check optional_notemode_duration optional_rest {
-
-               Input i = THIS->pop_spot ();
                if (!THIS->lexer_->is_note_state ())
-                       THIS->parser_error (_ ("Have to be in Note mode for notes"));
+                       THIS->parser_error (@1, _ ("Have to be in Note mode for notes"));
 
                Music *n = 0;
                if ($6)
@@ -2209,13 +2176,11 @@ simple_element:
                v->set_property ("elements", scm_list_1 (n->self_scm ()));
                scm_gc_unprotect_object (n->self_scm ());
 
-               v->set_spot (i);
-               n->set_spot (i);
+               v->set_spot (@$);
+               n->set_spot (@$);
                $$ = v;
        }
        | DRUM_PITCH optional_notemode_duration {
-               Input i = THIS->pop_spot ();
-
                Music *n = MY_MAKE_MUSIC ("NoteEvent");
                n->set_property ("duration", $2);
                n->set_property ("drum-type", $1);
@@ -2223,15 +2188,14 @@ simple_element:
                Music *v = MY_MAKE_MUSIC ("EventChord");
                v->set_property ("elements", scm_list_1 (n->self_scm ()));
                scm_gc_unprotect_object (n->self_scm ());
-               v->set_spot (i);
-               n->set_spot (i);
+               v->set_spot (@$);
+               n->set_spot (@$);
                $$ = v;
                
        }
        | figure_spec optional_notemode_duration {
                Music *m = unsmob_music ($1);
-               Input i = THIS->pop_spot ();
-               m->set_spot (i);
+               m->set_spot (@$);
                for (SCM s = m->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s))
                {
                        unsmob_music (scm_car (s))->set_property ("duration", $2);
@@ -2239,8 +2203,6 @@ simple_element:
                $$ = m;
        }       
        | RESTNAME optional_notemode_duration           {
-
-               Input i = THIS->pop_spot ();
                Music *ev = 0;
                if (ly_scm2string ($1) == "s") {
                        /* Space */
@@ -2251,44 +2213,38 @@ simple_element:
                
                    }
                ev->set_property ("duration", $2);
-               ev->set_spot (i);
+               ev->set_spot (@$);
                Music *velt = MY_MAKE_MUSIC ("EventChord");
                velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
-               velt->set_spot (i);
+               velt->set_spot (@$);
 
                scm_gc_unprotect_object (ev->self_scm ());
 
                $$ = velt;
        }
        | MULTI_MEASURE_REST optional_notemode_duration         {
-               THIS->pop_spot ();
-
                SCM proc = ly_lily_module_constant ("make-multi-measure-rest");
-               SCM mus = scm_call_2 (proc, $2,
-                       make_input (THIS->here_input ()));      
+               SCM mus = scm_call_2 (proc, $2, make_input (@$));
                scm_gc_protect_object (mus);
                $$ = unsmob_music (mus);
        }
        
        | lyric_element optional_notemode_duration      {
-               Input i = THIS->pop_spot ();
                if (!THIS->lexer_->is_lyric_state ())
-                       THIS->parser_error (_ ("Have to be in Lyric mode for lyrics"));
+                       THIS->parser_error (@1, _ ("Have to be in Lyric mode for lyrics"));
 
                Music *lreq = MY_MAKE_MUSIC ("LyricEvent");
-                lreq->set_property ("text", $1);
+               lreq->set_property ("text", $1);
                lreq->set_property ("duration",$2);
-               lreq->set_spot (i);
+               lreq->set_spot (@$);
                Music *velt = MY_MAKE_MUSIC ("EventChord");
                velt->set_property ("elements", scm_list_1 (lreq->self_scm ()));
 
                $$= velt;
        }
        | new_chord {
-               THIS->pop_spot ();
-
                 if (!THIS->lexer_->is_chord_state ())
-                        THIS->parser_error (_ ("Have to be in Chord mode for chords"));
+                        THIS->parser_error (@1, _ ("Have to be in Chord mode for chords"));
                 $$ = unsmob_music ($1);
        }
        ;
@@ -2440,7 +2396,7 @@ bare_int:
                        $$ = k;
                } else
                {
-                       THIS->parser_error (_ ("need integer number arg"));
+                       THIS->parser_error (@1, _ ("need integer number arg"));
                        $$ = 0;
                }
        }
index 1253bb5f066db63365e3fe6ab38c8ea44167718a..2bf8761bc69317e71e7b400697b62e6325680bf8 100644 (file)
@@ -72,6 +72,10 @@ Source_file::Source_file (String filename, String data)
   length_ = data.length ();
   pos_str0_ = to_str0 ();
   init_port ();
+
+  for (int i = 0; i < length_; i++)
+    if (contents_str0_[i] == '\n')
+      newline_locations_.push (contents_str0_ + i);
 }
 
 Source_file::Source_file (String filename_string)