From 7ddd37b725a79a6eb02d747b445fb7032fc9b252 Mon Sep 17 00:00:00 2001 From: Luna Date: Fri, 20 Sep 2019 12:22:46 -0300 Subject: [PATCH] add synchronization to the parser --- src/main.zig | 6 +++-- src/parsers.zig | 59 +++++++++++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/main.zig b/src/main.zig index f17f242..cf09d7c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -38,10 +38,12 @@ pub fn run(allocator: *std.mem.Allocator, slice: []const u8) !Result { var parser = parsers.Parser.init(allocator, &scan); var root = try parser.parse(); - var it = root.Root.iterator(); + if (root == null) { + return Result.ParseError; + } std.debug.warn("parse tree\n"); - //printer.printNode(root, 0); + printer.printNode(root.?, 0); return Result.Ok; } diff --git a/src/parsers.zig b/src/parsers.zig index 1b25957..de655e7 100644 --- a/src/parsers.zig +++ b/src/parsers.zig @@ -3,7 +3,7 @@ const scanners = @import("scanners.zig"); const main = @import("main.zig"); const ast = @import("ast.zig"); const tokens = @import("tokens.zig"); -const err = @import("errors.zig"); +const ereport = @import("errors.zig"); const printer = @import("ast_printer.zig"); const Allocator = std.mem.Allocator; @@ -44,12 +44,31 @@ pub const Parser = struct { self.tokens.deinit(); } - fn doError(self: *Parser, comptime fmt: []const u8, args: ...) void { + fn doError(self: *Parser, comptime fmt: []const u8, args: ...) ParseError { self.hadError = true; std.debug.warn("parser error at line {}\n\t", self.scanner.line); std.debug.warn(fmt, args); std.debug.warn("\n"); + + return ParseError.CompileError; + } + + fn synchronize(self: *Parser) !void { + // TODO is it nextToken()? + _ = try self.nextToken(); + + while (!self.isAtEnd()) { + if (self.previous().typ == .Semicolon) return; + + // TODO add more "stmt"-"starting" tokens here + switch (self.peek().typ) { + .Fn => return, + else => {}, + } + + _ = try self.nextToken(); + } } fn peek(self: *Parser) Token { @@ -60,11 +79,11 @@ pub const Parser = struct { return self.tokens.at(self.tokens.len - 2); } - fn tokenError(self: *Parser, token: Token, msg: []const u8) ParseError!void { + fn tokenError(self: *Parser, token: Token, msg: []const u8) ParseError { if (token.typ == .EOF) { - err.report(token.line, " at end", msg); + ereport.report(token.line, " at end", msg); } else { - err.reportFmt(token.line, " at '{}': {}", token.lexeme, msg); + ereport.reportFmt(token.line, " at '{}': {}", token.lexeme, msg); } return ParseError.CompileError; @@ -104,8 +123,7 @@ pub const Parser = struct { return tok; } - try self.tokenError(self.peek(), msg); - return ParseError.CompileError; + return self.tokenError(self.peek(), msg); } /// Consume the current token. Gives default error messages @@ -125,8 +143,7 @@ pub const Parser = struct { self.peek().typ, ); - try self.tokenError(self.peek(), buf); - return ParseError.CompileError; + return self.tokenError(self.peek(), buf); } /// check() against multiple tokens @@ -369,7 +386,7 @@ pub const Parser = struct { return expr; } - pub fn parse(self: *Parser) !*ast.Node { + pub fn parse(self: *Parser) !?*ast.Node { var root = try Node.mkRoot(self.allocator); var token_opt: ?Token = null; @@ -384,7 +401,10 @@ pub const Parser = struct { var token = token_opt.?; if (token.typ == .EOF) break; - var node = try self.parseTopDecl(); + var node = self.parseTopDecl() catch |err| { + if (err == ParseError.CompileError) return null; + return err; + }; try root.Root.append(node.*); } @@ -610,8 +630,7 @@ pub const Parser = struct { .Enum => try self.parseEnumDecl(), else => |typ| blk: { - self.doError("expected Fn, Const, Struct, got {}\n", typ); - return ParseError.CompileError; + return self.doError("expected Fn, Const, Struct, got {}\n", typ); }, }; } @@ -840,8 +859,7 @@ pub const Parser = struct { .Get => |get| { switch (op.typ) { .ColonEqual => { - self.doError("can not initialize struct field"); - return ParseError.CompileError; + return self.doError("can not initialize struct field"); }, .Equal => return try self.mkSet(get.struc, get.name, value), @@ -860,8 +878,7 @@ pub const Parser = struct { }, else => |expr_typ| { - self.doError("Invalid assignment target {}", expr_typ); - return ParseError.CompileError; + return self.doError("Invalid assignment target {}", expr_typ); }, } } @@ -997,7 +1014,7 @@ pub const Parser = struct { expr = try self.mkGet(expr, name); } } else { - break; + return self.tokenError(self.peek(), "Expect expression."); } } @@ -1031,8 +1048,7 @@ pub const Parser = struct { // {a: 10 b: 10} // for this to work properly, must be Variable, since its a type. if (ast.ExprType(expr.*) != .Variable) { - self.doError("Expected variable for struct type, got {}", ast.ExprType(expr.*)); - return ParseError.CompileError; + return self.doError("Expected variable for struct type, got {}", ast.ExprType(expr.*)); } var inits = ast.StructInitList.init(self.allocator); @@ -1096,8 +1112,7 @@ pub const Parser = struct { }, else => blk: { - self.doError("expected literal, got {}", curtype); - return ParseError.CompileError; + return self.doError("expected literal, got {}", curtype); }, };