eyeling 1.15.4 → 1.15.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/examples/fft8-numeric.n3 +138 -0
- package/examples/fft8-symbolic.n3 +109 -0
- package/examples/output/fft8-numeric.n3 +4 -0
- package/examples/output/fft8-symbolic.n3 +3 -0
- package/eyeling.js +24 -9
- package/lib/parser.js +24 -9
- package/package.json +1 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# ===================================================
|
|
2
|
+
# Fast Fourier Transform (FFT)
|
|
3
|
+
# Input sequence: (0 1 2 3 4 5 6 7)
|
|
4
|
+
# Numeric version with explicit complex pairs (re im)
|
|
5
|
+
# 8th roots of unity are baked in as constants
|
|
6
|
+
# ===================================================
|
|
7
|
+
|
|
8
|
+
@prefix : <http://example.org/fft8#>.
|
|
9
|
+
@prefix math: <http://www.w3.org/2000/10/swap/math#>.
|
|
10
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
|
|
11
|
+
|
|
12
|
+
# -------------------------------------------
|
|
13
|
+
# 8th roots of unity: W8^k = exp(-2*pi*i*k/8)
|
|
14
|
+
# represented as (re im)
|
|
15
|
+
# -------------------------------------------
|
|
16
|
+
|
|
17
|
+
0 :w8 (1.0 0.0).
|
|
18
|
+
1 :w8 (0.7071067811865476 -0.7071067811865476).
|
|
19
|
+
2 :w8 (0.0 -1.0).
|
|
20
|
+
3 :w8 (-0.7071067811865476 -0.7071067811865476).
|
|
21
|
+
4 :w8 (-1.0 0.0).
|
|
22
|
+
5 :w8 (-0.7071067811865476 0.7071067811865476).
|
|
23
|
+
6 :w8 (0.0 1.0).
|
|
24
|
+
7 :w8 (0.7071067811865476 0.7071067811865476).
|
|
25
|
+
|
|
26
|
+
# --------------------------------------------
|
|
27
|
+
# Complex arithmetic on explicit pairs (re im)
|
|
28
|
+
# --------------------------------------------
|
|
29
|
+
|
|
30
|
+
# (a+bi) + (c+di) = (a+c) + (b+d)i
|
|
31
|
+
{
|
|
32
|
+
((?ar ?ai) (?br ?bi)) :cAdd (?cr ?ci).
|
|
33
|
+
} <= {
|
|
34
|
+
(?ar ?br) math:sum ?cr.
|
|
35
|
+
(?ai ?bi) math:sum ?ci.
|
|
36
|
+
}.
|
|
37
|
+
|
|
38
|
+
# (a+bi) * (c+di) = (ac-bd) + (ad+bc)i
|
|
39
|
+
{
|
|
40
|
+
((?ar ?ai) (?br ?bi)) :cMul (?cr ?ci).
|
|
41
|
+
} <= {
|
|
42
|
+
(?ar ?br) math:product ?ac.
|
|
43
|
+
(?ai ?bi) math:product ?bd.
|
|
44
|
+
(?ac ?bd) math:difference ?cr.
|
|
45
|
+
|
|
46
|
+
(?ar ?bi) math:product ?ad.
|
|
47
|
+
(?ai ?br) math:product ?bc.
|
|
48
|
+
(?ad ?bc) math:sum ?ci.
|
|
49
|
+
}.
|
|
50
|
+
|
|
51
|
+
# --------------------------------------------------------
|
|
52
|
+
# Numeric radix-2 FFT evaluator
|
|
53
|
+
#
|
|
54
|
+
# ((samples...) p) :fftPair (re im)
|
|
55
|
+
#
|
|
56
|
+
# This computes X[p] for the given sample list, where p is
|
|
57
|
+
# in 0..7 and the primitive 8th root table above is used.
|
|
58
|
+
# --------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
# Base case: one real sample x becomes the complex number (x 0)
|
|
61
|
+
{
|
|
62
|
+
((?x) ?p) :fftPair (?x 0.0).
|
|
63
|
+
} <= {}.
|
|
64
|
+
|
|
65
|
+
# Length 2
|
|
66
|
+
{
|
|
67
|
+
((?x0 ?x1) ?p) :fftPair ?out.
|
|
68
|
+
} <= {
|
|
69
|
+
(?p 2) math:product ?twiceP.
|
|
70
|
+
(?twiceP 8) math:remainder ?childP.
|
|
71
|
+
|
|
72
|
+
((?x0) ?childP) :fftPair ?lhs.
|
|
73
|
+
((?x1) ?childP) :fftPair ?rhs.
|
|
74
|
+
|
|
75
|
+
?p :w8 ?w.
|
|
76
|
+
(?w ?rhs) :cMul ?tw.
|
|
77
|
+
(?lhs ?tw) :cAdd ?out.
|
|
78
|
+
}.
|
|
79
|
+
|
|
80
|
+
# Length 4
|
|
81
|
+
{
|
|
82
|
+
((?x0 ?x1 ?x2 ?x3) ?p) :fftPair ?out.
|
|
83
|
+
} <= {
|
|
84
|
+
(?p 2) math:product ?twiceP.
|
|
85
|
+
(?twiceP 8) math:remainder ?childP.
|
|
86
|
+
|
|
87
|
+
((?x0 ?x2) ?childP) :fftPair ?lhs.
|
|
88
|
+
((?x1 ?x3) ?childP) :fftPair ?rhs.
|
|
89
|
+
|
|
90
|
+
?p :w8 ?w.
|
|
91
|
+
(?w ?rhs) :cMul ?tw.
|
|
92
|
+
(?lhs ?tw) :cAdd ?out.
|
|
93
|
+
}.
|
|
94
|
+
|
|
95
|
+
# Length 8
|
|
96
|
+
{
|
|
97
|
+
((?x0 ?x1 ?x2 ?x3 ?x4 ?x5 ?x6 ?x7) ?p) :fftPair ?out.
|
|
98
|
+
} <= {
|
|
99
|
+
(?p 2) math:product ?twiceP.
|
|
100
|
+
(?twiceP 8) math:remainder ?childP.
|
|
101
|
+
|
|
102
|
+
((?x0 ?x2 ?x4 ?x6) ?childP) :fftPair ?lhs.
|
|
103
|
+
((?x1 ?x3 ?x5 ?x7) ?childP) :fftPair ?rhs.
|
|
104
|
+
|
|
105
|
+
?p :w8 ?w.
|
|
106
|
+
(?w ?rhs) :cMul ?tw.
|
|
107
|
+
(?lhs ?tw) :cAdd ?out.
|
|
108
|
+
}.
|
|
109
|
+
|
|
110
|
+
# ---------------------
|
|
111
|
+
# Top-level 8-point FFT
|
|
112
|
+
# ---------------------
|
|
113
|
+
|
|
114
|
+
{
|
|
115
|
+
(?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :fft8
|
|
116
|
+
(?y0 ?y1 ?y2 ?y3 ?y4 ?y5 ?y6 ?y7).
|
|
117
|
+
} <= {
|
|
118
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) 0) :fftPair ?y0.
|
|
119
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) 1) :fftPair ?y1.
|
|
120
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) 2) :fftPair ?y2.
|
|
121
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) 3) :fftPair ?y3.
|
|
122
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) 4) :fftPair ?y4.
|
|
123
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) 5) :fftPair ?y5.
|
|
124
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) 6) :fftPair ?y6.
|
|
125
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) 7) :fftPair ?y7.
|
|
126
|
+
}.
|
|
127
|
+
|
|
128
|
+
# -----
|
|
129
|
+
# Query
|
|
130
|
+
# -----
|
|
131
|
+
|
|
132
|
+
{
|
|
133
|
+
(0 1 2 3 4 5 6 7) :fft8 ?out.
|
|
134
|
+
}
|
|
135
|
+
log:query
|
|
136
|
+
{
|
|
137
|
+
:result :fft ?out.
|
|
138
|
+
}.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# ===================================================
|
|
2
|
+
# Fast Fourier Transform (FFT)
|
|
3
|
+
# Input sequence: (0 1 2 3 4 5 6 7)
|
|
4
|
+
# Symbolic radix-2 FFT
|
|
5
|
+
# Complex roots of unity are represented symbolically
|
|
6
|
+
# ===================================================
|
|
7
|
+
|
|
8
|
+
@prefix : <http://example.org/fft8#>.
|
|
9
|
+
@prefix math: <http://www.w3.org/2000/10/swap/math#>.
|
|
10
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
|
|
11
|
+
|
|
12
|
+
# -------------------------------------------------
|
|
13
|
+
# Symbolic expression encoding
|
|
14
|
+
#
|
|
15
|
+
# sample i -> (:leaf i)
|
|
16
|
+
# omega^p -> (:twiddle :omega p)
|
|
17
|
+
# omega^p * expr -> (:mul (:twiddle :omega p) expr)
|
|
18
|
+
# a + b -> (:add a b)
|
|
19
|
+
# -------------------------------------------------
|
|
20
|
+
|
|
21
|
+
# ---------
|
|
22
|
+
# Base case
|
|
23
|
+
# ---------
|
|
24
|
+
|
|
25
|
+
# A list of length 1 is turned into a leaf node.
|
|
26
|
+
{
|
|
27
|
+
((?i) ?root ?p ?n) :fftExpr (:leaf ?i).
|
|
28
|
+
} <= {}.
|
|
29
|
+
|
|
30
|
+
# ------------------------------
|
|
31
|
+
# FFT rule for lists of length 2
|
|
32
|
+
# ------------------------------
|
|
33
|
+
|
|
34
|
+
# FFT([a,b], p) =
|
|
35
|
+
# FFT([a], 2p mod n) + omega^p * FFT([b], 2p mod n)
|
|
36
|
+
{
|
|
37
|
+
((?i0 ?i1) ?root ?p ?n) :fftExpr
|
|
38
|
+
(:add ?lhs (:mul (:twiddle ?root ?p) ?rhs)).
|
|
39
|
+
} <= {
|
|
40
|
+
(?p 2) math:product ?twiceP.
|
|
41
|
+
(?twiceP ?n) math:remainder ?childP.
|
|
42
|
+
|
|
43
|
+
((?i0) ?root ?childP ?n) :fftExpr ?lhs.
|
|
44
|
+
((?i1) ?root ?childP ?n) :fftExpr ?rhs.
|
|
45
|
+
}.
|
|
46
|
+
|
|
47
|
+
# ------------------------------
|
|
48
|
+
# FFT rule for lists of length 4
|
|
49
|
+
# ------------------------------
|
|
50
|
+
|
|
51
|
+
# Split the input into even and odd positions.
|
|
52
|
+
{
|
|
53
|
+
((?i0 ?i1 ?i2 ?i3) ?root ?p ?n) :fftExpr
|
|
54
|
+
(:add ?lhs (:mul (:twiddle ?root ?p) ?rhs)).
|
|
55
|
+
} <= {
|
|
56
|
+
(?p 2) math:product ?twiceP.
|
|
57
|
+
(?twiceP ?n) math:remainder ?childP.
|
|
58
|
+
|
|
59
|
+
((?i0 ?i2) ?root ?childP ?n) :fftExpr ?lhs.
|
|
60
|
+
((?i1 ?i3) ?root ?childP ?n) :fftExpr ?rhs.
|
|
61
|
+
}.
|
|
62
|
+
|
|
63
|
+
# ------------------------------
|
|
64
|
+
# FFT rule for lists of length 8
|
|
65
|
+
# ------------------------------
|
|
66
|
+
|
|
67
|
+
# Split the input into even and odd positions.
|
|
68
|
+
{
|
|
69
|
+
((?i0 ?i1 ?i2 ?i3 ?i4 ?i5 ?i6 ?i7) ?root ?p ?n) :fftExpr
|
|
70
|
+
(:add ?lhs (:mul (:twiddle ?root ?p) ?rhs)).
|
|
71
|
+
} <= {
|
|
72
|
+
(?p 2) math:product ?twiceP.
|
|
73
|
+
(?twiceP ?n) math:remainder ?childP.
|
|
74
|
+
|
|
75
|
+
((?i0 ?i2 ?i4 ?i6) ?root ?childP ?n) :fftExpr ?lhs.
|
|
76
|
+
((?i1 ?i3 ?i5 ?i7) ?root ?childP ?n) :fftExpr ?rhs.
|
|
77
|
+
}.
|
|
78
|
+
|
|
79
|
+
# ---------------------
|
|
80
|
+
# Top-level 8-point FFT
|
|
81
|
+
# ---------------------
|
|
82
|
+
|
|
83
|
+
# Evaluate the symbolic FFT at p = 0..7.
|
|
84
|
+
{
|
|
85
|
+
(?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :fft8
|
|
86
|
+
(?x0 ?x1 ?x2 ?x3 ?x4 ?x5 ?x6 ?x7).
|
|
87
|
+
} <= {
|
|
88
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :omega 0 8) :fftExpr ?x0.
|
|
89
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :omega 1 8) :fftExpr ?x1.
|
|
90
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :omega 2 8) :fftExpr ?x2.
|
|
91
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :omega 3 8) :fftExpr ?x3.
|
|
92
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :omega 4 8) :fftExpr ?x4.
|
|
93
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :omega 5 8) :fftExpr ?x5.
|
|
94
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :omega 6 8) :fftExpr ?x6.
|
|
95
|
+
((?a0 ?a1 ?a2 ?a3 ?a4 ?a5 ?a6 ?a7) :omega 7 8) :fftExpr ?x7.
|
|
96
|
+
}.
|
|
97
|
+
|
|
98
|
+
# -----
|
|
99
|
+
# Query
|
|
100
|
+
# -----
|
|
101
|
+
|
|
102
|
+
# Ask for the symbolic FFT of (0 1 2 3 4 5 6 7).
|
|
103
|
+
{
|
|
104
|
+
(0 1 2 3 4 5 6 7) :fft8 ?out.
|
|
105
|
+
}
|
|
106
|
+
log:query
|
|
107
|
+
{
|
|
108
|
+
:result :fft ?out.
|
|
109
|
+
}.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
@prefix : <http://example.org/fft8#> .
|
|
2
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
3
|
+
|
|
4
|
+
:result :fft (("28"^^xsd:decimal "0"^^xsd:decimal) ("-4"^^xsd:decimal "9.65685424949238"^^xsd:decimal) ("-4"^^xsd:decimal "4"^^xsd:decimal) ("-4"^^xsd:decimal "1.6568542494923806"^^xsd:decimal) ("-4"^^xsd:decimal "0"^^xsd:decimal) ("-4"^^xsd:decimal "-1.6568542494923806"^^xsd:decimal) ("-4"^^xsd:decimal "-4"^^xsd:decimal) ("-4"^^xsd:decimal "-9.65685424949238"^^xsd:decimal)) .
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
@prefix : <http://example.org/fft8#> .
|
|
2
|
+
|
|
3
|
+
:result :fft ((:add (:add (:add (:leaf 0) (:mul (:twiddle :omega 0) (:leaf 4))) (:mul (:twiddle :omega 0) (:add (:leaf 2) (:mul (:twiddle :omega 0) (:leaf 6))))) (:mul (:twiddle :omega 0) (:add (:add (:leaf 1) (:mul (:twiddle :omega 0) (:leaf 5))) (:mul (:twiddle :omega 0) (:add (:leaf 3) (:mul (:twiddle :omega 0) (:leaf 7))))))) (:add (:add (:add (:leaf 0) (:mul (:twiddle :omega 4) (:leaf 4))) (:mul (:twiddle :omega 2) (:add (:leaf 2) (:mul (:twiddle :omega 4) (:leaf 6))))) (:mul (:twiddle :omega 1) (:add (:add (:leaf 1) (:mul (:twiddle :omega 4) (:leaf 5))) (:mul (:twiddle :omega 2) (:add (:leaf 3) (:mul (:twiddle :omega 4) (:leaf 7))))))) (:add (:add (:add (:leaf 0) (:mul (:twiddle :omega 0) (:leaf 4))) (:mul (:twiddle :omega 4) (:add (:leaf 2) (:mul (:twiddle :omega 0) (:leaf 6))))) (:mul (:twiddle :omega 2) (:add (:add (:leaf 1) (:mul (:twiddle :omega 0) (:leaf 5))) (:mul (:twiddle :omega 4) (:add (:leaf 3) (:mul (:twiddle :omega 0) (:leaf 7))))))) (:add (:add (:add (:leaf 0) (:mul (:twiddle :omega 4) (:leaf 4))) (:mul (:twiddle :omega 6) (:add (:leaf 2) (:mul (:twiddle :omega 4) (:leaf 6))))) (:mul (:twiddle :omega 3) (:add (:add (:leaf 1) (:mul (:twiddle :omega 4) (:leaf 5))) (:mul (:twiddle :omega 6) (:add (:leaf 3) (:mul (:twiddle :omega 4) (:leaf 7))))))) (:add (:add (:add (:leaf 0) (:mul (:twiddle :omega 0) (:leaf 4))) (:mul (:twiddle :omega 0) (:add (:leaf 2) (:mul (:twiddle :omega 0) (:leaf 6))))) (:mul (:twiddle :omega 4) (:add (:add (:leaf 1) (:mul (:twiddle :omega 0) (:leaf 5))) (:mul (:twiddle :omega 0) (:add (:leaf 3) (:mul (:twiddle :omega 0) (:leaf 7))))))) (:add (:add (:add (:leaf 0) (:mul (:twiddle :omega 4) (:leaf 4))) (:mul (:twiddle :omega 2) (:add (:leaf 2) (:mul (:twiddle :omega 4) (:leaf 6))))) (:mul (:twiddle :omega 5) (:add (:add (:leaf 1) (:mul (:twiddle :omega 4) (:leaf 5))) (:mul (:twiddle :omega 2) (:add (:leaf 3) (:mul (:twiddle :omega 4) (:leaf 7))))))) (:add (:add (:add (:leaf 0) (:mul (:twiddle :omega 0) (:leaf 4))) (:mul (:twiddle :omega 4) (:add (:leaf 2) (:mul (:twiddle :omega 0) (:leaf 6))))) (:mul (:twiddle :omega 6) (:add (:add (:leaf 1) (:mul (:twiddle :omega 0) (:leaf 5))) (:mul (:twiddle :omega 4) (:add (:leaf 3) (:mul (:twiddle :omega 0) (:leaf 7))))))) (:add (:add (:add (:leaf 0) (:mul (:twiddle :omega 4) (:leaf 4))) (:mul (:twiddle :omega 6) (:add (:leaf 2) (:mul (:twiddle :omega 4) (:leaf 6))))) (:mul (:twiddle :omega 7) (:add (:add (:leaf 1) (:mul (:twiddle :omega 4) (:leaf 5))) (:mul (:twiddle :omega 6) (:add (:leaf 3) (:mul (:twiddle :omega 4) (:leaf 7)))))))) .
|
package/eyeling.js
CHANGED
|
@@ -8606,6 +8606,10 @@ function assertValidQNamePrefix(prefixName, fail, tok, context = 'prefixed name'
|
|
|
8606
8606
|
}
|
|
8607
8607
|
}
|
|
8608
8608
|
|
|
8609
|
+
function failInvalidKeywordLikeIdent(fail, tok, name) {
|
|
8610
|
+
fail(`invalid_keyword(${name})`, tok);
|
|
8611
|
+
}
|
|
8612
|
+
|
|
8609
8613
|
class Parser {
|
|
8610
8614
|
constructor(tokens) {
|
|
8611
8615
|
this.toks = tokens;
|
|
@@ -8795,7 +8799,10 @@ class Parser {
|
|
|
8795
8799
|
if (tok2.typ === 'IriRef') {
|
|
8796
8800
|
iri = resolveIriRef(tok2.value || '', this.prefixes.baseIri || '');
|
|
8797
8801
|
} else if (tok2.typ === 'Ident') {
|
|
8798
|
-
|
|
8802
|
+
const qn = tok2.value || '';
|
|
8803
|
+
if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok2, qn);
|
|
8804
|
+
assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok2, '@prefix directive IRI');
|
|
8805
|
+
iri = this.prefixes.expandQName(qn);
|
|
8799
8806
|
} else {
|
|
8800
8807
|
this.fail(`Expected IRI after @prefix, got ${tok2.toString()}`, tok2);
|
|
8801
8808
|
}
|
|
@@ -8809,7 +8816,10 @@ class Parser {
|
|
|
8809
8816
|
if (tok.typ === 'IriRef') {
|
|
8810
8817
|
iri = resolveIriRef(tok.value || '', this.prefixes.baseIri || '');
|
|
8811
8818
|
} else if (tok.typ === 'Ident') {
|
|
8812
|
-
|
|
8819
|
+
const qn = tok.value || '';
|
|
8820
|
+
if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok, qn);
|
|
8821
|
+
assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok, '@base directive IRI');
|
|
8822
|
+
iri = this.prefixes.expandQName(qn);
|
|
8813
8823
|
} else {
|
|
8814
8824
|
this.fail(`Expected IRI after @base, got ${tok.toString()}`, tok);
|
|
8815
8825
|
}
|
|
@@ -8835,7 +8845,10 @@ class Parser {
|
|
|
8835
8845
|
if (tok2.typ === 'IriRef') {
|
|
8836
8846
|
iri = resolveIriRef(tok2.value || '', this.prefixes.baseIri || '');
|
|
8837
8847
|
} else if (tok2.typ === 'Ident') {
|
|
8838
|
-
|
|
8848
|
+
const qn = tok2.value || '';
|
|
8849
|
+
if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok2, qn);
|
|
8850
|
+
assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok2, '@prefix directive IRI');
|
|
8851
|
+
iri = this.prefixes.expandQName(qn);
|
|
8839
8852
|
} else {
|
|
8840
8853
|
this.fail(`Expected IRI after PREFIX, got ${tok2.toString()}`, tok2);
|
|
8841
8854
|
}
|
|
@@ -8853,7 +8866,10 @@ class Parser {
|
|
|
8853
8866
|
if (tok.typ === 'IriRef') {
|
|
8854
8867
|
iri = resolveIriRef(tok.value || '', this.prefixes.baseIri || '');
|
|
8855
8868
|
} else if (tok.typ === 'Ident') {
|
|
8856
|
-
|
|
8869
|
+
const qn = tok.value || '';
|
|
8870
|
+
if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok, qn);
|
|
8871
|
+
assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok, 'BASE directive IRI');
|
|
8872
|
+
iri = this.prefixes.expandQName(qn);
|
|
8857
8873
|
} else {
|
|
8858
8874
|
this.fail(`Expected IRI after BASE, got ${tok.toString()}`, tok);
|
|
8859
8875
|
}
|
|
@@ -8905,7 +8921,7 @@ class Parser {
|
|
|
8905
8921
|
assertValidQNamePrefix(name.split(':', 1)[0], this.fail.bind(this), tok);
|
|
8906
8922
|
return internIri(this.prefixes.expandQName(name));
|
|
8907
8923
|
} else {
|
|
8908
|
-
|
|
8924
|
+
failInvalidKeywordLikeIdent(this.fail.bind(this), tok, name);
|
|
8909
8925
|
}
|
|
8910
8926
|
}
|
|
8911
8927
|
|
|
@@ -8936,10 +8952,9 @@ class Parser {
|
|
|
8936
8952
|
dtIri = dtTok.value || '';
|
|
8937
8953
|
} else if (dtTok.typ === 'Ident') {
|
|
8938
8954
|
const qn = dtTok.value || '';
|
|
8939
|
-
if (qn.includes(':'))
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
} else dtIri = qn;
|
|
8955
|
+
if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), dtTok, qn);
|
|
8956
|
+
assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), dtTok, 'datatype prefixed name');
|
|
8957
|
+
dtIri = this.prefixes.expandQName(qn);
|
|
8943
8958
|
} else {
|
|
8944
8959
|
this.fail(`Expected datatype after ^^, got ${dtTok.toString()}`, dtTok);
|
|
8945
8960
|
}
|
package/lib/parser.js
CHANGED
|
@@ -37,6 +37,10 @@ function assertValidQNamePrefix(prefixName, fail, tok, context = 'prefixed name'
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
function failInvalidKeywordLikeIdent(fail, tok, name) {
|
|
41
|
+
fail(`invalid_keyword(${name})`, tok);
|
|
42
|
+
}
|
|
43
|
+
|
|
40
44
|
class Parser {
|
|
41
45
|
constructor(tokens) {
|
|
42
46
|
this.toks = tokens;
|
|
@@ -226,7 +230,10 @@ class Parser {
|
|
|
226
230
|
if (tok2.typ === 'IriRef') {
|
|
227
231
|
iri = resolveIriRef(tok2.value || '', this.prefixes.baseIri || '');
|
|
228
232
|
} else if (tok2.typ === 'Ident') {
|
|
229
|
-
|
|
233
|
+
const qn = tok2.value || '';
|
|
234
|
+
if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok2, qn);
|
|
235
|
+
assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok2, '@prefix directive IRI');
|
|
236
|
+
iri = this.prefixes.expandQName(qn);
|
|
230
237
|
} else {
|
|
231
238
|
this.fail(`Expected IRI after @prefix, got ${tok2.toString()}`, tok2);
|
|
232
239
|
}
|
|
@@ -240,7 +247,10 @@ class Parser {
|
|
|
240
247
|
if (tok.typ === 'IriRef') {
|
|
241
248
|
iri = resolveIriRef(tok.value || '', this.prefixes.baseIri || '');
|
|
242
249
|
} else if (tok.typ === 'Ident') {
|
|
243
|
-
|
|
250
|
+
const qn = tok.value || '';
|
|
251
|
+
if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok, qn);
|
|
252
|
+
assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok, '@base directive IRI');
|
|
253
|
+
iri = this.prefixes.expandQName(qn);
|
|
244
254
|
} else {
|
|
245
255
|
this.fail(`Expected IRI after @base, got ${tok.toString()}`, tok);
|
|
246
256
|
}
|
|
@@ -266,7 +276,10 @@ class Parser {
|
|
|
266
276
|
if (tok2.typ === 'IriRef') {
|
|
267
277
|
iri = resolveIriRef(tok2.value || '', this.prefixes.baseIri || '');
|
|
268
278
|
} else if (tok2.typ === 'Ident') {
|
|
269
|
-
|
|
279
|
+
const qn = tok2.value || '';
|
|
280
|
+
if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok2, qn);
|
|
281
|
+
assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok2, '@prefix directive IRI');
|
|
282
|
+
iri = this.prefixes.expandQName(qn);
|
|
270
283
|
} else {
|
|
271
284
|
this.fail(`Expected IRI after PREFIX, got ${tok2.toString()}`, tok2);
|
|
272
285
|
}
|
|
@@ -284,7 +297,10 @@ class Parser {
|
|
|
284
297
|
if (tok.typ === 'IriRef') {
|
|
285
298
|
iri = resolveIriRef(tok.value || '', this.prefixes.baseIri || '');
|
|
286
299
|
} else if (tok.typ === 'Ident') {
|
|
287
|
-
|
|
300
|
+
const qn = tok.value || '';
|
|
301
|
+
if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), tok, qn);
|
|
302
|
+
assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), tok, 'BASE directive IRI');
|
|
303
|
+
iri = this.prefixes.expandQName(qn);
|
|
288
304
|
} else {
|
|
289
305
|
this.fail(`Expected IRI after BASE, got ${tok.toString()}`, tok);
|
|
290
306
|
}
|
|
@@ -336,7 +352,7 @@ class Parser {
|
|
|
336
352
|
assertValidQNamePrefix(name.split(':', 1)[0], this.fail.bind(this), tok);
|
|
337
353
|
return internIri(this.prefixes.expandQName(name));
|
|
338
354
|
} else {
|
|
339
|
-
|
|
355
|
+
failInvalidKeywordLikeIdent(this.fail.bind(this), tok, name);
|
|
340
356
|
}
|
|
341
357
|
}
|
|
342
358
|
|
|
@@ -367,10 +383,9 @@ class Parser {
|
|
|
367
383
|
dtIri = dtTok.value || '';
|
|
368
384
|
} else if (dtTok.typ === 'Ident') {
|
|
369
385
|
const qn = dtTok.value || '';
|
|
370
|
-
if (qn.includes(':'))
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
} else dtIri = qn;
|
|
386
|
+
if (!qn.includes(':')) failInvalidKeywordLikeIdent(this.fail.bind(this), dtTok, qn);
|
|
387
|
+
assertValidQNamePrefix(qn.split(':', 1)[0], this.fail.bind(this), dtTok, 'datatype prefixed name');
|
|
388
|
+
dtIri = this.prefixes.expandQName(qn);
|
|
374
389
|
} else {
|
|
375
390
|
this.fail(`Expected datatype after ^^, got ${dtTok.toString()}`, dtTok);
|
|
376
391
|
}
|