sizeof is surprisingly difficult to parse in c
8 points by raymii
8 points by raymii
C has a lot of this stuff in it: accidental complexity that is unrelated to the essential complexity of being a 70s language built for low level programming. I wonder if anyone has investigated why C ended up this way - I recall that other languages of the time could have fairly straightforward syntax.
A lot of this is that, unlike Algol and successors, C didn’t start with a formal grammar. The grammar for C was ‘whatever the C compiler accepts’. When C89 was standardised, they had to define parsing rules that accepted existing C code. The original C compilers were incredibly memory constrained, so the parsers contained a bunch of hacks to minimise the amount of state that they had to track.
I’m not sure if I misread the post but the way you are supposed to resolve this is tracking what a symbol refers to (name or type). You need to do this anyways in C. As a result the parsing ambiguity becomes less problematic because the only remaining question is whether you’re looking at sizeof(type) or sizeof((type){...}), which can be resolved with a small amount of lookahead after the closing parenthesis. In a way the hard part isn’t sizeof itself but already having enough semantic information to recognize a type name in the first place.
The pseudo code is a bit like this (I had AI generate this for me since I’m on the phone):
consume("sizeof")
if next_token != '(':
operand = parse_unary_expression()
return SizeofExpression(operand)
consume('(')
if tokens_begin_type_name_using_current_scope(): /* this part matters */
type = parse_type_name()
consume(')')
if next_token == '{':
expr = parse_compound_literal(type)
expr = parse_postfix_suffixes(expr)
return SizeofExpression(expr)
return SizeofType(type)
expr = parse_parenthesized_expression()
expr = parse_postfix_suffixes(expr)
return SizeofExpression(expr)