Skip to content

Commit f711f5b

Browse files
committed
Add example grammars for XML and source-mapping:mapping
1 parent 05fcaff commit f711f5b

File tree

2 files changed

+554
-0
lines changed

2 files changed

+554
-0
lines changed

examples/source-mappings.peggy

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// See https://sourcemaps.info/spec.html
2+
// This grammar only parses the "mapping" field.
3+
{{
4+
const BASE64u = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
5+
// ub64.A = 0, etc.
6+
const ub64 = [...BASE64u].reduce((p, v, i) => {
7+
p[v] = i
8+
return p
9+
}, {})
10+
}}
11+
12+
// each group representing a line in the generated file is separated by a ”;”
13+
mappings = head:line? tail:(";" @line)* { return head ? [head, ...tail] : tail; }
14+
15+
// each segment is separated by a “,”
16+
line = head:segment? tail:("," @segment)* { return head ? [head, ...tail] : tail; }
17+
18+
/*
19+
gen_col: The zero-based starting column of the line in the generated code
20+
that the segment represents. If this is the first field of the first
21+
segment, or the first segment following a new generated line (“;”), then
22+
this field holds the whole base 64 VLQ. Otherwise, this field contains a
23+
base 64 VLQ that is relative to the previous occurrence of this field. Note
24+
that this is different than the fields below because the previous value is
25+
reset after every generated line.
26+
27+
source: If present, an zero-based index into the “sources” list. This field
28+
is a base 64 VLQ relative to the previous occurrence of this field, unless
29+
this is the first occurrence of this field, in which case the whole value is
30+
represented.
31+
32+
source_line: If present, the zero-based starting line in the original source
33+
represented. This field is a base 64 VLQ relative to the previous occurrence
34+
of this field, unless this is the first occurrence of this field, in which
35+
case the whole value is represented. Always present if there is a source
36+
field.
37+
38+
source_col: If present, the zero-based starting column of the line in the
39+
source represented. This field is a base 64 VLQ relative to the previous
40+
occurrence of this field, unless this is the first occurrence of this field,
41+
in which case the whole value is represented. Always present if there is a
42+
source field.
43+
44+
name: If present, the zero-based index into the “names” list associated with
45+
this segment. This field is a base 64 VLQ relative to the previous
46+
occurrence of this field, unless this is the first occurrence of this field,
47+
in which case the whole value is represented.
48+
*/
49+
50+
// each segment is made up of 1,4 or 5 variable length fields
51+
segment = gen_col:field sf:source_fields? {
52+
const s = sf || {}
53+
s.gen_col = gen_col
54+
return s
55+
}
56+
57+
source_fields = source:field source_line:field source_col:field name:field? {
58+
const ret = { gen_col:0, source, source_line, source_col }
59+
if (name) {
60+
ret.name = name
61+
}
62+
return ret
63+
}
64+
65+
field = run:vlq_continue* end:vlq_end {
66+
// Lowest bit of end is the sign
67+
const sign = (end & 0x1) ? -1 : 1
68+
// Last 4 bits come from the top 4 bits of the end byte
69+
const last4 = (end & 0x1e) >> 1
70+
// Each continue byte has 5 bits.
71+
return sign * ((run.reduce((p, v) => (p << 5) + v, 0) << 4) + last4)
72+
}
73+
74+
// The top bit (bit 5) set means "continue". ub64.g = 32, which is the first of those.
75+
vlq_continue = c:[ghijklmnopqrstuvwxyz0123456789+/] { return ub64[c]; }
76+
vlq_end = c:[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef] { return ub64[c]; }

0 commit comments

Comments
 (0)