/
Narsese.swift
82 lines (58 loc) · 2.64 KB
/
Narsese.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import NAL
public struct Narsese {
public let parser: Parser
public let dialect: Dialect
public init(dialect: Dialect) throws {
self.dialect = dialect
try Copula.validate(dialect)
try Connector.validate(dialect)
let ebnf = Narsese.grammar(dialect)
let grammar = try Grammar(ebnf: ebnf, start: "exp")
self.parser = EarleyParser(grammar: grammar)
}
public func parse(_ s: String) throws -> ParseTree {
try parser.syntaxTree(for: s)
}
public static func grammar(_ dialect: Dialect) -> String {
"""
exp = '<', (statement | term), '>';
statement = term, space, copula, space, term;
copula = \(Copula.allCases.all(dialect));
operation = '(', '^', word, [seq, terms], ')';
compound = compound-set
| compound-prefix
| compound-infix
| compound-neg
| compound-image
;
compound-set = ('{', terms, '}') | ('[', terms, ']');
compound-prefix = '(', ((connector, seq, term, seq, terms)
|(connector-diff, seq, term, seq, term))
,')'
;
compound-infix = '(', term, seq, (connector|connector-diff), seq, term, ')';
compound-neg = '(', \(ç.neg(dialect)), (seq|space), term, ')';
compound-image = '(',
('/' | '\\\\'), seq, term, seq,
((placeholder, seq, term) | (term, seq, placeholder))
,')'
;
placeholder = 'º' | '_';
connector = \(ç.primary(dialect));
connector-diff = \(ç.diff(dialect));
terms = term, [{seq-comma, term}|{seq-space, term}];
seq = seq-comma | seq-space;
seq-comma = space, ',', space;
seq-space = space, ' ', space;
term = word | variable | exp | statement | compound | operation;
variable = indep-var | dep-var | query-var;
indep-var = '#', word;
dep-var = '#', [word, '(', [{indep-var|','|space}], ')'];
query-var = '?', [word];
word = {letter|digit|'_'};
space = [{' '}];
digit = '0' ... '9';
letter = 'A' ... 'Z' | 'a' ... 'z';
"""
}
}