bibtex-ruby 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bibtex-ruby might be problematic. Click here for more details.

@@ -0,0 +1,37 @@
1
+ module BibTeX
2
+
3
+ #
4
+ # Represents a lexical or syntactical error.
5
+ #
6
+ class Error < Element
7
+
8
+ attr_reader :trace
9
+
10
+ def initialize(trace=[])
11
+ @trace = trace
12
+ end
13
+
14
+ def trace=(trace)
15
+ raise(ArgumentError, "BibTeX::Error trace must be of type Array; was: #{trace.class.name}.") unless trace.kind_of?(Array)
16
+ @trace = trace
17
+ end
18
+
19
+ def content
20
+ @trace.map { |e| e[1] }.join
21
+ end
22
+
23
+ # Called when the element was added to a bibliography.
24
+ def added_to_bibliography(bibliography)
25
+ super(bibliography)
26
+ bibliography.errors << self
27
+ self
28
+ end
29
+
30
+ # Called when the element was removed from a bibliography.
31
+ def removed_from_bibliography(bibliography)
32
+ super(bibliography)
33
+ bibliography.errors.delete(self)
34
+ self
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,328 @@
1
+ #--
2
+ # BibTeX-Ruby
3
+ # Copyright (C) 2010 Sylvester Keil <http://sylvester.keil.or.at>
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ #++
18
+
19
+ require 'strscan'
20
+
21
+
22
+ module BibTeX
23
+
24
+ #
25
+ # The BibTeX::Lexer handles the lexical analysis of BibTeX bibliographies.
26
+ #
27
+ class Lexer
28
+
29
+ attr_reader :src, :options, :stack
30
+
31
+ #
32
+ # Creates a new instance. Possible options and their respective
33
+ # default values are:
34
+ #
35
+ # - :include => [:errors] A list that may contain :meta_comments, and
36
+ # :errors; depending on whether or not these are present, the respective
37
+ # tokens are included in the parse tree.
38
+ # - :strict => true In strict mode objects can start anywhere; therefore
39
+ # the `@' symbol is not possible except inside literals or @comment
40
+ # objects; for a more lenient lexer set to false and objects are
41
+ # expected to start after a new line (leading white space is permitted).
42
+ #
43
+ def initialize(options={})
44
+ @options = options
45
+ @options[:include] ||= [:errors]
46
+ @options[:strict] = true unless @options.has_key?(:strict)
47
+ @src = nil
48
+ end
49
+
50
+ # Sets the source for the lexical analysis and resets the internal state.
51
+ def src=(src)
52
+ @stack = []
53
+ @brace_level = 0
54
+ @mode = :meta
55
+ @active_object = nil
56
+ @src = StringScanner.new(src)
57
+ @line_breaks = []
58
+ @line_breaks << @src.pos until @src.scan_until(/\n|$/).empty?
59
+ @src.reset
60
+ end
61
+
62
+ # Returns the line number at a given position in the source.
63
+ def line_number_at(index)
64
+ (@line_breaks.find_index { |n| n >= index } || 0) + 1
65
+ end
66
+
67
+ # Returns the next token from the parse stack.
68
+ def next_token
69
+ @stack.shift
70
+ end
71
+
72
+ def mode=(mode)
73
+ Log.debug("Lexer: switching to #{mode} mode...")
74
+
75
+ @active_object = case
76
+ when [:comment,:string,:preamble,:entry].include?(mode) then mode
77
+ when mode == :meta then nil
78
+ else @active_object
79
+ end
80
+
81
+ @mode = mode
82
+ end
83
+
84
+ def mode
85
+ @mode
86
+ end
87
+
88
+ # Returns true if the lexer is currenty parsing a BibTeX object.
89
+ def bibtex_mode?
90
+ [:bibtex,:comment,:string,:preamble,:entry].include?(self.mode)
91
+ end
92
+
93
+ # Returns true if the lexer is currently parsing meta comments.
94
+ def meta_mode?
95
+ self.mode == :meta
96
+ end
97
+
98
+ # Returns true if the lexer is currently parsing a braced-out expression.
99
+ def content_mode?
100
+ self.mode == :content
101
+ end
102
+
103
+ # Returns true if the lexer is currently parsing a string literal.
104
+ def literal_mode?
105
+ self.mode == :literal
106
+ end
107
+
108
+ # Returns true if the lexer is currently parsing the given object type.
109
+ def is_active?(object)
110
+ @active_object == object
111
+ end
112
+
113
+ # Pushes a value onto the parse stack.
114
+ def push(value)
115
+ case
116
+ when ([:CONTENT,:STRING_LITERAL].include?(value[0]) && value[0] == @stack.last[0])
117
+ @stack.last[1][0] << value[1]
118
+ @stack.last[1][1] = line_number_at(@src.pos)
119
+ when value[0] == :ERROR
120
+ @stack.push(value) if @options[:include].include?(:errors)
121
+ leave_object
122
+ when value[0] == :META_COMMENT
123
+ if @options[:include].include?(:meta_comments)
124
+ value[1] = [value[1], line_number_at(@src.pos)]
125
+ @stack.push(value)
126
+ end
127
+ else
128
+ value[1] = [value[1], line_number_at(@src.pos)]
129
+ @stack.push(value)
130
+ end
131
+ return self
132
+ end
133
+
134
+ # Start the lexical analysis.
135
+ def analyse(src=nil)
136
+ raise(ArgumentError, 'Lexer: failed to start analysis: no source given!') if src.nil? && @src.nil?
137
+ Log.debug('Lexer: starting lexical analysis...')
138
+
139
+ self.src = src || @src.string
140
+ self.src.reset
141
+
142
+ until self.src.eos?
143
+ case
144
+ when self.bibtex_mode?
145
+ parse_bibtex
146
+ when self.meta_mode?
147
+ parse_meta
148
+ when self.content_mode?
149
+ parse_content
150
+ when self.literal_mode?
151
+ parse_literal
152
+ end
153
+ end
154
+
155
+ Log.debug('Lexer: finished lexical analysis.')
156
+ push [false, '$end']
157
+ end
158
+
159
+ def parse_bibtex
160
+ case
161
+ when self.src.scan(/[\t\r\n\s]+/o)
162
+ when self.src.scan(/\{/o)
163
+ @brace_level += 1
164
+ push [:LBRACE,'{']
165
+ if (@brace_level == 1 && is_active?(:comment)) || (@brace_level == 2 && is_active?(:entry))
166
+ self.mode = :content
167
+ end
168
+ when self.src.scan(/\}/o)
169
+ return error_unbalanced_braces if @brace_level < 1
170
+ @brace_level -= 1
171
+ push [:RBRACE,'}']
172
+ leave_object if @brace_level == 0
173
+ when self.src.scan( /=/o)
174
+ push [:EQ,'=']
175
+ when self.src.scan(/,/o)
176
+ push [:COMMA,',']
177
+ when self.src.scan(/#/o)
178
+ push [:SHARP,'#']
179
+ when self.src.scan(/\d+/o)
180
+ push [:NUMBER,self.src.matched]
181
+ when self.src.scan(/[a-z\d:_!$\.%&*-]+/io)
182
+ push [:NAME,self.src.matched]
183
+ when self.src.scan(/"/o)
184
+ self.mode = :literal
185
+ when self.src.scan(/@/o)
186
+ error_unexpected_token
187
+ enter_object
188
+ when self.src.scan(/./o)
189
+ error_unexpected_token
190
+ enter_object
191
+ end
192
+ end
193
+
194
+ def parse_meta
195
+ match = self.src.scan_until(@options[:strict] ? /@[\t ]*/o : /(^|\n)[\t ]*@[\t ]*/o)
196
+ unless self.src.matched.nil?
197
+ push [:META_COMMENT, match.chop]
198
+ enter_object
199
+ else
200
+ push [:META_COMMENT,self.src.rest]
201
+ self.src.terminate
202
+ end
203
+ end
204
+
205
+ def parse_content
206
+ match = self.src.scan_until(/\{|\}/o)
207
+ case self.src.matched
208
+ when '{'
209
+ @brace_level += 1
210
+ push [:CONTENT,match]
211
+ when '}'
212
+ @brace_level -= 1
213
+ case
214
+ when @brace_level < 0
215
+ push [:CONTENT,match.chop]
216
+ error_unbalanced_braces
217
+ when @brace_level == 0
218
+ push [:CONTENT,match.chop]
219
+ push [:RBRACE,'}']
220
+ leave_object
221
+ when @brace_level == 1 && is_active?(:entry)
222
+ push [:CONTENT,match.chop]
223
+ push [:RBRACE,'}']
224
+ self.mode = :bibtex
225
+ else
226
+ push [:CONTENT, match]
227
+ end
228
+ else
229
+ push [:CONTENT,self.src.rest]
230
+ self.src.terminate
231
+ error_unterminated_content
232
+ end
233
+ end
234
+
235
+ def parse_literal
236
+ match = self.src.scan_until(/[\{\}"\n]/o)
237
+ case self.src.matched
238
+ when '{'
239
+ @brace_level += 1
240
+ push [:STRING_LITERAL,match]
241
+ when '}'
242
+ @brace_level -= 1
243
+ if @brace_level < 1
244
+ push [:STRING_LITERAL,match.chop]
245
+ error_unbalanced_braces
246
+ else
247
+ push [:STRING_LITERAL,match]
248
+ end
249
+ when '"'
250
+ if @brace_level == 1
251
+ push [:STRING_LITERAL,match.chop]
252
+ self.mode = :bibtex
253
+ else
254
+ push [:STRING_LITERAL,match]
255
+ end
256
+ when "\n"
257
+ push [:STRING_LITERAL,match.chop]
258
+ error_unterminated_string
259
+ else
260
+ push [:STRING_LITERAL,self.src.rest]
261
+ self.src.terminate
262
+ error_unterminated_string
263
+ end
264
+ end
265
+
266
+ # Called when the lexer encounters a new BibTeX object.
267
+ def enter_object
268
+ @brace_level = 0
269
+ self.mode = :bibtex
270
+ push [:AT,'@']
271
+
272
+ case
273
+ when self.src.scan(/string/io)
274
+ self.mode = :string
275
+ push [:STRING, self.src.matched]
276
+ when self.src.scan(/preamble/io)
277
+ self.mode = :preamble
278
+ push [:PREAMBLE, self.src.matched]
279
+ when self.src.scan(/comment/io)
280
+ self.mode = :comment
281
+ push [:COMMENT, self.src.matched]
282
+ when self.src.scan(/[a-z\d:_!\.$%&*-]+/io)
283
+ self.mode = :entry
284
+ push [:NAME, self.src.matched]
285
+ end
286
+ end
287
+
288
+ # Called when parser leaves a BibTeX object.
289
+ def leave_object
290
+ self.mode = :meta
291
+ @brace_level = 0
292
+ end
293
+
294
+
295
+ def error_unbalanced_braces
296
+ n = line_number_at(self.src.pos)
297
+ Log.warn("Lexer: unbalanced braces on line #{n}; brace level #{@brace_level}; mode #{@mode.inspect}.")
298
+ backtrace [:E_UNBALANCED_BRACES, [self.src.matched,n]]
299
+ end
300
+
301
+ def error_unterminated_string
302
+ n = line_number_at(self.src.pos)
303
+ Log.warn("Lexer: unterminated string on line #{n}; brace level #{@brace_level}; mode #{@mode.inspect}.")
304
+ backtrace [:E_UNTERMINATED_STRING, [self.src.matched,n]]
305
+ end
306
+
307
+ def error_unterminated_content
308
+ n = line_number_at(self.src.pos)
309
+ Log.warn("Lexer: unterminated content on line #{n}; brace level #{@brace_level}; mode #{@mode.inspect}.")
310
+ backtrace [:E_UNTERMINATED_CONTENT, [self.src.matched,n]]
311
+ end
312
+
313
+ def error_unexpected_token
314
+ n = line_number_at(self.src.pos)
315
+ Log.warn("Lexer: unexpected token `#{self.src.matched}' on line #{n}; brace level #{@brace_level}; mode #{@mode.inspect}.")
316
+ backtrace [:E_UNEXPECTED_TOKEN, [self.src.matched,n]]
317
+ end
318
+
319
+ def backtrace(error)
320
+ trace = []
321
+ trace.unshift(@stack.pop) until @stack.empty? || (!trace.empty? && [:AT,:META_COMMENT].include?(trace[0][0]))
322
+ trace << error
323
+ push [:ERROR,trace]
324
+ end
325
+
326
+ end
327
+
328
+ end
@@ -0,0 +1,578 @@
1
+
2
+
3
+ -------- Grammar --------
4
+
5
+ rule 1 bibliography:
6
+ rule 2 bibliography: objects
7
+ rule 3 objects: object
8
+ rule 4 objects: objects object
9
+ rule 5 object: AT at_object
10
+ rule 6 object: META_COMMENT
11
+ rule 7 object: ERROR
12
+ rule 8 at_object: comment
13
+ rule 9 at_object: string
14
+ rule 10 at_object: preamble
15
+ rule 11 at_object: entry
16
+ rule 12 comment: COMMENT LBRACE content RBRACE
17
+ rule 13 content:
18
+ rule 14 content: CONTENT
19
+ rule 15 preamble: PREAMBLE LBRACE string_value RBRACE
20
+ rule 16 string: STRING LBRACE string_assignment RBRACE
21
+ rule 17 string_assignment: NAME EQ string_value
22
+ rule 18 string_value: string_literal
23
+ rule 19 string_value: string_value SHARP string_literal
24
+ rule 20 string_literal: NAME
25
+ rule 21 string_literal: STRING_LITERAL
26
+ rule 22 entry: entry_head assignments RBRACE
27
+ rule 23 entry: entry_head assignments COMMA RBRACE
28
+ rule 24 entry: entry_head RBRACE
29
+ rule 25 entry_head: NAME LBRACE key COMMA
30
+ rule 26 key: NAME
31
+ rule 27 key: NUMBER
32
+ rule 28 assignments: assignment
33
+ rule 29 assignments: assignments COMMA assignment
34
+ rule 30 assignment: NAME EQ value
35
+ rule 31 value: string_value
36
+ rule 32 value: NUMBER
37
+ rule 33 value: LBRACE content RBRACE
38
+
39
+ ------- Symbols -------
40
+
41
+ **Nonterminals, with rules where they appear
42
+
43
+ $start (17)
44
+ on right:
45
+ on left :
46
+ bibliography (18)
47
+ on right:
48
+ on left : 1 2
49
+ objects (19)
50
+ on right: 2 4
51
+ on left : 3 4
52
+ object (20)
53
+ on right: 3 4
54
+ on left : 5 6 7
55
+ at_object (21)
56
+ on right: 5
57
+ on left : 8 9 10 11
58
+ comment (22)
59
+ on right: 8
60
+ on left : 12
61
+ string (23)
62
+ on right: 9
63
+ on left : 16
64
+ preamble (24)
65
+ on right: 10
66
+ on left : 15
67
+ entry (25)
68
+ on right: 11
69
+ on left : 22 23 24
70
+ content (26)
71
+ on right: 12 33
72
+ on left : 13 14
73
+ string_value (27)
74
+ on right: 15 17 19 31
75
+ on left : 18 19
76
+ string_assignment (28)
77
+ on right: 16
78
+ on left : 17
79
+ string_literal (29)
80
+ on right: 18 19
81
+ on left : 20 21
82
+ entry_head (30)
83
+ on right: 22 23 24
84
+ on left : 25
85
+ assignments (31)
86
+ on right: 22 23 29
87
+ on left : 28 29
88
+ key (32)
89
+ on right: 25
90
+ on left : 26 27
91
+ assignment (33)
92
+ on right: 28 29
93
+ on left : 30
94
+ value (34)
95
+ on right: 30
96
+ on left : 31 32 33
97
+
98
+ **Terminals, with rules where they appear
99
+
100
+ $end (0)
101
+ error (1)
102
+ AT (2) 5
103
+ COMMA (3) 23 25 29
104
+ COMMENT (4) 12
105
+ CONTENT (5) 14
106
+ ERROR (6) 7
107
+ EQ (7) 17 30
108
+ LBRACE (8) 12 15 16 25 33
109
+ META_COMMENT (9) 6
110
+ NAME (10) 17 20 25 26 30
111
+ NUMBER (11) 27 32
112
+ PREAMBLE (12) 15
113
+ RBRACE (13) 12 15 16 22 23 24 33
114
+ SHARP (14) 19
115
+ STRING (15) 16
116
+ STRING_LITERAL (16) 21
117
+
118
+ --------- State ---------
119
+
120
+ state 0
121
+
122
+
123
+ AT shift, and go to state 4
124
+ ERROR shift, and go to state 6
125
+ META_COMMENT shift, and go to state 5
126
+ $default reduce using rule 1 (bibliography)
127
+
128
+ bibliography go to state 1
129
+ objects go to state 2
130
+ object go to state 3
131
+
132
+ state 1
133
+
134
+
135
+ $end shift, and go to state 7
136
+
137
+
138
+ state 2
139
+
140
+ 2) bibliography : objects _
141
+ 4) objects : objects _ object
142
+
143
+ AT shift, and go to state 4
144
+ ERROR shift, and go to state 6
145
+ META_COMMENT shift, and go to state 5
146
+ $default reduce using rule 2 (bibliography)
147
+
148
+ object go to state 8
149
+
150
+ state 3
151
+
152
+ 3) objects : object _
153
+
154
+ $default reduce using rule 3 (objects)
155
+
156
+
157
+ state 4
158
+
159
+ 5) object : AT _ at_object
160
+
161
+ COMMENT shift, and go to state 14
162
+ NAME shift, and go to state 18
163
+ PREAMBLE shift, and go to state 15
164
+ STRING shift, and go to state 16
165
+
166
+ at_object go to state 9
167
+ comment go to state 10
168
+ string go to state 11
169
+ preamble go to state 12
170
+ entry go to state 13
171
+ entry_head go to state 17
172
+
173
+ state 5
174
+
175
+ 6) object : META_COMMENT _
176
+
177
+ $default reduce using rule 6 (object)
178
+
179
+
180
+ state 6
181
+
182
+ 7) object : ERROR _
183
+
184
+ $default reduce using rule 7 (object)
185
+
186
+
187
+ state 7
188
+
189
+
190
+ $end shift, and go to state 19
191
+
192
+
193
+ state 8
194
+
195
+ 4) objects : objects object _
196
+
197
+ $default reduce using rule 4 (objects)
198
+
199
+
200
+ state 9
201
+
202
+ 5) object : AT at_object _
203
+
204
+ $default reduce using rule 5 (object)
205
+
206
+
207
+ state 10
208
+
209
+ 8) at_object : comment _
210
+
211
+ $default reduce using rule 8 (at_object)
212
+
213
+
214
+ state 11
215
+
216
+ 9) at_object : string _
217
+
218
+ $default reduce using rule 9 (at_object)
219
+
220
+
221
+ state 12
222
+
223
+ 10) at_object : preamble _
224
+
225
+ $default reduce using rule 10 (at_object)
226
+
227
+
228
+ state 13
229
+
230
+ 11) at_object : entry _
231
+
232
+ $default reduce using rule 11 (at_object)
233
+
234
+
235
+ state 14
236
+
237
+ 12) comment : COMMENT _ LBRACE content RBRACE
238
+
239
+ LBRACE shift, and go to state 20
240
+
241
+
242
+ state 15
243
+
244
+ 15) preamble : PREAMBLE _ LBRACE string_value RBRACE
245
+
246
+ LBRACE shift, and go to state 21
247
+
248
+
249
+ state 16
250
+
251
+ 16) string : STRING _ LBRACE string_assignment RBRACE
252
+
253
+ LBRACE shift, and go to state 22
254
+
255
+
256
+ state 17
257
+
258
+ 22) entry : entry_head _ assignments RBRACE
259
+ 23) entry : entry_head _ assignments COMMA RBRACE
260
+ 24) entry : entry_head _ RBRACE
261
+
262
+ NAME shift, and go to state 26
263
+ RBRACE shift, and go to state 24
264
+
265
+ assignments go to state 23
266
+ assignment go to state 25
267
+
268
+ state 18
269
+
270
+ 25) entry_head : NAME _ LBRACE key COMMA
271
+
272
+ LBRACE shift, and go to state 27
273
+
274
+
275
+ state 19
276
+
277
+
278
+ $default accept
279
+
280
+
281
+ state 20
282
+
283
+ 12) comment : COMMENT LBRACE _ content RBRACE
284
+
285
+ CONTENT shift, and go to state 29
286
+ $default reduce using rule 13 (content)
287
+
288
+ content go to state 28
289
+
290
+ state 21
291
+
292
+ 15) preamble : PREAMBLE LBRACE _ string_value RBRACE
293
+
294
+ NAME shift, and go to state 32
295
+ STRING_LITERAL shift, and go to state 33
296
+
297
+ string_value go to state 30
298
+ string_literal go to state 31
299
+
300
+ state 22
301
+
302
+ 16) string : STRING LBRACE _ string_assignment RBRACE
303
+
304
+ NAME shift, and go to state 35
305
+
306
+ string_assignment go to state 34
307
+
308
+ state 23
309
+
310
+ 22) entry : entry_head assignments _ RBRACE
311
+ 23) entry : entry_head assignments _ COMMA RBRACE
312
+ 29) assignments : assignments _ COMMA assignment
313
+
314
+ COMMA shift, and go to state 37
315
+ RBRACE shift, and go to state 36
316
+
317
+
318
+ state 24
319
+
320
+ 24) entry : entry_head RBRACE _
321
+
322
+ $default reduce using rule 24 (entry)
323
+
324
+
325
+ state 25
326
+
327
+ 28) assignments : assignment _
328
+
329
+ $default reduce using rule 28 (assignments)
330
+
331
+
332
+ state 26
333
+
334
+ 30) assignment : NAME _ EQ value
335
+
336
+ EQ shift, and go to state 38
337
+
338
+
339
+ state 27
340
+
341
+ 25) entry_head : NAME LBRACE _ key COMMA
342
+
343
+ NAME shift, and go to state 40
344
+ NUMBER shift, and go to state 41
345
+
346
+ key go to state 39
347
+
348
+ state 28
349
+
350
+ 12) comment : COMMENT LBRACE content _ RBRACE
351
+
352
+ RBRACE shift, and go to state 42
353
+
354
+
355
+ state 29
356
+
357
+ 14) content : CONTENT _
358
+
359
+ $default reduce using rule 14 (content)
360
+
361
+
362
+ state 30
363
+
364
+ 15) preamble : PREAMBLE LBRACE string_value _ RBRACE
365
+ 19) string_value : string_value _ SHARP string_literal
366
+
367
+ RBRACE shift, and go to state 43
368
+ SHARP shift, and go to state 44
369
+
370
+
371
+ state 31
372
+
373
+ 18) string_value : string_literal _
374
+
375
+ $default reduce using rule 18 (string_value)
376
+
377
+
378
+ state 32
379
+
380
+ 20) string_literal : NAME _
381
+
382
+ $default reduce using rule 20 (string_literal)
383
+
384
+
385
+ state 33
386
+
387
+ 21) string_literal : STRING_LITERAL _
388
+
389
+ $default reduce using rule 21 (string_literal)
390
+
391
+
392
+ state 34
393
+
394
+ 16) string : STRING LBRACE string_assignment _ RBRACE
395
+
396
+ RBRACE shift, and go to state 45
397
+
398
+
399
+ state 35
400
+
401
+ 17) string_assignment : NAME _ EQ string_value
402
+
403
+ EQ shift, and go to state 46
404
+
405
+
406
+ state 36
407
+
408
+ 22) entry : entry_head assignments RBRACE _
409
+
410
+ $default reduce using rule 22 (entry)
411
+
412
+
413
+ state 37
414
+
415
+ 23) entry : entry_head assignments COMMA _ RBRACE
416
+ 29) assignments : assignments COMMA _ assignment
417
+
418
+ NAME shift, and go to state 26
419
+ RBRACE shift, and go to state 47
420
+
421
+ assignment go to state 48
422
+
423
+ state 38
424
+
425
+ 30) assignment : NAME EQ _ value
426
+
427
+ LBRACE shift, and go to state 52
428
+ NAME shift, and go to state 32
429
+ NUMBER shift, and go to state 51
430
+ STRING_LITERAL shift, and go to state 33
431
+
432
+ string_literal go to state 31
433
+ string_value go to state 49
434
+ value go to state 50
435
+
436
+ state 39
437
+
438
+ 25) entry_head : NAME LBRACE key _ COMMA
439
+
440
+ COMMA shift, and go to state 53
441
+
442
+
443
+ state 40
444
+
445
+ 26) key : NAME _
446
+
447
+ $default reduce using rule 26 (key)
448
+
449
+
450
+ state 41
451
+
452
+ 27) key : NUMBER _
453
+
454
+ $default reduce using rule 27 (key)
455
+
456
+
457
+ state 42
458
+
459
+ 12) comment : COMMENT LBRACE content RBRACE _
460
+
461
+ $default reduce using rule 12 (comment)
462
+
463
+
464
+ state 43
465
+
466
+ 15) preamble : PREAMBLE LBRACE string_value RBRACE _
467
+
468
+ $default reduce using rule 15 (preamble)
469
+
470
+
471
+ state 44
472
+
473
+ 19) string_value : string_value SHARP _ string_literal
474
+
475
+ NAME shift, and go to state 32
476
+ STRING_LITERAL shift, and go to state 33
477
+
478
+ string_literal go to state 54
479
+
480
+ state 45
481
+
482
+ 16) string : STRING LBRACE string_assignment RBRACE _
483
+
484
+ $default reduce using rule 16 (string)
485
+
486
+
487
+ state 46
488
+
489
+ 17) string_assignment : NAME EQ _ string_value
490
+
491
+ NAME shift, and go to state 32
492
+ STRING_LITERAL shift, and go to state 33
493
+
494
+ string_value go to state 55
495
+ string_literal go to state 31
496
+
497
+ state 47
498
+
499
+ 23) entry : entry_head assignments COMMA RBRACE _
500
+
501
+ $default reduce using rule 23 (entry)
502
+
503
+
504
+ state 48
505
+
506
+ 29) assignments : assignments COMMA assignment _
507
+
508
+ $default reduce using rule 29 (assignments)
509
+
510
+
511
+ state 49
512
+
513
+ 19) string_value : string_value _ SHARP string_literal
514
+ 31) value : string_value _
515
+
516
+ SHARP shift, and go to state 44
517
+ $default reduce using rule 31 (value)
518
+
519
+
520
+ state 50
521
+
522
+ 30) assignment : NAME EQ value _
523
+
524
+ $default reduce using rule 30 (assignment)
525
+
526
+
527
+ state 51
528
+
529
+ 32) value : NUMBER _
530
+
531
+ $default reduce using rule 32 (value)
532
+
533
+
534
+ state 52
535
+
536
+ 33) value : LBRACE _ content RBRACE
537
+
538
+ CONTENT shift, and go to state 29
539
+ $default reduce using rule 13 (content)
540
+
541
+ content go to state 56
542
+
543
+ state 53
544
+
545
+ 25) entry_head : NAME LBRACE key COMMA _
546
+
547
+ $default reduce using rule 25 (entry_head)
548
+
549
+
550
+ state 54
551
+
552
+ 19) string_value : string_value SHARP string_literal _
553
+
554
+ $default reduce using rule 19 (string_value)
555
+
556
+
557
+ state 55
558
+
559
+ 17) string_assignment : NAME EQ string_value _
560
+ 19) string_value : string_value _ SHARP string_literal
561
+
562
+ SHARP shift, and go to state 44
563
+ $default reduce using rule 17 (string_assignment)
564
+
565
+
566
+ state 56
567
+
568
+ 33) value : LBRACE content _ RBRACE
569
+
570
+ RBRACE shift, and go to state 57
571
+
572
+
573
+ state 57
574
+
575
+ 33) value : LBRACE content RBRACE _
576
+
577
+ $default reduce using rule 33 (value)
578
+