OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library immic.grammar; | |
6 | |
7 import 'package:petitparser/petitparser.dart'; | |
8 | |
9 class ImmiGrammarDefinition extends GrammarDefinition { | |
10 Parser token(String input) { | |
11 Parser parser = input.length == 1 ? char(input) : string(input); | |
12 return parser.token().trim(ref(HIDDEN)); | |
13 } | |
14 | |
15 | |
16 // ----------------------------------------------------------------- | |
17 // Keyword definitions. | |
18 // ----------------------------------------------------------------- | |
19 LIST() => ref(token, 'List'); | |
20 | |
21 STRUCT() => ref(token, 'node'); | |
22 | |
23 UNION() => ref(token, 'union'); | |
24 | |
25 IMPORT() => ref(token, 'import'); | |
26 | |
27 // ----------------------------------------------------------------- | |
28 // Grammar productions. | |
29 // ----------------------------------------------------------------- | |
30 start() => ref(unit).end(); | |
31 | |
32 unit() => ref(import).star() & ref(struct).star(); | |
33 | |
34 import() => ref(IMPORT) | |
35 & ((ref(token, '"') | |
36 & ref(token, '"').neg().star() | |
37 & ref(token, '"')) | |
38 | | |
39 (ref(token, "'") | |
40 & ref(token, "'").neg().star() | |
41 & ref(token, "'"))) | |
42 & ref(token, ';'); | |
43 | |
44 struct() => ref(STRUCT) | |
45 & ref(identifier) | |
46 & ref(token, '{') | |
47 & (ref(slot) | ref(union) | ref(method)).star() | |
48 & ref(token, '}'); | |
49 | |
50 slot() => ref(formal) | |
51 & ref(token, ';'); | |
52 | |
53 union() => ref(UNION) | |
54 & ref(token, '{') | |
55 & ref(slot).star() | |
56 & ref(token, '}'); | |
57 | |
58 method() => ref(type) | |
59 & ref(identifier) | |
60 & ref(token, '(') | |
61 & ref(formals).optional(const []) | |
62 & ref(token, ')') | |
63 & ref(token, ';'); | |
64 | |
65 formals() => ref(formal) | |
66 .separatedBy(ref(token, ','), includeSeparators: false); | |
67 | |
68 formal() => ref(type) | |
69 & ref(identifier); | |
70 | |
71 type() => ref(listType) | |
72 | ref(stringType) | |
73 | ref(nodeType) | |
74 | ref(simpleType); | |
75 | |
76 stringType() => ref(token, 'String'); | |
77 nodeType() => ref(token, 'Node'); | |
78 | |
79 simpleType() => ref(identifier) | |
80 & ref(token, '*').optional(null).map((e) => e != null); | |
81 | |
82 listType() => ref(LIST) | |
83 & ref(token, '<') | |
84 & ref(listMemberType) | |
85 & ref(token, '>'); | |
86 | |
87 listMemberType() => ref(nodeType) | |
88 | ref(simpleType); | |
89 | |
90 identifier() => ref(IDENTIFIER).trim(ref(HIDDEN)); | |
91 | |
92 | |
93 // ----------------------------------------------------------------- | |
94 // Lexical tokens. | |
95 // ----------------------------------------------------------------- | |
96 IDENTIFIER() => ref(IDENTIFIER_START) | |
97 & ref(IDENTIFIER_PART).star(); | |
98 | |
99 IDENTIFIER_START() => ref(IDENTIFIER_START_NO_DOLLAR) | |
100 | char('\$'); | |
101 | |
102 IDENTIFIER_START_NO_DOLLAR() => ref(LETTER) | |
103 | char('_'); | |
104 | |
105 IDENTIFIER_PART_NO_DOLLAR() => ref(IDENTIFIER_START_NO_DOLLAR) | |
106 | ref(DIGIT); | |
107 | |
108 IDENTIFIER_PART() => ref(IDENTIFIER_START) | |
109 | ref(DIGIT); | |
110 | |
111 LETTER() => letter(); | |
112 | |
113 DIGIT() => digit(); | |
114 | |
115 | |
116 // ----------------------------------------------------------------- | |
117 // Whitespace and comments. | |
118 // ----------------------------------------------------------------- | |
119 HIDDEN() => ref(WHITESPACE_OR_COMMENT).plus(); | |
120 | |
121 WHITESPACE_OR_COMMENT() => ref(WHITESPACE) | |
122 | ref(SINGLE_LINE_COMMENT) | |
123 | ref(MULTI_LINE_COMMENT) | |
124 ; | |
125 | |
126 WHITESPACE() => whitespace(); | |
127 NEWLINE() => pattern('\n\r'); | |
128 | |
129 SINGLE_LINE_COMMENT() => string('//') | |
130 & ref(NEWLINE).neg().star() | |
131 & ref(NEWLINE).optional() | |
132 ; | |
133 | |
134 MULTI_LINE_COMMENT() => string('/*') | |
135 & (ref(MULTI_LINE_COMMENT) | string('*/').neg()).star() & string('*/') | |
136 ; | |
137 } | |
OLD | NEW |