/usr/share/lilypond/2.14.2/scm/parser-ly-from-scheme.scm is in lilypond-data 2.14.2-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | ;;;; This file is part of LilyPond, the GNU music typesetter.
;;;;
;;;; Copyright (C) 2004--2011 Nicolas Sceaux <nicolas.sceaux@free.fr>
;;;; 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/>.
(define gen-lily-sym
;; Generate a lilyvartmpXX symbol, that may be (hopefully) unique.
(let ((var-idx -1))
(lambda ()
(set! var-idx (1+ var-idx))
(string->symbol (format #f "lilyvartmp~a"
(list->string (map (lambda (chr)
(integer->char (+ (char->integer #\a)
(- (char->integer chr)
(char->integer #\0)))))
(string->list (number->string var-idx)))))))))
(define-public (parse-string-result str parser)
"Parse @var{str}, which is supposed to contain a music expression."
(ly:parser-parse-string
parser
(format #f "parseStringResult = \\notemode { ~a }" str))
(ly:parser-lookup parser 'parseStringResult))
(define-public (read-lily-expression chr port)
"Read a lilypond music expression enclosed within @code{#@}} and @code{#@}}
from @var{port} and return the corresponding Scheme music expression.
The @samp{$} character may be used to introduce Scheme forms, typically
symbols. @code{$$} may be used to simply write a @samp{$} character itself."
(let ((bindings '()))
(define (create-binding! val)
"Create a new symbol, bind it to `val' and return it."
(let ((tmp-symbol (gen-lily-sym)))
(set! bindings (cons (cons tmp-symbol val) bindings))
tmp-symbol))
(define (remove-dollars! form)
"Generate a form where `$variable' and `$ value' mottos are replaced
by new symbols, which are binded to the adequate values."
(cond (;; $variable
(and (symbol? form)
(string=? (substring (symbol->string form) 0 1) "$")
(not (and (<= 2 (string-length (symbol->string form)))
(string=? (substring (symbol->string form) 1 2) "$"))))
(create-binding! (string->symbol (substring (symbol->string form) 1))))
(;; atom
(not (pair? form)) form)
(;; ($ value ...)
(eqv? (car form) '$)
(cons (create-binding! (cadr form)) (remove-dollars! (cddr form))))
(else ;; (something ...)
(cons (remove-dollars! (car form)) (remove-dollars! (cdr form))))))
(let ((lily-string (call-with-output-string
(lambda (out)
(do ((c (read-char port) (read-char port)))
((and (char=? c #\#)
(char=? (peek-char port) #\})) ;; we stop when #} is encoutered
(read-char port))
(cond
;; a $form expression
((and (char=? c #\$) (not (char=? (peek-char port) #\$)))
(format out "\\~a" (create-binding! (read port))))
;; just a $ character
((and (char=? c #\$) (char=? (peek-char port) #\$))
;; pop the second $
(display (read-char port) out))
;; a #scheme expression
((char=? c #\#)
(let ((expr (read port)))
(format out "#~s" (if (eq? '$ expr)
(create-binding! (read port))
(remove-dollars! expr)))))
;; other caracters
(else
(display c out))))))))
`(let ((parser-clone (ly:parser-clone parser)))
,@(map (lambda (binding)
`(ly:parser-define! parser-clone ',(car binding) ,(cdr binding)))
(reverse bindings))
(parse-string-result ,lily-string parser-clone)))))
(read-hash-extend #\{ read-lily-expression)
|