Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(769)

Side by Side Diff: pkg/servicec/lib/parser.dart

Issue 2035023003: Remove service-compiler related code. (Closed) Base URL: git@github.com:dartino/sdk.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/servicec/lib/node.dart ('k') | pkg/servicec/lib/scanner.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 servicec.parser;
6
7 import 'package:compiler/src/tokens/token.dart' show
8 ErrorToken,
9 KeywordToken,
10 Token;
11
12 import 'package:compiler/src/tokens/token_constants.dart' show
13 EOF_TOKEN,
14 IDENTIFIER_TOKEN,
15 KEYWORD_TOKEN;
16
17 import 'listener.dart' show
18 Listener;
19
20 import 'scanner.dart' show
21 LF_TOKEN;
22
23 /// Parser for the Dart service IDL, reusing the dart2js tokens.
24 class Parser {
25 Listener listener;
26 Parser(this.listener);
27
28 /// Entry point for the parser. The linked list [tokens] should be produced by
29 /// the dart2js [Scanner].
30 ///
31 /// <unit> ::= <top-level-declaration>*
32 Token parseUnit(Token tokens) {
33 tokens = listener.beginCompilationUnit(tokens);
34 int count = 0;
35 while (valid(tokens)) {
36 tokens = parseTopLevel(tokens);
37 ++count;
38 }
39 tokens = listener.endCompilationUnit(tokens, count);
40 return tokens;
41 }
42
43 /// A top-level declaration is a service or a struct.
44 ///
45 /// <top-level-declaration> ::= <service> | <struct>
46 Token parseTopLevel(Token tokens) {
47 tokens = listener.beginTopLevel(tokens);
48 if (optional('service', tokens)) {
49 tokens = parseService(tokens);
50 } else if (optional('struct', tokens)) {
51 tokens = parseStruct(tokens);
52 } else {
53 tokens = listener.expectedTopLevel(tokens);
54 }
55 tokens = listener.endTopLevel(tokens);
56 return tokens;
57 }
58
59 /// A service contains the keyword, an identifier, and a body. The body is
60 /// enclosed in {} and contains zero or more function declarations.
61 ///
62 /// <service> ::= 'service' <identifier> '{' <func-decl>* '}'
63 Token parseService(Token tokens) {
64 tokens = listener.beginService(skipNewLines(tokens));
65 tokens = parseIdentifier(next(tokens));
66 tokens = expect('{', tokens);
67 int count = 0;
68 if (valid(tokens)) {
69 while (!optional('}', tokens)) {
70 tokens = parseFunction(tokens);
71 if (!valid(tokens)) break; // Don't count unsuccessful declarations
72 ++count;
73 }
74 }
75 tokens = expect('}', tokens);
76 tokens = listener.endService(tokens, count);
77 return tokens;
78 }
79
80 /// A struct contains the keyword, an identifier, and a body. The body is
81 /// enclosed in {} and contains zero or more field declarations.
82 ///
83 /// <struct> ::= 'struct' <identifier> '{' <field-decl>* '}'
84 Token parseStruct(Token tokens) {
85 tokens = listener.beginStruct(skipNewLines(tokens));
86 tokens = parseIdentifier(next(tokens));
87 tokens = expect('{', tokens);
88 int count = 0;
89 if (valid(tokens)) {
90 while (!optional('}', tokens)) {
91 tokens = parseMember(tokens);
92 if (!valid(tokens)) break; // Don't count unsuccessful declarations
93 ++count;
94 }
95 }
96 tokens = expect('}', tokens);
97 tokens = listener.endStruct(tokens, count);
98 return tokens;
99 }
100
101 Token parseIdentifier(Token tokens) {
102 Token trimmedTokens = skipNewLines(tokens);
103 if (isValidIdentifier(trimmedTokens)) {
104 tokens = listener.handleIdentifier(trimmedTokens);
105 } else {
106 tokens = listener.expectedIdentifier(tokens);
107 }
108 return tokens;
109 }
110
111 /// A function declaration contains a type, an identifier, formal parameters,
112 /// and a semicolon.
113 ///
114 /// <func-decl> ::= <type> <identifier> <formal-params> ';'
115 Token parseFunction(Token tokens) {
116 tokens = listener.beginFunction(tokens);
117 tokens = parseType(tokens);
118 tokens = parseIdentifier(tokens);
119 tokens = expect('(', tokens);
120 int count = 0;
121 if (!optional(')', tokens)) {
122 tokens = parseFormal(tokens);
123 ++count;
124 while (optional(',', tokens)) {
125 tokens = next(tokens);
126 tokens = parseFormal(tokens);
127 ++count;
128 }
129 }
130 tokens = expect(')', tokens);
131 tokens = expect(';', tokens);
132 tokens = listener.endFunction(tokens, count);
133 return tokens;
134 }
135
136 // Parse a struct member that can be either a field or a union.
137 Token parseMember(Token tokens) {
138 if (optional('union', tokens)) {
139 tokens = parseUnion(tokens);
140 } else {
141 tokens = parseField(tokens);
142 }
143 return tokens;
144 }
145
146 /// A union contains the 'union' keyword and a list of fields, enclosed in
147 /// curly braces.
148 ///
149 /// <union> ::= 'union' '{' <field>* '}'
150 Token parseUnion(Token tokens) {
151 tokens = listener.beginUnion(tokens);
152 tokens = expect('{', next(tokens));
153 int count = 0;
154 if (valid(tokens)) {
155 while (!optional('}', tokens)) {
156 tokens = parseField(tokens);
157 if (!valid(tokens)) break; // Don't count unsuccessful declarations
158 ++count;
159 }
160 }
161 tokens = expect('}', tokens);
162 tokens = listener.endUnion(tokens, count);
163 return tokens;
164 }
165
166 /// A field contains a type, an identifier, and a semicolon.
167 ///
168 /// <field-decl> ::= <type> <identifier> ';'
169 Token parseField(Token tokens) {
170 tokens = listener.beginField(tokens);
171 tokens = parseType(tokens);
172 tokens = parseIdentifier(tokens);
173 tokens = expect(';', tokens);
174 tokens = listener.endField(tokens);
175 return tokens;
176 }
177
178 Token parseType(Token tokens) {
179 tokens = listener.beginType(tokens);
180 tokens = parseIdentifier(tokens);
181 if (optional('*', tokens)) {
182 // Push a simple type on the stack.
183 tokens = listener.handleSimpleType(tokens);
184 tokens = next(tokens);
185 // Pop the simple type and push a pointer type.
186 tokens = listener.handlePointerType(tokens);
187 } else if (optional('<', tokens)) {
188 tokens = next(tokens);
189 tokens = parseType(tokens);
190 tokens = expect('>', tokens);
191 tokens = listener.handleListType(tokens);
192 } else {
193 tokens = listener.handleSimpleType(tokens);
194 }
195 tokens = listener.endType(tokens);
196 return tokens;
197 }
198
199 /// A formal contains a type and an identifier.
200 ///
201 /// <param> ::= <type> <identifier>
202 Token parseFormal(Token tokens) {
203 tokens = listener.beginFormal(tokens);
204 tokens = parseType(tokens);
205 tokens = parseIdentifier(tokens);
206 tokens = listener.endFormal(tokens);
207 return tokens;
208 }
209
210 bool isValidIdentifier(Token tokens) {
211 tokens = skipNewLines(tokens);
212 return tokens.kind == IDENTIFIER_TOKEN;
213 }
214
215 Token skipNewLines(Token tokens) {
216 while (tokens.kind == LF_TOKEN) {
217 tokens = tokens.next;
218 }
219 return tokens;
220 }
221
222 /// Returns true if the [tokens] is a SymbolToken or a KeywordToken with
223 /// stringValue [string].
224 bool optional(String string, Token tokens) {
225 tokens = skipNewLines(tokens);
226 return string == tokens.stringValue;
227 }
228
229 /// Checks that the [tokens] is a SymbolToken or a KeywordToken with
230 /// stringValue [value].
231 Token expect(String string, Token tokens) {
232 tokens = skipNewLines(tokens);
233 if (string != tokens.stringValue) {
234 tokens = listener.expected(string, tokens);
235 } else {
236 tokens = next(tokens);
237 }
238 return tokens;
239 }
240
241 bool valid(Token tokens) {
242 tokens = skipNewLines(tokens);
243 return tokens.kind != EOF_TOKEN && tokens is! ErrorToken;
244 }
245
246 Token next(Token tokens) => skipNewLines(skipNewLines(tokens).next);
247 }
OLDNEW
« no previous file with comments | « pkg/servicec/lib/node.dart ('k') | pkg/servicec/lib/scanner.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698