| ... | @@ -55,242 +55,356 @@ pub fn parse(allocator: *Allocator, source: []const u8) !*Tree { | ... | @@ -55,242 +55,356 @@ pub fn parse(allocator: *Allocator, source: []const u8) !*Tree { |
| 55 | } | 55 | } |
| 56 | } | 56 | } |
| 57 | | 57 | |
| 58 | tree.root_node = try parseRoot(arena, &it, tree); | 58 | var parser = Parser{ |
| | 59 | .arena = arena, |
| | 60 | .it = &it, |
| | 61 | .tree = tree, |
| | 62 | }; |
| | 63 | |
| | 64 | tree.root_node = try parser.root(); |
| 59 | return tree; | 65 | return tree; |
| 60 | } | 66 | } |
| 61 | | 67 | |
| 62 | /// Root <- ExternalDeclaration* eof | 68 | const Parser = struct { |
| 63 | fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!*Node { | 69 | arena: *Allocator, |
| 64 | const node = try arena.create(ast.Root); | 70 | it: *TokenIterator, |
| 65 | node.* = .{ | 71 | tree: *Tree, |
| 66 | .decls = ast.Node.DeclList.init(arena), | 72 | |
| 67 | .eof_token = undefined, | 73 | /// Root <- ExternalDeclaration* eof |
| 68 | }; | 74 | fn root(parser: *Parser) Allocator.Error!*Node { |
| 69 | while (parseExternalDeclarations(arena, it, tree) catch |err| switch (err) { | 75 | const node = try arena.create(ast.Root); |
| 70 | error.OutOfMemory => return error.OutOfMemory, | 76 | node.* = .{ |
| 71 | error.ParseError => return node, | 77 | .decls = ast.Node.DeclList.init(arena), |
| 72 | }) |decl| { | 78 | .eof = undefined, |
| 73 | try node.decls.push(decl); | 79 | }; |
| 74 | } | 80 | while (parser.externalDeclarations() catch |err| switch (err) { |
| 75 | node.eof_token = eatToken(it, .Eof) orelse { | 81 | error.OutOfMemory => return error.OutOfMemory, |
| 76 | try tree.errors.push(.{ | 82 | error.ParseError => return node, |
| 77 | .ExpectedDecl = .{ .token = it.index }, | 83 | }) |decl| { |
| 78 | }); | 84 | try node.decls.push(decl); |
| | 85 | } |
| | 86 | node.eof = eatToken(it, .Eof) orelse { |
| | 87 | try tree.errors.push(.{ |
| | 88 | .ExpectedDecl = .{ .token = it.index }, |
| | 89 | }); |
| | 90 | return node; |
| | 91 | }; |
| 79 | return node; | 92 | return node; |
| 80 | }; | 93 | } |
| 81 | return node; | | |
| 82 | } | | |
| 83 | | 94 | |
| 84 | /// ExternalDeclaration | 95 | /// ExternalDeclaration |
| 85 | /// <- Declaration | 96 | /// <- Declaration |
| 86 | /// / DeclarationSpecifiers Declarator Declaration* CompoundStmt | 97 | /// / DeclarationSpecifiers Declarator Declaration* CompoundStmt |
| 87 | fn parseExternalDeclarations(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | 98 | fn externalDeclarations(parser: *Parser) !?*Node { |
| 88 | if (try parseDeclaration(arena, it, tree)) |decl| {} | 99 | if (try Declaration(parser)) |decl| {} |
| 89 | return null; | 100 | return null; |
| 90 | } | 101 | } |
| | 102 | |
| | 103 | /// Declaration |
| | 104 | /// <- DeclarationSpecifiers (Declarator (EQUAL Initializer)?)* SEMICOLON |
| | 105 | /// \ StaticAssertDeclaration |
| | 106 | fn declaration(parser: *Parser) !?*Node {} |
| | 107 | |
| | 108 | /// StaticAssertDeclaration <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON |
| | 109 | fn staticAssertDeclaration(parser: *Parser) !?*Node {} |
| | 110 | |
| | 111 | /// DeclarationSpecifiers |
| | 112 | /// <- StorageClassSpecifier DeclarationSpecifiers? |
| | 113 | /// / TypeSpecifier DeclarationSpecifiers? |
| | 114 | /// / TypeQualifier DeclarationSpecifiers? |
| | 115 | /// / FunctionSpecifier DeclarationSpecifiers? |
| | 116 | /// / AlignmentSpecifier DeclarationSpecifiers? |
| | 117 | fn declarationSpecifiers(parser: *Parser) !*Node {} |
| | 118 | |
| | 119 | /// StorageClassSpecifier |
| | 120 | /// <- Keyword_typedef / Keyword_extern / Keyword_static / Keyword_thread_local / Keyword_auto / Keyword_register |
| | 121 | fn storageClassSpecifier(parser: *Parser) !*Node {} |
| | 122 | |
| | 123 | /// TypeSpecifier |
| | 124 | /// <- Keyword_void / Keyword_char / Keyword_short / Keyword_int / Keyword_long / Keyword_float / Keyword_double |
| | 125 | /// / Keyword_signed / Keyword_unsigned / Keyword_bool / Keyword_complex / Keyword_imaginary / |
| | 126 | /// / Keyword_atomic LPAREN TypeName RPAREN |
| | 127 | /// / EnumSpecifier |
| | 128 | /// / RecordSpecifier |
| | 129 | /// / IDENTIFIER // typedef name |
| | 130 | fn typeSpecifier(parser: *Parser) !*Node {} |
| | 131 | |
| | 132 | /// TypeQualifier <- Keyword_const / Keyword_restrict / Keyword_volatile / Keyword_atomic |
| | 133 | fn typeQualifier(parser: *Parser) !*Node {} |
| | 134 | |
| | 135 | /// FunctionSpecifier <- Keyword_inline / Keyword_noreturn |
| | 136 | fn functionSpecifier(parser: *Parser) !*Node {} |
| 91 | | 137 | |
| 92 | /// Declaration | 138 | /// AlignmentSpecifier <- Keyword_alignas LPAREN (TypeName / ConstExpr) RPAREN |
| 93 | /// <- DeclarationSpecifiers (Declarator (EQUAL Initializer)?)* SEMICOLON | 139 | fn alignmentSpecifier(parser: *Parser) !*Node {} |
| 94 | /// \ StaticAssertDeclaration | | |
| 95 | fn parseDeclaration(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {} | | |
| 96 | | | |
| 97 | /// StaticAssertDeclaration <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON | | |
| 98 | fn 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? | | |
| 106 | fn 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 | | |
| 110 | fn 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 | | |
| 119 | fn parseTypeSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 120 | | 140 | |
| 121 | /// TypeQualifier <- Keyword_const / Keyword_restrict / Keyword_volatile / Keyword_atomic | 141 | /// EnumSpecifier <- Keyword_enum IDENTIFIER? (LBRACE EnumField RBRACE)? |
| 122 | fn parseTypeQualifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | 142 | fn enumSpecifier(parser: *Parser) !*Node {} |
| 123 | | 143 | |
| 124 | /// FunctionSpecifier <- Keyword_inline / Keyword_noreturn | 144 | /// EnumField <- IDENTIFIER (EQUAL ConstExpr)? (COMMA EnumField) COMMA? |
| 125 | fn parseFunctionSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | 145 | fn enumField(parser: *Parser) !*Node {} |
| 126 | | 146 | |
| 127 | /// AlignmentSpecifier <- Keyword_alignas LPAREN (TypeName / ConstExpr) RPAREN | 147 | /// RecordSpecifier <- (Keyword_struct / Keyword_union) IDENTIFIER? (LBRACE RecordField+ RBRACE)? |
| 128 | fn parseAlignmentSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | 148 | fn recordSpecifier(parser: *Parser) !*Node {} |
| | 149 | |
| | 150 | /// RecordField |
| | 151 | /// <- SpecifierQualifer (RecordDeclarator (COMMA RecordDeclarator))? SEMICOLON |
| | 152 | /// \ StaticAssertDeclaration |
| | 153 | fn recordField(parser: *Parser) !*Node {} |
| | 154 | |
| | 155 | /// TypeName |
| | 156 | /// <- SpecifierQualifer AbstractDeclarator? |
| | 157 | fn typeName(parser: *Parser) !*Node {} |
| | 158 | |
| | 159 | /// SpecifierQualifer |
| | 160 | /// <- TypeSpecifier SpecifierQualifer? |
| | 161 | /// / TypeQualifier SpecifierQualifer? |
| | 162 | fn specifierQualifer(parser: *Parser) !*Node {} |
| | 163 | |
| | 164 | /// RecordDeclarator <- Declarator? (COLON ConstExpr)? |
| | 165 | fn recordDeclarator(parser: *Parser) !*Node {} |
| | 166 | |
| | 167 | /// Declarator <- Pointer? DirectDeclarator |
| | 168 | fn declarator(parser: *Parser) !*Node {} |
| | 169 | |
| | 170 | /// Pointer <- ASTERISK TypeQualifier* Pointer? |
| | 171 | fn pointer(parser: *Parser) !*Node {} |
| | 172 | |
| | 173 | /// DirectDeclarator |
| | 174 | /// <- IDENTIFIER |
| | 175 | /// / LPAREN Declarator RPAREN |
| | 176 | /// / DirectDeclarator LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET |
| | 177 | /// / DirectDeclarator LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN |
| | 178 | fn directDeclarator(parser: *Parser) !*Node {} |
| | 179 | |
| | 180 | /// BracketDeclarator |
| | 181 | /// <- Keyword_static TypeQualifier* AssignmentExpr |
| | 182 | /// / TypeQualifier+ (ASTERISK / Keyword_static AssignmentExpr) |
| | 183 | /// / TypeQualifier+ AssignmentExpr? |
| | 184 | /// / AssignmentExpr |
| | 185 | fn bracketDeclarator(parser: *Parser) !*Node {} |
| | 186 | |
| | 187 | /// ParamDecl <- DeclarationSpecifiers (Declarator / AbstractDeclarator) |
| | 188 | fn paramDecl(parser: *Parser) !*Node {} |
| | 189 | |
| | 190 | /// AbstractDeclarator <- Pointer? DirectAbstractDeclarator? |
| | 191 | fn abstractDeclarator(parser: *Parser) !*Node {} |
| | 192 | |
| | 193 | /// DirectAbstractDeclarator |
| | 194 | /// <- IDENTIFIER |
| | 195 | /// / LPAREN DirectAbstractDeclarator RPAREN |
| | 196 | /// / DirectAbstractDeclarator? LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET |
| | 197 | /// / DirectAbstractDeclarator? LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN |
| | 198 | fn directAbstractDeclarator(parser: *Parser) !*Node {} |
| | 199 | |
| | 200 | /// Expr <- AssignmentExpr (COMMA Expr)* |
| | 201 | fn expr(parser: *Parser) !*Node {} |
| | 202 | |
| | 203 | /// AssignmentExpr |
| | 204 | /// <- ConditionalExpr // TODO recursive? |
| | 205 | /// / UnaryExpr (EQUAL / ASTERISKEQUAL / SLASHEQUAL / PERCENTEQUAL / PLUSEQUAL / MINUSEQUA / |
| | 206 | /// / ANGLEBRACKETANGLEBRACKETLEFTEQUAL / ANGLEBRACKETANGLEBRACKETRIGHTEQUAL / |
| | 207 | /// / AMPERSANDEQUAL / CARETEQUAL / PIPEEQUAL) AssignmentExpr |
| | 208 | fn assignmentExpr(parser: *Parser) !*Node {} |
| | 209 | |
| | 210 | /// ConstExpr <- ConditionalExpr |
| | 211 | /// ConditionalExpr <- LogicalOrExpr (QUESTIONMARK Expr COLON ConditionalExpr)? |
| | 212 | fn conditionalExpr(parser: *Parser) !*Node {} |
| | 213 | |
| | 214 | /// LogicalOrExpr <- LogicalAndExpr (PIPEPIPE LogicalOrExpr)* |
| | 215 | fn logicalOrExpr(parser: *Parser) !*Node {} |
| | 216 | |
| | 217 | /// LogicalAndExpr <- BinOrExpr (AMPERSANDAMPERSAND LogicalAndExpr)* |
| | 218 | fn logicalAndExpr(parser: *Parser) !*Node {} |
| | 219 | |
| | 220 | /// BinOrExpr <- BinXorExpr (PIPE BinOrExpr)* |
| | 221 | fn binOrExpr(parser: *Parser) !*Node {} |
| | 222 | |
| | 223 | /// BinXorExpr <- BinAndExpr (CARET BinXorExpr)* |
| | 224 | fn binXorExpr(parser: *Parser) !*Node {} |
| | 225 | |
| | 226 | /// BinAndExpr <- EqualityExpr (AMPERSAND BinAndExpr)* |
| | 227 | fn binAndExpr(parser: *Parser) !*Node {} |
| | 228 | |
| | 229 | /// EqualityExpr <- ComparisionExpr ((EQUALEQUAL / BANGEQUAL) EqualityExpr)* |
| | 230 | fn equalityExpr(parser: *Parser) !*Node {} |
| | 231 | |
| | 232 | /// ComparisionExpr <- ShiftExpr (ANGLEBRACKETLEFT / ANGLEBRACKETLEFTEQUAL /ANGLEBRACKETRIGHT / ANGLEBRACKETRIGHTEQUAL) ComparisionExpr)* |
| | 233 | fn comparisionExpr(parser: *Parser) !*Node {} |
| | 234 | |
| | 235 | /// ShiftExpr <- AdditiveExpr (ANGLEBRACKETANGLEBRACKETLEFT / ANGLEBRACKETANGLEBRACKETRIGHT) ShiftExpr)* |
| | 236 | fn shiftExpr(parser: *Parser) !*Node {} |
| | 237 | |
| | 238 | /// AdditiveExpr <- MultiplicativeExpr (PLUS / MINUS) AdditiveExpr)* |
| | 239 | fn additiveExpr(parser: *Parser) !*Node {} |
| | 240 | |
| | 241 | /// MultiplicativeExpr <- UnaryExpr (ASTERISK / SLASH / PERCENT) MultiplicativeExpr)* |
| | 242 | fn multiplicativeExpr(parser: *Parser) !*Node {} |
| | 243 | |
| | 244 | /// UnaryExpr |
| | 245 | /// <- LPAREN TypeName RPAREN UnaryExpr |
| | 246 | /// / Keyword_sizeof LAPERN TypeName RPAREN |
| | 247 | /// / Keyword_sizeof UnaryExpr |
| | 248 | /// / Keyword_alignof LAPERN TypeName RPAREN |
| | 249 | /// / (AMPERSAND / ASTERISK / PLUS / PLUSPLUS / MINUS / MINUSMINUS / TILDE / BANG) UnaryExpr |
| | 250 | /// / PrimaryExpr PostFixExpr* |
| | 251 | fn unaryExpr(parser: *Parser) !*Node {} |
| | 252 | |
| | 253 | /// PrimaryExpr |
| | 254 | /// <- IDENTIFIER |
| | 255 | /// / INTEGERLITERAL / FLITERAL / STRINGLITERAL / CHARLITERAL |
| | 256 | /// / LPAREN Expr RPAREN |
| | 257 | /// / Keyword_generic LPAREN AssignmentExpr (COMMA Generic)+ RPAREN |
| | 258 | fn primaryExpr(parser: *Parser) !*Node {} |
| | 259 | |
| | 260 | /// Generic |
| | 261 | /// <- TypeName COLON AssignmentExpr |
| | 262 | /// / Keyword_default COLON AssignmentExpr |
| | 263 | fn generic(parser: *Parser) !*Node {} |
| | 264 | |
| | 265 | /// PostFixExpr |
| | 266 | /// <- LPAREN TypeName RPAREN LBRACE Initializers RBRACE |
| | 267 | /// / LBRACKET Expr RBRACKET |
| | 268 | /// / LPAREN (AssignmentExpr (COMMA AssignmentExpr)*)? RPAREN |
| | 269 | /// / (PERIOD / ARROW) IDENTIFIER |
| | 270 | /// / (PLUSPLUS / MINUSMINUS) |
| | 271 | fn postFixExpr(parser: *Parser) !*Node {} |
| | 272 | |
| | 273 | /// Initializers <- ((Designator+ EQUAL)? Initializer COMMA)* (Designator+ EQUAL)? Initializer COMMA? |
| | 274 | fn initializers(parser: *Parser) !*Node {} |
| | 275 | |
| | 276 | /// Initializer |
| | 277 | /// <- LBRACE Initializers RBRACE |
| | 278 | /// / AssignmentExpr |
| | 279 | fn initializer(parser: *Parser) !*Node {} |
| | 280 | |
| | 281 | /// Designator |
| | 282 | /// <- LBRACKET Initializers RBRACKET |
| | 283 | /// / PERIOD IDENTIFIER |
| | 284 | fn designator(parser: *Parser) !*Node {} |
| | 285 | |
| | 286 | /// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE |
| | 287 | fn compoundStmt(parser: *Parser) !?*Node {} |
| | 288 | |
| | 289 | /// Stmt |
| | 290 | /// <- CompoundStmt |
| | 291 | /// / Keyword_if LPAREN Expr RPAREN Stmt (Keyword_ELSE Stmt)? |
| | 292 | /// / Keyword_switch LPAREN Expr RPAREN Stmt |
| | 293 | /// / Keyword_while LPAREN Expr RPAREN Stmt |
| | 294 | /// / Keyword_do statement Keyword_while LPAREN Expr RPAREN SEMICOLON |
| | 295 | /// / Keyword_for LPAREN (Declaration / ExprStmt) ExprStmt Expr? RPAREN Stmt |
| | 296 | /// / Keyword_default COLON Stmt |
| | 297 | /// / Keyword_case ConstExpr COLON Stmt |
| | 298 | /// / Keyword_goto IDENTIFIER SEMICOLON |
| | 299 | /// / Keyword_continue SEMICOLON |
| | 300 | /// / Keyword_break SEMICOLON |
| | 301 | /// / Keyword_return Expr? SEMICOLON |
| | 302 | /// / IDENTIFIER COLON Stmt |
| | 303 | /// / ExprStmt |
| | 304 | fn stmt(parser: *Parser) !?*Node { |
| | 305 | if (parser.compoundStmt()) |node| return node; |
| | 306 | // if (parser.eatToken(.Keyword_if)) |tok| {} |
| | 307 | // if (parser.eatToken(.Keyword_switch)) |tok| {} |
| | 308 | // if (parser.eatToken(.Keyword_while)) |tok| {} |
| | 309 | // if (parser.eatToken(.Keyword_do)) |tok| {} |
| | 310 | // if (parser.eatToken(.Keyword_for)) |tok| {} |
| | 311 | // if (parser.eatToken(.Keyword_default)) |tok| {} |
| | 312 | // if (parser.eatToken(.Keyword_case)) |tok| {} |
| | 313 | if (parser.eatToken(.Keyword_goto)) |tok| { |
| | 314 | const node = try parser.arena.create(Node.JumpStmt); |
| | 315 | node.* = .{ |
| | 316 | .ltoken = tok, |
| | 317 | .kind = .Goto, |
| | 318 | .semicolon = parser.expectToken(.Semicolon), |
| | 319 | }; |
| | 320 | return &node.base; |
| | 321 | } |
| | 322 | if (parser.eatToken(.Keyword_continue)) |tok| { |
| | 323 | const node = try parser.arena.create(Node.JumpStmt); |
| | 324 | node.* = .{ |
| | 325 | .ltoken = tok, |
| | 326 | .kind = .Continue, |
| | 327 | .semicolon = parser.expectToken(.Semicolon), |
| | 328 | }; |
| | 329 | return &node.base; |
| | 330 | } |
| | 331 | if (parser.eatToken(.Keyword_break)) |tok| { |
| | 332 | const node = try parser.arena.create(Node.JumpStmt); |
| | 333 | node.* = .{ |
| | 334 | .ltoken = tok, |
| | 335 | .kind = .Break, |
| | 336 | .semicolon = parser.expectToken(.Semicolon), |
| | 337 | }; |
| | 338 | return &node.base; |
| | 339 | } |
| | 340 | if (parser.eatToken(.Keyword_return)) |tok| { |
| | 341 | const node = try parser.arena.create(Node.JumpStmt); |
| | 342 | node.* = .{ |
| | 343 | .ltoken = tok, |
| | 344 | .kind = .{ .Return = try parser.expr() }, |
| | 345 | .semicolon = parser.expectToken(.Semicolon), |
| | 346 | }; |
| | 347 | return &node.base; |
| | 348 | } |
| | 349 | if (parser.eatToken(.Identifier)) |tok| { |
| | 350 | if (parser.eatToken(.Colon)) |col| { |
| | 351 | const node = try parser.arena.create(Node.Label); |
| | 352 | node.* = .{ |
| | 353 | .identifier = tok, |
| | 354 | .semicolon = parser.expectToken(.Colon), |
| | 355 | }; |
| | 356 | return &node.base; |
| | 357 | } |
| | 358 | putBackToken(tok); |
| | 359 | } |
| | 360 | if (parser.exprStmt()) |node| return node; |
| | 361 | return null; |
| | 362 | } |
| 129 | | 363 | |
| 130 | /// EnumSpecifier <- Keyword_enum IDENTIFIER? (LBRACE EnumField RBRACE)? | 364 | /// ExprStmt <- Expr? SEMICOLON |
| 131 | fn parseEnumSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | 365 | fn exprStmt(parser: *Parser) !*Node { |
| | 366 | const node = try parser.arena.create(Node.ExprStmt); |
| | 367 | node.* = .{ |
| | 368 | .expr = try parser.expr(), |
| | 369 | .semicolon = parser.expectToken(.Semicolon), |
| | 370 | }; |
| | 371 | return &node.base; |
| | 372 | } |
| 132 | | 373 | |
| 133 | /// EnumField <- IDENTIFIER (EQUAL ConstExpr)? (COMMA EnumField) COMMA? | 374 | fn eatToken(parser: *Parser, id: Token.Id) ?TokenIndex { |
| 134 | fn parseEnumField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | 375 | while (true) { |
| | 376 | const next_tok = parser.it.next() orelse return null; |
| | 377 | if (next_tok.id != .LineComment and next_tok.id != .MultiLineComment) { |
| | 378 | if (next_tok.id == id) { |
| | 379 | return parser.it.index; |
| | 380 | } |
| | 381 | parser.it.prev(); |
| | 382 | return null; |
| | 383 | } |
| | 384 | } |
| | 385 | } |
| 135 | | 386 | |
| 136 | /// RecordSpecifier <- (Keyword_struct / Keyword_union) IDENTIFIER? (LBRACE RecordField+ RBRACE)? | 387 | fn expectToken(parser: *Parser, id: Token.Id) Error!TokenIndex { |
| 137 | fn parseRecordSpecifier(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | 388 | while (true) { |
| 138 | | 389 | const next_tok = parser.it.next() orelse return error.ParseError; |
| 139 | /// RecordField | 390 | if (next_tok.id != .LineComment and next_tok.id != .MultiLineComment) { |
| 140 | /// <- SpecifierQualifer (RecordDeclarator (COMMA RecordDeclarator))? SEMICOLON | 391 | if (next_tok.id != id) { |
| 141 | /// \ StaticAssertDeclaration | 392 | try tree.errors.push(.{ |
| 142 | fn parseRecordField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | 393 | .ExpectedToken = .{ .token = parser.it.index, .expected_id = id }, |
| 143 | | 394 | }); |
| 144 | /// TypeName | 395 | return error.ParseError; |
| 145 | /// <- SpecifierQualifer AbstractDeclarator? | 396 | } |
| 146 | fn parseTypeName(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | 397 | return parser.it.index; |
| 147 | | 398 | } |
| 148 | /// SpecifierQualifer | 399 | } |
| 149 | /// <- TypeSpecifier SpecifierQualifer? | 400 | } |
| 150 | /// / TypeQualifier SpecifierQualifer? | 401 | |
| 151 | fn parseSpecifierQualifer(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | 402 | fn putBackToken(it: *TokenIterator, putting_back: TokenIndex) void { |
| 152 | | 403 | while (true) { |
| 153 | /// RecordDeclarator <- Declarator? (COLON ConstExpr)? | 404 | const prev_tok = it.prev() orelse return; |
| 154 | fn parseRecordDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | 405 | if (next_tok.id == .LineComment or next_tok.id == .MultiLineComment) continue; |
| 155 | | 406 | assert(it.list.at(putting_back) == prev_tok); |
| 156 | /// Declarator <- Pointer? DirectDeclarator | 407 | return; |
| 157 | fn parseDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | 408 | } |
| 158 | | 409 | } |
| 159 | /// Pointer <- ASTERISK TypeQualifier* Pointer? | 410 | }; |
| 160 | fn 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 | | |
| 167 | fn 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 | | |
| 174 | fn parseBracketDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 175 | | | |
| 176 | /// ParamDecl <- DeclarationSpecifiers (Declarator / AbstractDeclarator) | | |
| 177 | fn parseParamDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 178 | | | |
| 179 | /// AbstractDeclarator <- Pointer? DirectAbstractDeclarator? | | |
| 180 | fn 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 | | |
| 187 | fn parseDirectAbstractDeclarator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 188 | | | |
| 189 | /// Expr <- AssignmentExpr (COMMA Expr)* | | |
| 190 | fn 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 | | |
| 197 | fn parseAssignmentExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 198 | | | |
| 199 | /// ConstExpr <- ConditionalExpr | | |
| 200 | /// ConditionalExpr <- LogicalOrExpr (QUESTIONMARK Expr COLON ConditionalExpr)? | | |
| 201 | fn parseConditionalExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 202 | | | |
| 203 | /// LogicalOrExpr <- LogicalAndExpr (PIPEPIPE LogicalOrExpr)* | | |
| 204 | fn parseLogicalOrExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 205 | | | |
| 206 | /// LogicalAndExpr <- BinOrExpr (AMPERSANDAMPERSAND LogicalAndExpr)* | | |
| 207 | fn parseLogicalAndExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 208 | | | |
| 209 | /// BinOrExpr <- BinXorExpr (PIPE BinOrExpr)* | | |
| 210 | fn parseBinOrExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 211 | | | |
| 212 | /// BinXorExpr <- BinAndExpr (CARET BinXorExpr)* | | |
| 213 | fn parseBinXorExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 214 | | | |
| 215 | /// BinAndExpr <- EqualityExpr (AMPERSAND BinAndExpr)* | | |
| 216 | fn parseBinAndExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 217 | | | |
| 218 | /// EqualityExpr <- ComparisionExpr ((EQUALEQUAL / BANGEQUAL) EqualityExpr)* | | |
| 219 | fn parseEqualityExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 220 | | | |
| 221 | /// ComparisionExpr <- ShiftExpr (ANGLEBRACKETLEFT / ANGLEBRACKETLEFTEQUAL /ANGLEBRACKETRIGHT / ANGLEBRACKETRIGHTEQUAL) ComparisionExpr)* | | |
| 222 | fn parseComparisionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 223 | | | |
| 224 | /// ShiftExpr <- AdditiveExpr (ANGLEBRACKETANGLEBRACKETLEFT / ANGLEBRACKETANGLEBRACKETRIGHT) ShiftExpr)* | | |
| 225 | fn parseShiftExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 226 | | | |
| 227 | /// AdditiveExpr <- MultiplicativeExpr (PLUS / MINUS) AdditiveExpr)* | | |
| 228 | fn parseAdditiveExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 229 | | | |
| 230 | /// MultiplicativeExpr <- UnaryExpr (ASTERISK / SLASH / PERCENT) MultiplicativeExpr)* | | |
| 231 | fn 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* | | |
| 240 | fn 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 | | |
| 247 | fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 248 | | | |
| 249 | /// Generic | | |
| 250 | /// <- TypeName COLON AssignmentExpr | | |
| 251 | /// / Keyword_default COLON AssignmentExpr | | |
| 252 | fn 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) | | |
| 260 | fn parsePostFixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 261 | | | |
| 262 | /// Initializers <- ((Designator+ EQUAL)? Initializer COMMA)* (Designator+ EQUAL)? Initializer COMMA? | | |
| 263 | fn parseInitializers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 264 | | | |
| 265 | /// Initializer | | |
| 266 | /// <- LBRACE Initializers RBRACE | | |
| 267 | /// / AssignmentExpr | | |
| 268 | fn parseInitializer(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 269 | | | |
| 270 | /// Designator | | |
| 271 | /// <- LBRACKET Initializers RBRACKET | | |
| 272 | /// / PERIOD IDENTIFIER | | |
| 273 | fn parseDesignator(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 274 | | | |
| 275 | /// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE | | |
| 276 | fn 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 | | |
| 293 | fn parseStmt(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |
| 294 | | | |
| 295 | /// ExprStmt <- Expr? SEMICOLON | | |
| 296 | fn parseExprStmt(arena: *Allocator, it: *TokenIterator, tree: *Tree) !*Node {} | | |