OLD | NEW |
1 /* | 1 /* |
2 This file is part of LilyPond, the GNU music typesetter. | 2 This file is part of LilyPond, the GNU music typesetter. |
3 | 3 |
4 Copyright (C) 1997--2020 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 1997--2020 Han-Wen Nienhuys <hanwen@xs4all.nl> |
5 | 5 |
6 LilyPond is free software: you can redistribute it and/or modify | 6 LilyPond is free software: you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
8 the Free Software Foundation, either version 3 of the License, or | 8 the Free Software Foundation, either version 3 of the License, or |
9 (at your option) any later version. | 9 (at your option) any later version. |
10 | 10 |
11 LilyPond is distributed in the hope that it will be useful, | 11 LilyPond is distributed in the hope that it will be useful, |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 GNU General Public License for more details. | 14 GNU General Public License for more details. |
15 | 15 |
16 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>. | 17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>. |
18 */ | 18 */ |
19 | 19 |
20 #include "lily-lexer.hh" | 20 #include "lily-lexer.hh" |
21 | 21 |
22 #include <cctype> | |
23 #include <sstream> | |
24 | |
25 #include "context.hh" // for nested_property_alist | 22 #include "context.hh" // for nested_property_alist |
26 #include "international.hh" | 23 #include "international.hh" |
27 #include "interval.hh" | 24 #include "interval.hh" |
28 #include "keyword.hh" | |
29 #include "main.hh" | 25 #include "main.hh" |
30 #include "moment.hh" | 26 #include "moment.hh" |
31 #include "parser.hh" | 27 #include "parser.hh" |
32 #include "scm-hash.hh" | 28 #include "scm-hash.hh" |
33 #include "source-file.hh" | 29 #include "source-file.hh" |
34 #include "warn.hh" | 30 #include "warn.hh" |
35 #include "program-option.hh" | 31 #include "program-option.hh" |
36 #include "lily-parser.hh" | 32 #include "lily-parser.hh" |
37 #include "ly-module.hh" | 33 #include "ly-module.hh" |
38 | 34 |
| 35 #include <cctype> |
| 36 #include <sstream> |
| 37 #include <unordered_map> |
| 38 |
39 using std::string; | 39 using std::string; |
40 | 40 |
41 static Keyword_ent the_key_tab[] | 41 static std::unordered_map<std::string, int> keytable{ |
42 = | |
43 { | |
44 {"accepts", ACCEPTS}, | 42 {"accepts", ACCEPTS}, |
45 {"addlyrics", ADDLYRICS}, | 43 {"addlyrics", ADDLYRICS}, |
46 {"alias", ALIAS}, | 44 {"alias", ALIAS}, |
47 {"alternative", ALTERNATIVE}, | 45 {"alternative", ALTERNATIVE}, |
48 {"book", BOOK}, | 46 {"book", BOOK}, |
49 {"bookpart", BOOKPART}, | 47 {"bookpart", BOOKPART}, |
50 {"change", CHANGE}, | 48 {"change", CHANGE}, |
51 {"chordmode", CHORDMODE}, | 49 {"chordmode", CHORDMODE}, |
52 {"chords", CHORDS}, | 50 {"chords", CHORDS}, |
53 {"consists", CONSISTS}, | 51 {"consists", CONSISTS}, |
(...skipping 25 matching lines...) Expand all Loading... |
79 {"rest", REST}, | 77 {"rest", REST}, |
80 {"revert", REVERT}, | 78 {"revert", REVERT}, |
81 {"score", SCORE}, | 79 {"score", SCORE}, |
82 {"sequential", SEQUENTIAL}, | 80 {"sequential", SEQUENTIAL}, |
83 {"set", SET}, | 81 {"set", SET}, |
84 {"simultaneous", SIMULTANEOUS}, | 82 {"simultaneous", SIMULTANEOUS}, |
85 {"tempo", TEMPO}, | 83 {"tempo", TEMPO}, |
86 {"type", TYPE}, | 84 {"type", TYPE}, |
87 {"unset", UNSET}, | 85 {"unset", UNSET}, |
88 {"with", WITH}, | 86 {"with", WITH}, |
89 {0, 0} | |
90 }; | 87 }; |
91 | 88 |
92 Lily_lexer::Lily_lexer (Sources *sources, Lily_parser *parser) | 89 Lily_lexer::Lily_lexer (Sources *sources, Lily_parser *parser) |
93 { | 90 { |
94 parser_ = parser; | 91 parser_ = parser; |
95 keytable_ = new Keyword_table (the_key_tab); | 92 |
96 chordmodifier_tab_ = SCM_EOL; | 93 chordmodifier_tab_ = SCM_EOL; |
97 pitchname_tab_stack_ = SCM_EOL; | 94 pitchname_tab_stack_ = SCM_EOL; |
98 sources_ = sources; | 95 sources_ = sources; |
99 scopes_ = SCM_EOL; | 96 scopes_ = SCM_EOL; |
100 error_level_ = 0; | 97 error_level_ = 0; |
101 is_main_input_ = false; | 98 is_main_input_ = false; |
102 main_input_level_ = 0; | 99 main_input_level_ = 0; |
103 start_module_ = SCM_EOL; | 100 start_module_ = SCM_EOL; |
104 extra_tokens_ = SCM_EOL; | 101 extra_tokens_ = SCM_EOL; |
105 smobify_self (); | 102 smobify_self (); |
106 | 103 |
107 add_scope (ly_make_module (false)); | 104 add_scope (ly_make_module (false)); |
108 push_note_state (SCM_EOL); | 105 push_note_state (SCM_EOL); |
109 chordmodifier_tab_ = scm_make_vector (scm_from_int (1), SCM_EOL); | 106 chordmodifier_tab_ = scm_make_vector (scm_from_int (1), SCM_EOL); |
110 } | 107 } |
111 | 108 |
112 Lily_lexer::Lily_lexer (Lily_lexer const &src, Lily_parser *parser, | 109 Lily_lexer::Lily_lexer (Lily_lexer const &src, Lily_parser *parser, |
113 SCM override_input) | 110 SCM override_input) |
114 : Includable_lexer () | 111 : Includable_lexer () |
115 { | 112 { |
116 parser_ = parser; | 113 parser_ = parser; |
117 keytable_ = (src.keytable_) ? new Keyword_table (*src.keytable_) : 0; | |
118 chordmodifier_tab_ = src.chordmodifier_tab_; | 114 chordmodifier_tab_ = src.chordmodifier_tab_; |
119 pitchname_tab_stack_ = src.pitchname_tab_stack_; | 115 pitchname_tab_stack_ = src.pitchname_tab_stack_; |
120 sources_ = src.sources_; | 116 sources_ = src.sources_; |
121 scopes_ = src.scopes_; | 117 scopes_ = src.scopes_; |
122 start_module_ = SCM_EOL; | 118 start_module_ = SCM_EOL; |
123 | 119 |
124 error_level_ = 0; | 120 error_level_ = 0; |
125 is_main_input_ = src.is_main_input_; | 121 is_main_input_ = src.is_main_input_; |
126 main_input_level_ = 0; | 122 main_input_level_ = 0; |
127 | 123 |
128 extra_tokens_ = SCM_EOL; | 124 extra_tokens_ = SCM_EOL; |
129 if (unsmob<Input> (override_input)) | 125 if (unsmob<Input> (override_input)) |
130 override_input_ = *unsmob<Input> (override_input); | 126 override_input_ = *unsmob<Input> (override_input); |
131 | 127 |
132 smobify_self (); | 128 smobify_self (); |
133 | 129 |
134 push_note_state (SCM_EOL); | 130 push_note_state (SCM_EOL); |
135 } | 131 } |
136 | 132 |
137 Lily_lexer::~Lily_lexer () | |
138 { | |
139 delete keytable_; | |
140 } | |
141 | |
142 void | 133 void |
143 Lily_lexer::add_scope (SCM module) | 134 Lily_lexer::add_scope (SCM module) |
144 { | 135 { |
145 ly_reexport_module (scm_current_module ()); | 136 ly_reexport_module (scm_current_module ()); |
146 if (!scm_is_pair (scopes_)) | 137 if (!scm_is_pair (scopes_)) |
147 start_module_ = scm_current_module (); | 138 start_module_ = scm_current_module (); |
148 | 139 |
149 for (SCM s = scopes_; scm_is_pair (s); s = scm_cdr (s)) | 140 for (SCM s = scopes_; scm_is_pair (s); s = scm_cdr (s)) |
150 ly_use_module (module, scm_car (s)); | 141 ly_use_module (module, scm_car (s)); |
151 scopes_ = scm_cons (module, scopes_); | 142 scopes_ = scm_cons (module, scopes_); |
(...skipping 24 matching lines...) Expand all Loading... |
176 scm_set_current_module (scm_car (scopes_)); | 167 scm_set_current_module (scm_car (scopes_)); |
177 else | 168 else |
178 scm_set_current_module (start_module_); | 169 scm_set_current_module (start_module_); |
179 | 170 |
180 return old; | 171 return old; |
181 } | 172 } |
182 | 173 |
183 int | 174 int |
184 Lily_lexer::lookup_keyword (const string &s) | 175 Lily_lexer::lookup_keyword (const string &s) |
185 { | 176 { |
186 return keytable_->lookup (s.c_str ()); | 177 auto const &it = keytable.find (s); |
| 178 if (it == keytable.end ()) |
| 179 { |
| 180 return -1; |
| 181 } |
| 182 return it->second; |
187 } | 183 } |
188 | 184 |
189 SCM | 185 SCM |
190 Lily_lexer::keyword_list () const | |
191 { | |
192 if (!keytable_) | |
193 return SCM_EOL; | |
194 | |
195 SCM l = SCM_EOL; | |
196 SCM *tail = &l; | |
197 for (vsize i = 0; i < keytable_->table_.size (); i++) | |
198 { | |
199 *tail = scm_acons (scm_from_utf8_string (keytable_->table_[i].name_), | |
200 scm_from_int (keytable_->table_[i].tokcode_), | |
201 SCM_EOL); | |
202 | |
203 tail = SCM_CDRLOC (*tail); | |
204 } | |
205 | |
206 return l; | |
207 } | |
208 | |
209 SCM | |
210 Lily_lexer::lookup_identifier_symbol (SCM sym) | 186 Lily_lexer::lookup_identifier_symbol (SCM sym) |
211 { | 187 { |
212 for (SCM s = scopes_; scm_is_pair (s); s = scm_cdr (s)) | 188 for (SCM s = scopes_; scm_is_pair (s); s = scm_cdr (s)) |
213 { | 189 { |
214 SCM var = ly_module_lookup (scm_car (s), sym); | 190 SCM var = ly_module_lookup (scm_car (s), sym); |
215 if (scm_is_true (var)) | 191 if (scm_is_true (var)) |
216 return scm_variable_ref (var); | 192 return scm_variable_ref (var); |
217 } | 193 } |
218 | 194 |
219 return SCM_UNDEFINED; | 195 return SCM_UNDEFINED; |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 scm_display (scopes_, port); | 362 scm_display (scopes_, port); |
387 scm_puts (" >", port); | 363 scm_puts (" >", port); |
388 return 1; | 364 return 1; |
389 } | 365 } |
390 | 366 |
391 bool | 367 bool |
392 Lily_lexer::is_clean () const | 368 Lily_lexer::is_clean () const |
393 { | 369 { |
394 return include_stack_.empty (); | 370 return include_stack_.empty (); |
395 } | 371 } |
OLD | NEW |