yukigo-prolog-parser 0.1.3 → 0.2.2

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/dist/std.js CHANGED
@@ -1,133 +1,133 @@
1
- export const stdCode = `
2
- % between(+Low, +High, ?Value)
3
- % True if Low =< Value =< High (assuming integers)
4
- between(Low, High, Low) :- Low =< High.
5
- between(Low, High, Value) :-
6
- Low < High,
7
- NextLow is Low + 1,
8
- between(NextLow, High, Value).
9
-
10
- % union(+List1, +List2, -Union)
11
- % Union of two lists without duplicates (order not preserved)
12
- union([], L, L).
13
- union([H|T], L2, Union) :-
14
- ( member(H, L2)
15
- -> union(T, L2, Union)
16
- ; Union = [H|Rest],
17
- union(T, L2, Rest)
18
- ).
19
-
20
- % intersection(+List1, +List2, -Intersection)
21
- intersection([], _, []).
22
- intersection([H|T], L2, [H|Rest]) :-
23
- member(H, L2),
24
- !,
25
- intersection(T, L2, Rest).
26
- intersection([_|T], L2, Rest) :-
27
- intersection(T, L2, Rest).
28
-
29
- % max_member(-Max, +List)
30
- max_member(Max, [Max]) :- !.
31
- max_member(Max, [H|T]) :-
32
- max_member(M, T),
33
- ( H > M
34
- -> Max = H
35
- ; Max = M
36
- ).
37
-
38
- % min_member(-Min, +List)
39
- min_member(Min, [Min]) :- !.
40
- min_member(Min, [H|T]) :-
41
- min_member(M, T),
42
- ( H < M
43
- -> Min = H
44
- ; Min = M
45
- ).
46
-
47
- % sumlist(+List, -Sum)
48
- sumlist([], 0).
49
- sumlist([H|T], Sum) :-
50
- sumlist(T, RestSum),
51
- Sum is H + RestSum.
52
-
53
- % length(?List, ?Length)
54
- length([], 0).
55
- length([_|Tail], N) :-
56
- length(Tail, M),
57
- N is M + 1.
58
-
59
- % flatten(+NestedList, -FlatList)
60
- flatten([], []).
61
- flatten([H|T], Flat) :-
62
- !,
63
- flatten(H, FlatH),
64
- flatten(T, FlatT),
65
- append(FlatH, FlatT, Flat).
66
- flatten(X, [X]).
67
-
68
- % reverse(+List, -Reversed)
69
- reverse(List, Reversed) :-
70
- reverse_acc(List, [], Reversed).
71
-
72
- reverse_acc([], Acc, Acc).
73
- reverse_acc([H|T], Acc, Reversed) :-
74
- reverse_acc(T, [H|Acc], Reversed).
75
-
76
- % list_to_set(+List, -Set)
77
- % Removes duplicates, keeps first occurrence
78
- list_to_set([], []).
79
- list_to_set([H|T], [H|Rest]) :-
80
- exclude(==(H), T, T1),
81
- list_to_set(T1, Rest).
82
-
83
- ==(H, T) :-
84
- H == T.
85
-
86
- % nth0(?Index, ?List, ?Elem)
87
- % Index starts at 0
88
- nth0(0, [H|_], H).
89
- nth0(N, [_|T], Elem) :-
90
- N > 0,
91
- N1 is N - 1,
92
- nth0(N1, T, Elem).
93
-
94
- % nth1(?Index, ?List, ?Elem)
95
- % Index starts at 1
96
- nth1(1, [H|_], H).
97
- nth1(N, [_|T], Elem) :-
98
- N > 1,
99
- N1 is N - 1,
100
- nth1(N1, T, Elem).
101
-
102
- % append/3 (needed for flatten and union)
103
- append([], L, L).
104
- append([H|T], L, [H|R]) :-
105
- append(T, L, R).
106
-
107
- % member/2 (needed for many predicates)
108
- member(H, [H|_]).
109
- member(H, [_|T]) :-
110
- member(H, T).
111
-
112
- % exclude(+Pred, +List, -Filtered)
113
- % Removes elements satisfying Pred
114
- exclude(_, [], []).
115
- exclude(Pred, [H|T], Rest) :-
116
- ( call(Pred, H)
117
- -> exclude(Pred, T, Rest)
118
- ; Rest = [H|Rest2],
119
- exclude(Pred, T, Rest2)
120
- ).
121
-
122
- % Arithmetic predicates
123
- abs(X, Y) :- Y is abs(X).
124
- round(X, Y) :- Y is round(X).
125
- sqrt(X, Y) :- Y is sqrt(X).
126
-
127
-
128
- max_list([X], X).
129
- max_list([H|T], Max) :-
130
- max_list(T, MaxTail),
131
- Max is max(H, MaxTail).
1
+ export const stdCode = `
2
+ % between(+Low, +High, ?Value)
3
+ % True if Low =< Value =< High (assuming integers)
4
+ between(Low, High, Low) :- Low =< High.
5
+ between(Low, High, Value) :-
6
+ Low < High,
7
+ NextLow is Low + 1,
8
+ between(NextLow, High, Value).
9
+
10
+ % union(+List1, +List2, -Union)
11
+ % Union of two lists without duplicates (order not preserved)
12
+ union([], L, L).
13
+ union([H|T], L2, Union) :-
14
+ ( member(H, L2)
15
+ -> union(T, L2, Union)
16
+ ; Union = [H|Rest],
17
+ union(T, L2, Rest)
18
+ ).
19
+
20
+ % intersection(+List1, +List2, -Intersection)
21
+ intersection([], _, []).
22
+ intersection([H|T], L2, [H|Rest]) :-
23
+ member(H, L2),
24
+ !,
25
+ intersection(T, L2, Rest).
26
+ intersection([_|T], L2, Rest) :-
27
+ intersection(T, L2, Rest).
28
+
29
+ % max_member(-Max, +List)
30
+ max_member(Max, [Max]) :- !.
31
+ max_member(Max, [H|T]) :-
32
+ max_member(M, T),
33
+ ( H > M
34
+ -> Max = H
35
+ ; Max = M
36
+ ).
37
+
38
+ % min_member(-Min, +List)
39
+ min_member(Min, [Min]) :- !.
40
+ min_member(Min, [H|T]) :-
41
+ min_member(M, T),
42
+ ( H < M
43
+ -> Min = H
44
+ ; Min = M
45
+ ).
46
+
47
+ % sumlist(+List, -Sum)
48
+ sumlist([], 0).
49
+ sumlist([H|T], Sum) :-
50
+ sumlist(T, RestSum),
51
+ Sum is H + RestSum.
52
+
53
+ % length(?List, ?Length)
54
+ length([], 0).
55
+ length([_|Tail], N) :-
56
+ length(Tail, M),
57
+ N is M + 1.
58
+
59
+ % flatten(+NestedList, -FlatList)
60
+ flatten([], []).
61
+ flatten([H|T], Flat) :-
62
+ !,
63
+ flatten(H, FlatH),
64
+ flatten(T, FlatT),
65
+ append(FlatH, FlatT, Flat).
66
+ flatten(X, [X]).
67
+
68
+ % reverse(+List, -Reversed)
69
+ reverse(List, Reversed) :-
70
+ reverse_acc(List, [], Reversed).
71
+
72
+ reverse_acc([], Acc, Acc).
73
+ reverse_acc([H|T], Acc, Reversed) :-
74
+ reverse_acc(T, [H|Acc], Reversed).
75
+
76
+ % list_to_set(+List, -Set)
77
+ % Removes duplicates, keeps first occurrence
78
+ list_to_set([], []).
79
+ list_to_set([H|T], [H|Rest]) :-
80
+ exclude(==(H), T, T1),
81
+ list_to_set(T1, Rest).
82
+
83
+ ==(H, T) :-
84
+ H == T.
85
+
86
+ % nth0(?Index, ?List, ?Elem)
87
+ % Index starts at 0
88
+ nth0(0, [H|_], H).
89
+ nth0(N, [_|T], Elem) :-
90
+ N > 0,
91
+ N1 is N - 1,
92
+ nth0(N1, T, Elem).
93
+
94
+ % nth1(?Index, ?List, ?Elem)
95
+ % Index starts at 1
96
+ nth1(1, [H|_], H).
97
+ nth1(N, [_|T], Elem) :-
98
+ N > 1,
99
+ N1 is N - 1,
100
+ nth1(N1, T, Elem).
101
+
102
+ % append/3 (needed for flatten and union)
103
+ append([], L, L).
104
+ append([H|T], L, [H|R]) :-
105
+ append(T, L, R).
106
+
107
+ % member/2 (needed for many predicates)
108
+ member(H, [H|_]).
109
+ member(H, [_|T]) :-
110
+ member(H, T).
111
+
112
+ % exclude(+Pred, +List, -Filtered)
113
+ % Removes elements satisfying Pred
114
+ exclude(_, [], []).
115
+ exclude(Pred, [H|T], Rest) :-
116
+ ( call(Pred, H)
117
+ -> exclude(Pred, T, Rest)
118
+ ; Rest = [H|Rest2],
119
+ exclude(Pred, T, Rest2)
120
+ ).
121
+
122
+ % Arithmetic predicates
123
+ abs(X, Y) :- Y is abs(X).
124
+ round(X, Y) :- Y is round(X).
125
+ sqrt(X, Y) :- Y is sqrt(X).
126
+
127
+
128
+ max_list([X], X).
129
+ max_list([H|T], Max) :-
130
+ max_list(T, MaxTail),
131
+ Max is max(H, MaxTail).
132
132
  `;
133
133
  //# sourceMappingURL=std.js.map
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "yukigo-prolog-parser",
3
- "version": "0.1.3",
3
+ "version": "0.2.2",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
- "build": "nearleyc ./src/parser/grammar.ne -o ./src/parser/grammar.ts && tsc",
9
+ "build": "nearleyc ./src/parser/grammar.ne -o ./src/parser/grammar.cjs && tsc",
10
10
  "test": "mocha --import=tsx"
11
11
  },
12
12
  "keywords": [],
@@ -17,23 +17,16 @@
17
17
  "moo-ignore": "^2.5.3",
18
18
  "nearley": "^2.20.1"
19
19
  },
20
+ "devDependencies": {
21
+ "@types/moo": "^0.5.10"
22
+ },
20
23
  "exports": {
21
24
  ".": {
22
25
  "import": "./dist/index.js",
23
26
  "types": "./dist/index.d.ts"
24
27
  }
25
28
  },
26
- "devDependencies": {
27
- "@types/chai": "^5.2.2",
28
- "@types/mocha": "^10.0.10",
29
- "@types/moo": "^0.5.10",
30
- "@types/node": "^24.10.0",
31
- "chai": "^6.2.0",
32
- "mocha": "^11.7.1",
33
- "tsx": "^4.20.6",
34
- "typescript": "^5.9.2"
35
- },
36
29
  "peerDependencies": {
37
- "yukigo-ast": "^0.2.0"
30
+ "yukigo-ast": "^0.3.0"
38
31
  }
39
32
  }
package/src/index.ts CHANGED
@@ -1,82 +1,93 @@
1
- import { AST, Expression, Rule, YukigoParser } from "yukigo-ast";
2
- import nearley from "nearley";
3
- import grammar from "./parser/grammar.js";
4
- import { Token } from "moo";
5
- import { stdCode } from "./std.js";
6
-
7
- class UnexpectedToken extends Error {
8
- constructor(token: Token) {
9
- super(
10
- `Parser: Unexpected '${token.type}' token '${token.value}' at line ${token.line} col ${token.col}.`
11
- );
12
- }
13
- }
14
- class AmbiguityError extends Error {
15
- constructor(amountAST: number) {
16
- super(
17
- `Parser: Too much ambiguity. ${amountAST} ASTs parsed. Output not generated.`
18
- );
19
- }
20
- }
21
-
22
- export type HaskellConfig = {
23
- typecheck: boolean;
24
- };
25
-
26
- export class YukigoPrologParser implements YukigoParser {
27
- public errors: string[] = [];
28
- private std: AST;
29
- constructor(std: string = stdCode) {
30
- this.errors = [];
31
- this.std = this.feedParser(std);
32
- }
33
- public parse(code: string): AST {
34
- const result = this.feedParser(code);
35
- const ast = groupRuleDeclarations(this.std.concat(result));
36
- return ast;
37
- }
38
- public parseExpression(code: string): Expression {
39
- const expr = this.feedParser(code)[0];
40
- return expr;
41
- }
42
- private feedParser(code: string): any {
43
- const parser = new nearley.Parser(nearley.Grammar.fromCompiled(grammar));
44
- try {
45
- parser.feed(code);
46
- parser.finish();
47
- } catch (error) {
48
- if ("token" in error) throw new UnexpectedToken(error.token);
49
- throw error;
50
- }
51
- const { results } = parser;
52
- if (results.length > 1) throw new AmbiguityError(results.length);
53
- if (results.length == 0) return [];
54
- return results[0];
55
- }
56
- }
57
-
58
- export function groupRuleDeclarations(ast: AST): AST {
59
- const groups: Record<string, Rule[]> = {};
60
- const others: AST = [];
61
-
62
- for (const node of ast) {
63
- if (node instanceof Rule) {
64
- const name = node.identifier.value;
65
- if (!groups[name]) {
66
- groups[name] = [];
67
- }
68
- groups[name].push(node);
69
- } else {
70
- others.push(node);
71
- }
72
- }
73
-
74
- // Merge equations for each rule
75
- const ruleGroups: Rule[] = Object.values(groups).map((rules) => {
76
- const identifier = rules[0].identifier;
77
- const allEquations = rules.flatMap((r) => r.equations);
78
- return new Rule(identifier, allEquations, identifier.loc);
79
- });
80
-
81
- return [...others, ...ruleGroups];
82
- }
1
+ import { AST, Expression, Rule, YukigoParser } from "yukigo-ast";
2
+ import nearley from "nearley";
3
+ import grammar from "./parser/grammar.cjs";
4
+ import { Token } from "moo";
5
+ import { stdCode } from "./std.js";
6
+
7
+ interface NearleyError {
8
+ token?: any;
9
+ offset?: number;
10
+ [key: string]: any;
11
+ }
12
+
13
+ class UnexpectedToken extends Error {
14
+ constructor(token: Token) {
15
+ super(
16
+ `Parser: Unexpected '${token.type}' token '${token.value}' at line ${token.line} col ${token.col}.`
17
+ );
18
+ }
19
+ }
20
+ class AmbiguityError extends Error {
21
+ constructor(amountAST: number) {
22
+ super(
23
+ `Parser: Too much ambiguity. ${amountAST} ASTs parsed. Output not generated.`
24
+ );
25
+ }
26
+ }
27
+
28
+ export type HaskellConfig = {
29
+ typecheck: boolean;
30
+ };
31
+
32
+ export class YukigoPrologParser implements YukigoParser {
33
+ public errors: string[] = [];
34
+ private std: AST;
35
+ constructor(std: string = stdCode) {
36
+ this.errors = [];
37
+ this.std = this.feedParser(std);
38
+ }
39
+ public parse(code: string): AST {
40
+ const result = this.feedParser(code);
41
+ const ast = groupRuleDeclarations(this.std.concat(result));
42
+ return ast;
43
+ }
44
+ public parseExpression(code: string): Expression {
45
+ const expr = this.feedParser(code)[0];
46
+ return expr;
47
+ }
48
+ private feedParser(code: string): any {
49
+ const parser = new nearley.Parser(
50
+ nearley.Grammar.fromCompiled(grammar as any)
51
+ );
52
+ try {
53
+ parser.feed(code);
54
+ parser.finish();
55
+ } catch (e: unknown) {
56
+ const error = e as NearleyError; // Assert the shape
57
+ if (error.token) {
58
+ throw new UnexpectedToken(error.token);
59
+ }
60
+ throw error;
61
+ }
62
+ const { results } = parser;
63
+ if (results.length > 1) throw new AmbiguityError(results.length);
64
+ if (results.length == 0) return [];
65
+ return results[0];
66
+ }
67
+ }
68
+
69
+ export function groupRuleDeclarations(ast: AST): AST {
70
+ const groups: Record<string, Rule[]> = {};
71
+ const others: AST = [];
72
+
73
+ for (const node of ast) {
74
+ if (node instanceof Rule) {
75
+ const name = node.identifier.value;
76
+ if (!groups[name]) {
77
+ groups[name] = [];
78
+ }
79
+ groups[name].push(node);
80
+ } else {
81
+ others.push(node);
82
+ }
83
+ }
84
+
85
+ // Merge equations for each rule
86
+ const ruleGroups: Rule[] = Object.values(groups).map((rules) => {
87
+ const identifier = rules[0].identifier;
88
+ const allEquations = rules.flatMap((r) => r.equations);
89
+ return new Rule(identifier, allEquations, identifier.loc);
90
+ });
91
+
92
+ return [...others, ...ruleGroups];
93
+ }