authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-04 20:37:04+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-05 20:25:50+02:00
log73a53fa263dd514940715b98e64e96764af91d46
treef2f038fd8bfd06b24d634e567383a4d6c9d7ab17
parente1b01d32f0869bae9b770a613f3f02fbda6c6556
signature Commit is signed but in an unrecognized format.

std-c outline parser


2 files changed, 297 insertions(+), 0 deletions(-)

lib/std/c.zig+1
......@@ -5,6 +5,7 @@ const page_size = std.mem.page_size;
55const tokenizer = @import("c/tokenizer.zig");
66pub const Token = tokenizer.Token;
77pub const Tokenizer = tokenizer.Tokenizer;
8pub const parse = @import("c/parse.zig").parse;
89pub const ast = @import("c/ast.zig");
910
1011pub usingnamespace @import("os/bits.zig");
lib/std/c/parse.zig created+296
......@@ -0,0 +1,296 @@
1const std = @import("../std.zig");
2const assert = std.debug.assert;
3const Allocator = std.mem.Allocator;
4const ast = std.c.ast;
5const Tree = ast.Tree;
6const TokenIndex = ast.TokenIndex;
7const Token = std.c.Token;
8const TokenIterator = ast.Tree.TokenList.Iterator;
9
10pub const Error = error{ParseError} || Allocator.Error;
11
12/// Result should be freed with tree.deinit() when there are
13/// no more references to any of the tokens or nodes.
14pub fn parse(allocator: *Allocator, source: []const u8) !*Tree {
15 const tree = blk: {
16 // This block looks unnecessary, but is a "foot-shield" to prevent the SegmentedLists
17 // from being initialized with a pointer to this `arena`, which is created on
18 // the stack. Following code should instead refer to `&tree.arena_allocator`, a
19 // pointer to data which lives safely on the heap and will outlive `parse`.
20 var arena = std.heap.ArenaAllocator.init(allocator);
21 errdefer arena.deinit();
22 const tree = try arena.allocator.create(ast.Tree);
23 tree.* = .{
24 .root_node = undefined,
25 .arena_allocator = arena,
26 .tokens = undefined,
27 .sources = undefined,
28 };
29 break :blk tree;
30 };
31 errdefer tree.deinit();
32 const arena = &tree.arena_allocator.allocator;
33
34 tree.tokens = ast.Tree.TokenList.init(arena);
35 tree.sources = ast.Tree.SourceList.init(arena);
36
37 var tokenizer = std.zig.Tokenizer.init(source);
38 while (true) {
39 const tree_token = try tree.tokens.addOne();
40 tree_token.* = tokenizer.next();
41 if (tree_token.id == .Eof) break;
42 }
43 // TODO preprocess here
44 var it = tree.tokens.iterator(0);
45
46 while (true) {
47 const tok = it.peek().?.id;
48 switch (id) {
49 .LineComment,
50 .MultiLineComment,
51 => {
52 _ = it.next();
53 },
54 else => break,
55 }
56 }
57
58 tree.root_node = try parseRoot(arena, &it, tree);
59 return tree;
60}
61
62/// Root <- ExternalDeclaration* eof
63fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!*Node {
64 const node = try arena.create(ast.Root);
65 node.* = .{
66 .decls = ast.Node.DeclList.init(arena),
67 .eof_token = undefined,
68 };
69 while (parseExternalDeclarations(arena, it, tree) catch |err| switch (err) {
70 error.OutOfMemory => return error.OutOfMemory,
71 error.ParseError => return node,
72 }) |decl| {
73 try node.decls.push(decl);
74 }
75 node.eof_token = eatToken(it, .Eof) orelse {
76 try tree.errors.push(.{
77 .ExpectedDecl = .{ .token = it.index },
78 });
79 return node;
80 };
81 return node;
82}
83
84/// ExternalDeclaration
85/// <- Declaration
86/// / DeclarationSpecifiers Declarator Declaration* CompoundStmt
87fn parseExternalDeclarations(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
88 if (try parseDeclaration(arena, it, tree)) |decl| {}
89 return null;
90}
91
92/// Declaration
93/// <- DeclarationSpecifiers (Declarator (EQUAL Initializer)?)* SEMICOLON
94/// \ StaticAssertDeclaration
95fn parseDeclaration(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {}
96
97/// StaticAssertDeclaration <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON
98fn parseStaticAssertDeclaration(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {}
99
100/// DeclarationSpecifiers
101/// <- StorageClassSpecifier DeclarationSpecifiers?
102/// / TypeSpecifier DeclarationSpecifiers?
103/// / TypeQualifier DeclarationSpecifiers?
104/// / FunctionSpecifier DeclarationSpecifiers?
105/// / AlignmentSpecifier DeclarationSpecifiers?
106fn parseDeclarationSpecifiers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
107
108/// StorageClassSpecifier
109/// <- Keyword_typedef / Keyword_extern / Keyword_static / Keyword_thread_local / Keyword_auto / Keyword_register
110fn parseStorageClassSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
111
112/// TypeSpecifier
113/// <- Keyword_void / Keyword_char / Keyword_short / Keyword_int / Keyword_long / Keyword_float / Keyword_double
114/// / Keyword_signed / Keyword_unsigned / Keyword_bool / Keyword_complex / Keyword_imaginary /
115/// / Keyword_atomic LPAREN TypeName RPAREN
116/// / EnumSpecifier
117/// / RecordSpecifier
118/// / IDENTIFIER // typedef name
119fn parseTypeSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
120
121/// TypeQualifier <- Keyword_const / Keyword_restrict / Keyword_volatile / Keyword_atomic
122fn parseTypeQualifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
123
124/// FunctionSpecifier <- Keyword_inline / Keyword_noreturn
125fn parseFunctionSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
126
127/// AlignmentSpecifier <- Keyword_alignas LPAREN (TypeName / ConstExpr) RPAREN
128fn parseAlignmentSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
129
130/// EnumSpecifier <- Keyword_enum IDENTIFIER? (LBRACE EnumField RBRACE)?
131fn parseEnumSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
132
133/// EnumField <- IDENTIFIER (EQUAL ConstExpr)? (COMMA EnumField) COMMA?
134fn parseEnumField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
135
136/// RecordSpecifier <- (Keyword_struct / Keyword_union) IDENTIFIER? (LBRACE RecordField+ RBRACE)?
137fn parseRecordSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
138
139/// RecordField
140/// <- SpecifierQualifer (RecordDeclarator (COMMA RecordDeclarator))? SEMICOLON
141/// \ StaticAssertDeclaration
142fn parseRecordField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
143
144/// TypeName
145/// <- SpecifierQualifer AbstractDeclarator?
146fn parseTypeName(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
147
148/// SpecifierQualifer
149/// <- TypeSpecifier SpecifierQualifer?
150/// / TypeQualifier SpecifierQualifer?
151fn parseSpecifierQualifer(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
152
153/// RecordDeclarator <- Declarator? (COLON ConstExpr)?
154fn parseRecordDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
155
156/// Declarator <- Pointer? DirectDeclarator
157fn parseDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
158
159/// Pointer <- ASTERISK TypeQualifier* Pointer?
160fn parsePointer(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
161
162/// DirectDeclarator
163/// <- IDENTIFIER
164/// / LPAREN Declarator RPAREN
165/// / DirectDeclarator LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET
166/// / DirectDeclarator LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
167fn parseDirectDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
168
169/// BracketDeclarator
170/// <- Keyword_static TypeQualifier* AssignmentExpr
171/// / TypeQualifier+ (ASTERISK / Keyword_static AssignmentExpr)
172/// / TypeQualifier+ AssignmentExpr?
173/// / AssignmentExpr
174fn parseBracketDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
175
176/// ParamDecl <- DeclarationSpecifiers (Declarator / AbstractDeclarator)
177fn parseParamDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
178
179/// AbstractDeclarator <- Pointer? DirectAbstractDeclarator?
180fn parseAbstractDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
181
182/// DirectAbstractDeclarator
183/// <- IDENTIFIER
184/// / LPAREN DirectAbstractDeclarator RPAREN
185/// / DirectAbstractDeclarator? LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET
186/// / DirectAbstractDeclarator? LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
187fn parseDirectAbstractDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
188
189/// Expr <- AssignmentExpr (COMMA Expr)*
190fn parseExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
191
192/// AssignmentExpr
193/// <- ConditionalExpr
194/// / UnaryExpr (EQUAL / ASTERISKEQUAL / SLASHEQUAL / PERCENTEQUAL / PLUSEQUAL / MINUSEQUA /
195/// / ANGLEBRACKETANGLEBRACKETLEFTEQUAL / ANGLEBRACKETANGLEBRACKETRIGHTEQUAL /
196/// / AMPERSANDEQUAL / CARETEQUAL / PIPEEQUAL) AssignmentExpr
197fn parseAssignmentExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
198
199/// ConstExpr <- ConditionalExpr
200/// ConditionalExpr <- LogicalOrExpr (QUESTIONMARK Expr COLON ConditionalExpr)?
201fn parseConditionalExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
202
203/// LogicalOrExpr <- LogicalAndExpr (PIPEPIPE LogicalOrExpr)*
204fn parseLogicalOrExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
205
206/// LogicalAndExpr <- BinOrExpr (AMPERSANDAMPERSAND LogicalAndExpr)*
207fn parseLogicalAndExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
208
209/// BinOrExpr <- BinXorExpr (PIPE BinOrExpr)*
210fn parseBinOrExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
211
212/// BinXorExpr <- BinAndExpr (CARET BinXorExpr)*
213fn parseBinXorExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
214
215/// BinAndExpr <- EqualityExpr (AMPERSAND BinAndExpr)*
216fn parseBinAndExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
217
218/// EqualityExpr <- ComparisionExpr ((EQUALEQUAL / BANGEQUAL) EqualityExpr)*
219fn parseEqualityExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
220
221/// ComparisionExpr <- ShiftExpr (ANGLEBRACKETLEFT / ANGLEBRACKETLEFTEQUAL /ANGLEBRACKETRIGHT / ANGLEBRACKETRIGHTEQUAL) ComparisionExpr)*
222fn parseComparisionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
223
224/// ShiftExpr <- AdditiveExpr (ANGLEBRACKETANGLEBRACKETLEFT / ANGLEBRACKETANGLEBRACKETRIGHT) ShiftExpr)*
225fn parseShiftExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
226
227/// AdditiveExpr <- MultiplicativeExpr (PLUS / MINUS) AdditiveExpr)*
228fn parseAdditiveExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
229
230/// MultiplicativeExpr <- UnaryExpr (ASTERISK / SLASH / PERCENT) MultiplicativeExpr)*
231fn parseMultiplicativeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
232
233/// UnaryExpr
234/// <- LPAREN TypeName RPAREN UnaryExpr
235/// / Keyword_sizeof LAPERN TypeName RPAREN
236/// / Keyword_sizeof UnaryExpr
237/// / Keyword_alignof LAPERN TypeName RPAREN
238/// / (AMPERSAND / ASTERISK / PLUS / PLUSPLUS / MINUS / MINUSMINUS / TILDE / BANG) UnaryExpr
239/// / PrimaryExpr PostFixExpr*
240fn parseUnaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
241
242/// PrimaryExpr
243/// <- IDENTIFIER
244/// / INTEGERLITERAL / FLITERAL / STRINGLITERAL / CHARLITERAL
245/// / LPAREN Expr RPAREN
246/// / Keyword_generic LPAREN AssignmentExpr (COMMA Generic)+ RPAREN
247fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
248
249/// Generic
250/// <- TypeName COLON AssignmentExpr
251/// / Keyword_default COLON AssignmentExpr
252fn parseGeneric(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
253
254/// PostFixExpr
255/// <- LPAREN TypeName RPAREN LBRACE Initializers RBRACE
256/// / LBRACKET Expr RBRACKET
257/// / LPAREN (AssignmentExpr (COMMA AssignmentExpr)*)? RPAREN
258/// / (PERIOD / ARROW) IDENTIFIER
259/// / (PLUSPLUS / MINUSMINUS)
260fn parsePostFixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
261
262/// Initializers <- ((Designator+ EQUAL)? Initializer COMMA)* (Designator+ EQUAL)? Initializer COMMA?
263fn parseInitializers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
264
265/// Initializer
266/// <- LBRACE Initializers RBRACE
267/// / AssignmentExpr
268fn parseInitializer(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
269
270/// Designator
271/// <- LBRACKET Initializers RBRACKET
272/// / PERIOD IDENTIFIER
273fn parseDesignator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
274
275/// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE
276fn parseCompoundStmt(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
277
278/// Stmt
279/// <- CompoundStmt
280/// / Keyword_if LPAREN Expr RPAREN Stmt (Keyword_ELSE Stmt)?
281/// / Keyword_switch LPAREN Expr RPAREN Stmt
282/// / Keyword_while LPAREN Expr RPAREN Stmt
283/// / Keyword_do statement Keyword_while LPAREN Expr RPAREN SEMICOLON
284/// / Keyword_for LPAREN (Declaration / ExprStmt) ExprStmt Expr? RPAREN Stmt
285/// / Keyword_default COLON Stmt
286/// / Keyword_case ConstExpr COLON Stmt
287/// / Keyword_goto IDENTIFIER SEMICOLON
288/// / Keyword_continue SEMICOLON
289/// / Keyword_break SEMICOLON
290/// / Keyword_return Expr? SEMICOLON
291/// / IDENTIFIER COLON Stmt
292/// / ExprStmt
293fn parseStmt(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}
294
295/// ExprStmt <- Expr? SEMICOLON
296fn parseExprStmt(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {}