Zig 0.17.0-dev (Split by item)
This is an example of documentation generated by
ZigDoc , an alternative to Zig's built-in
Auto Doc feature. See also
examples in other modes/formats . The project being documented here (as the example) is the Zig library itself.
Zig › std/ › zig/ › Parse.zig › parseExprPrecedence
parseExprPrecedence
Parse.parseExprPrecedence
fn parseExprPrecedence (p : *Parse , min_prec : i32 ) Error !?Node .Index
File
Code
fn parseExprPrecedence (p : *Parse , min_prec : i32 ) Error !?Node .Index {
assert (min_prec >= 0 );
var node = try p .parsePrefixExpr () orelse return null ;
var banned_prec : i8 = -1 ;
while (true ) {
const tok_tag = p .tokenTag (p .tok_i );
const info = operTable [@as (usize , @intCast (@backingInt (tok_tag )))];
if (info .prec < min_prec ) {
break ;
}
if (info .prec == banned_prec ) {
return p .fail (.chained_comparison_operators );
}
const oper_token = p .nextToken ();
if (tok_tag == .keyword_catch ) {
_ = try p .parsePayload ();
}
// Consider the case where there is a mismatched whitespace error but the rhs
// expression triggers stack overflow when parsing is attempted. In this case
// we want to return with an error rather than crashing on stack overflow.
{
const tok_len = tok_tag .lexeme ().?.len ;
if (p .tokenStart (oper_token ) + tok_len >= p .source .len ) {
try p .warn (.expected_expr );
return node ;
}
const char_before = p .source [p .tokenStart (oper_token ) - 1 ];
const char_after = p .source [p .tokenStart (oper_token ) + tok_len ];
if (tok_tag == .ampersand and char_after == '&' ) {
// The best the parser can do is recommend changing it to 'and' or ' & &'
try p .warnMsg (.{ .tag = .invalid_ampersand_ampersand , .token = oper_token });
} else if (std .ascii .isWhitespace (char_before ) != std .ascii .isWhitespace (char_after )) {
try p .warnMsg (.{ .tag = .mismatched_binary_op_whitespace , .token = oper_token });
}
}
const rhs = try p .parseExprPrecedence (info .prec + 1 ) orelse {
try p .warn (.expected_expr );
return node ;
};
node = try p .addNode (.{
.tag = info .tag ,
.main_token = oper_token ,
.data = .{ .node_and_node = .{ node , rhs } },
});
if (info .assoc == Assoc .none ) {
banned_prec = info .prec ;
}
}
return node ;
}