-
-
Notifications
You must be signed in to change notification settings - Fork 329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parsing Fuzzer Fixes #7672
Parsing Fuzzer Fixes #7672
Changes from all commits
abbcd74
d970230
b103e0b
9d2c811
f6ae028
35cd1e8
eeae3cd
62d208d
f6b94b7
8c75277
0ef4b16
3299a3e
383ad56
138975a
6121f2a
cc4a451
ea83e5b
0f17521
dbc2daf
c74f0a5
9472052
5755303
0961098
dca8aff
634dfb1
c8f7ac6
7706299
edee4ba
22d0a13
b5bbf77
bb455e2
b43d9f0
f66261f
18593b5
f09af53
365a9d5
39e1596
2fc3cd9
000b9c2
58da88d
680c434
bbf5465
fefd3a8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,15 +22,19 @@ pub fn parse(env: *base.ModuleEnv, source: []const u8) IR { | |
tokenizer.tokenize(); | ||
const result = tokenizer.finishAndDeinit(); | ||
|
||
if (result.messages.len > 0) { | ||
tokenizeReport(env.gpa, source, result.messages); | ||
for (result.messages) |msg| { | ||
_ = env.problems.append(env.gpa, .{ .tokenize = msg }); | ||
} | ||
Comment on lines
+25
to
27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to clarify here, the tokenizer and parser are building a local list of errors and we are later adding them to the global list? I would expect that the tokenzer and parser just add directly to the global list. Any specific reason for forcing the caller to move everything into the global list. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's just that the Parser was built independently of the ModuleEnv design, and we haven't yet converged on a final form. I think we should we will just add to the module environment, which helps with reporting and various other things that cut across the whole compiler. But that change can happen in a future PR. |
||
|
||
var parser = Parser.init(result.tokens); | ||
defer parser.deinit(); | ||
|
||
parser.parseFile(); | ||
|
||
for (parser.diagnostics.items) |msg| { | ||
_ = env.problems.append(env.gpa, .{ .parser = msg }); | ||
} | ||
|
||
const errors = parser.diagnostics.toOwnedSlice(env.gpa) catch |err| exitOnOom(err); | ||
|
||
return .{ | ||
|
@@ -40,106 +44,3 @@ pub fn parse(env: *base.ModuleEnv, source: []const u8) IR { | |
.errors = errors, | ||
}; | ||
} | ||
|
||
fn lineNum(newlines: std.ArrayList(usize), pos: u32) u32 { | ||
const pos_usize = @as(usize, @intCast(pos)); | ||
var lineno: u32 = 0; | ||
while (lineno < newlines.items.len) { | ||
if (newlines.items[lineno + 1] > pos_usize) { | ||
return lineno; | ||
} | ||
lineno += 1; | ||
} | ||
return lineno; | ||
} | ||
|
||
fn tokenizeReport(allocator: std.mem.Allocator, source: []const u8, msgs: []const tokenize.Diagnostic) void { | ||
std.debug.print("Found the {d} following issues while tokenizing:\n", .{msgs.len}); | ||
var newlines = std.ArrayList(usize).init(allocator); | ||
defer newlines.deinit(); | ||
newlines.append(0) catch |err| exitOnOom(err); | ||
var pos: usize = 0; | ||
for (source) |c| { | ||
if (c == '\n') { | ||
newlines.append(pos) catch |err| exitOnOom(err); | ||
} | ||
pos += 1; | ||
} | ||
for (msgs) |message| { | ||
switch (message.tag) { | ||
.MismatchedBrace => { | ||
const start_line_num = lineNum(newlines, message.begin); | ||
const start_col = message.begin - newlines.items[start_line_num]; | ||
const end_line_num = lineNum(newlines, message.end); | ||
const end_col = message.end - newlines.items[end_line_num]; | ||
|
||
const src = source[newlines.items[start_line_num]..newlines.items[end_line_num + 1]]; | ||
var spaces = std.ArrayList(u8).init(allocator); | ||
defer spaces.deinit(); | ||
for (0..start_col) |_| { | ||
spaces.append(' ') catch |err| exitOnOom(err); | ||
} | ||
|
||
std.debug.print( | ||
"({d}:{d}-{d}:{d}) Expected the correct closing brace here:\n{s}\n{s}^\n", | ||
.{ start_line_num, start_col, end_line_num, end_col, src, spaces.toOwnedSlice() catch |err| exitOnOom(err) }, | ||
); | ||
}, | ||
else => { | ||
std.debug.print("MSG: {any}\n", .{message}); | ||
}, | ||
} | ||
} | ||
} | ||
|
||
// TODO move this somewhere better, for now it's here to keep it simple. | ||
fn testSExprHelper(source: []const u8, expected: []const u8) !void { | ||
var env = base.ModuleEnv.init(testing.allocator); | ||
defer env.deinit(); | ||
|
||
// parse our source | ||
var parse_ast = parse(&env, source); | ||
defer parse_ast.deinit(); | ||
std.testing.expectEqualSlices(IR.Diagnostic, &[_]IR.Diagnostic{}, parse_ast.errors) catch { | ||
std.debug.print("Tokens:\n{any}", .{parse_ast.tokens.tokens.items(.tag)}); | ||
std.debug.panic("Test failed with parse errors", .{}); | ||
}; | ||
|
||
// shouldn't be required in future | ||
parse_ast.store.emptyScratch(); | ||
|
||
// buffer to write our SExpr to | ||
var buf = std.ArrayList(u8).init(testing.allocator); | ||
defer buf.deinit(); | ||
|
||
// convert the AST to our SExpr | ||
try parse_ast.toSExprStr(&env, buf.writer().any()); | ||
|
||
// TODO in future we should just write the SExpr to a file and snapshot it | ||
// for now we are comparing strings to keep it simple | ||
try testing.expectEqualStrings(expected, buf.items[0..]); | ||
} | ||
|
||
test "example s-expr" { | ||
const source = | ||
\\module [foo, bar] | ||
\\ | ||
\\foo = "hey" | ||
\\bar = "yo" | ||
; | ||
|
||
const expected = | ||
\\(file | ||
\\ (header | ||
\\ (exposed_item (lower_ident 'foo')) | ||
\\ (exposed_item (lower_ident 'bar'))) | ||
\\ (decl | ||
\\ (ident 'foo') | ||
\\ (string 'hey')) | ||
\\ (decl | ||
\\ (ident 'bar') | ||
\\ (string 'yo'))) | ||
; | ||
|
||
try testSExprHelper(source, expected); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is in the old compiler and probably wrong?
I would guess that zig 0.13.0 filters this differently than zig 0.14.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it was zig 0.14.0 that made this change. But old-workflows have ran this over and been happy so I left it.