Module Name:    src
Committed By:   rillig
Date:           Mon Oct 25 00:54:37 UTC 2021

Modified Files:
        src/usr.bin/indent: indent.c indent.h lexi.c parse.c pr_comment.c

Log Message:
indent: split type token_type into 3 separate types

Previously, token_type was used for 3 different purposes:

1. symbol types from the lexer
2. symbol types on the parser stack
3. kind of control statement for 'if (expr)' and similar statements

Splitting the 41 constants into separate types makes it immediately
clear that the parser stack never handles comments, preprocessing lines,
newlines, form feeds, the inner structure of expressions.

Previously, the constant switch_expr was especially confusing since it
was used for 3 different purposes: when returned from lexi, it
represented the keyword 'switch', in the parser stack it represented
'switch (expr)', and it was used for a statement head as well.

The only overlap between the lexer symbols and the parser symbols are
'{' and '}', and the keywords 'do' and 'else'. To increase confusion,
the constants of the previous token_type were in apparently random
order and before 2021, they had cryptic, highly abbreviated names.

No functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.155 -r1.156 src/usr.bin/indent/indent.c
cvs rdiff -u -r1.48 -r1.49 src/usr.bin/indent/indent.h
cvs rdiff -u -r1.99 -r1.100 src/usr.bin/indent/lexi.c
cvs rdiff -u -r1.38 -r1.39 src/usr.bin/indent/parse.c
cvs rdiff -u -r1.83 -r1.84 src/usr.bin/indent/pr_comment.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/indent/indent.c
diff -u src/usr.bin/indent/indent.c:1.155 src/usr.bin/indent/indent.c:1.156
--- src/usr.bin/indent/indent.c:1.155	Sun Oct 24 22:44:13 2021
+++ src/usr.bin/indent/indent.c	Mon Oct 25 00:54:37 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: indent.c,v 1.155 2021/10/24 22:44:13 rillig Exp $	*/
+/*	$NetBSD: indent.c,v 1.156 2021/10/25 00:54:37 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
@@ -43,7 +43,7 @@ static char sccsid[] = "@(#)indent.c	5.1
 
 #include <sys/cdefs.h>
 #if defined(__NetBSD__)
-__RCSID("$NetBSD: indent.c,v 1.155 2021/10/24 22:44:13 rillig Exp $");
+__RCSID("$NetBSD: indent.c,v 1.156 2021/10/25 00:54:37 rillig Exp $");
 #elif defined(__FreeBSD__)
 __FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $");
 #endif
@@ -239,16 +239,16 @@ search_brace_lbrace(void)
 }
 
 static bool
-search_brace_other(token_type ttype, bool *force_nl,
+search_brace_other(lexer_symbol lsym, bool *force_nl,
     bool comment_buffered, bool last_else)
 {
     bool remove_newlines;
 
     remove_newlines =
 	    /* "} else" */
-	    (ttype == tt_lex_else && code.e != code.s && code.e[-1] == '}')
+	    (lsym == lsym_else && code.e != code.s && code.e[-1] == '}')
 	    /* "else if" */
-	    || (ttype == tt_lex_if && last_else && opt.else_if);
+	    || (lsym == lsym_if && last_else && opt.else_if);
     if (remove_newlines)
 	*force_nl = false;
 
@@ -301,9 +301,9 @@ switch_buffer(void)
 }
 
 static void
-search_brace_lookahead(token_type *ttype)
+search_brace_lookahead(lexer_symbol *lsym)
 {
-    if (*ttype == end_of_file)
+    if (*lsym == lsym_eof)
 	return;
 
     /*
@@ -335,39 +335,39 @@ search_brace_lookahead(token_type *ttype
 
     struct parser_state transient_state;
     transient_state = ps;
-    *ttype = lexi(&transient_state);	/* read another token */
-    if (*ttype != newline && *ttype != tt_lex_form_feed &&
-	*ttype != comment && !transient_state.search_brace) {
+    *lsym = lexi(&transient_state);	/* read another token */
+    if (*lsym != lsym_newline && *lsym != lsym_form_feed &&
+	*lsym != lsym_comment && !transient_state.search_brace) {
 	ps = transient_state;
     }
 }
 
 static void
-search_brace(token_type *ttype, bool *force_nl,
+search_brace(lexer_symbol *lsym, bool *force_nl,
     bool *comment_buffered, bool *last_else)
 {
     while (ps.search_brace) {
-	switch (*ttype) {
-	case newline:
+	switch (*lsym) {
+	case lsym_newline:
 	    search_brace_newline(force_nl);
 	    break;
-	case tt_lex_form_feed:
+	case lsym_form_feed:
 	    break;
-	case comment:
+	case lsym_comment:
 	    search_brace_comment(comment_buffered);
 	    break;
-	case lbrace:
+	case lsym_lbrace:
 	    if (search_brace_lbrace())
 		goto switch_buffer;
 	    /* FALLTHROUGH */
 	default:		/* it is the start of a normal statement */
-	    if (!search_brace_other(*ttype, force_nl,
+	    if (!search_brace_other(*lsym, force_nl,
 		    *comment_buffered, *last_else))
 		return;
     switch_buffer:
 	    switch_buffer();
 	}
-	search_brace_lookahead(ttype);
+	search_brace_lookahead(lsym);
     }
 
     *last_else = false;
@@ -443,9 +443,9 @@ main_init_globals(void)
 {
     found_err = false;
 
-    ps.s_ttype[0] = stmt;
+    ps.s_sym[0] = psym_stmt;
     ps.last_nl = true;
-    ps.last_token = semicolon;
+    ps.last_token = lsym_semicolon;
     buf_init(&com);
     buf_init(&lab);
     buf_init(&code);
@@ -581,7 +581,7 @@ main_prepare_parsing(void)
 {
     inbuf_read_line();
 
-    parse(semicolon);
+    parse(psym_semicolon);
 
     int ind = 0;
     for (const char *p = inp.s;; p++) {
@@ -647,11 +647,11 @@ process_end_of_file(void)
 }
 
 static void
-process_comment_in_code(token_type ttype, bool *force_nl)
+process_comment_in_code(lexer_symbol lsym, bool *force_nl)
 {
     if (*force_nl &&
-	ttype != semicolon &&
-	(ttype != lbrace || !opt.brace_same_line)) {
+	lsym != lsym_semicolon &&
+	(lsym != lsym_lbrace || !opt.brace_same_line)) {
 
 	/* we should force a broken line here */
 	if (opt.verbose)
@@ -684,7 +684,7 @@ process_form_feed(void)
 static void
 process_newline(void)
 {
-    if (ps.last_token == comma && ps.p_l_follow == 0 && !ps.block_init &&
+    if (ps.last_token == lsym_comma && ps.p_l_follow == 0 && !ps.block_init &&
 	!opt.break_after_comma && break_comma &&
 	com.s == com.e)
 	goto stay_in_line;
@@ -701,9 +701,9 @@ want_blank_before_lparen(void)
 {
     if (!ps.want_blank)
 	return false;
-    if (ps.last_token == rparen_or_rbracket)
+    if (ps.last_token == lsym_rparen_or_rbracket)
 	return false;
-    if (ps.last_token != ident && ps.last_token != funcname)
+    if (ps.last_token != lsym_ident && ps.last_token != lsym_funcname)
 	return true;
     if (opt.proc_calls_space)
 	return true;
@@ -748,7 +748,7 @@ process_lparen_or_lbracket(int decl_ind,
 	 * this is a kluge to make sure that declarations will be aligned
 	 * right if proc decl has an explicit type on it, i.e. "int a(x) {..."
 	 */
-	parse(semicolon);	/* I said this was a kluge... */
+	parse(psym_semicolon);	/* I said this was a kluge... */
 	ps.init_or_struct = false;
     }
 
@@ -758,8 +758,7 @@ process_lparen_or_lbracket(int decl_ind,
 }
 
 static void
-process_rparen_or_rbracket(bool *sp_sw, bool *force_nl,
-    token_type hd_type)
+process_rparen_or_rbracket(bool *sp_sw, bool *force_nl, stmt_head hd)
 {
     if ((ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) != 0) {
 	ps.next_unary = true;
@@ -786,7 +785,7 @@ process_rparen_or_rbracket(bool *sp_sw, 
 	ps.next_unary = true;
 	ps.in_stmt = false;	/* don't use stmt continuation indentation */
 
-	parse(hd_type);		/* let parser worry about if, or whatever */
+	parse_hd(hd);		/* let parser worry about if, or whatever */
     }
 
     /*
@@ -870,15 +869,13 @@ process_colon(int *quest_level, bool *fo
 
 static void
 process_semicolon(bool *seen_case, int *quest_level, int decl_ind,
-    bool tabs_to_var, bool *sp_sw,
-    token_type hd_type,
-    bool *force_nl)
+    bool tabs_to_var, bool *sp_sw, stmt_head hd, bool *force_nl)
 {
     if (ps.decl_nest == 0)
 	ps.init_or_struct = false;
     *seen_case = false;		/* these will only need resetting in an error */
     *quest_level = 0;
-    if (ps.last_token == rparen_or_rbracket)
+    if (ps.last_token == lsym_rparen_or_rbracket)
 	ps.in_parameter_declaration = false;
     ps.cast_mask = 0;
     ps.not_cast_mask = 0;
@@ -897,7 +894,7 @@ process_semicolon(bool *seen_case, int *
 					 * structure declaration, we aren't
 					 * anymore */
 
-    if ((!*sp_sw || hd_type != for_exprs) && ps.p_l_follow > 0) {
+    if ((!*sp_sw || hd != hd_for) && ps.p_l_follow > 0) {
 
 	/*
 	 * There were unbalanced parens in the statement. It is a bit
@@ -908,7 +905,7 @@ process_semicolon(bool *seen_case, int *
 	if (*sp_sw) {		/* this is a check for an if, while, etc. with
 				 * unbalanced parens */
 	    *sp_sw = false;
-	    parse(hd_type);	/* don't lose the 'if', or whatever */
+	    parse_hd(hd);	/* don't lose the 'if', or whatever */
 	}
     }
     *code.e++ = ';';
@@ -917,13 +914,13 @@ process_semicolon(bool *seen_case, int *
 					 * stmt */
 
     if (!*sp_sw) {		/* if not if for (;;) */
-	parse(semicolon);	/* let parser know about end of stmt */
+	parse(psym_semicolon);	/* let parser know about end of stmt */
 	*force_nl = true;	/* force newline after an end of stmt */
     }
 }
 
 static void
-process_lbrace(bool *force_nl, bool *sp_sw, token_type hd_type,
+process_lbrace(bool *force_nl, bool *sp_sw, stmt_head hd,
     int *di_stack, int di_stack_cap, int *decl_ind)
 {
     ps.in_stmt = false;		/* don't indent the {} */
@@ -959,7 +956,7 @@ process_lbrace(bool *force_nl, bool *sp_
 	ps.p_l_follow = 0;
 	if (*sp_sw) {		/* check for unclosed if, for, etc. */
 	    *sp_sw = false;
-	    parse(hd_type);
+	    parse_hd(hd);
 	    ps.ind_level = ps.ind_level_follow;
 	}
     }
@@ -984,7 +981,7 @@ process_lbrace(bool *force_nl, bool *sp_
     }
 
     *decl_ind = 0;
-    parse(lbrace);
+    parse(psym_lbrace);
     if (ps.want_blank)
 	*code.e++ = ' ';
     ps.want_blank = false;
@@ -995,10 +992,10 @@ process_lbrace(bool *force_nl, bool *sp_
 static void
 process_rbrace(bool *sp_sw, int *decl_ind, const int *di_stack)
 {
-    if (ps.s_ttype[ps.tos] == decl && !ps.block_init)	/* semicolons can be
-							 * omitted in
-							 * declarations */
-	parse(semicolon);
+    if (ps.s_sym[ps.tos] == psym_decl && !ps.block_init) {
+	/* semicolons can be omitted in declarations */
+	parse(psym_semicolon);
+    }
 
     if (ps.p_l_follow != 0) {	/* check for unclosed if, for, else. */
 	diag(1, "Unbalanced parens");
@@ -1030,9 +1027,9 @@ process_rbrace(bool *sp_sw, int *decl_in
     }
 
     blank_line_before = false;
-    parse(rbrace);		/* let parser know about this */
+    parse(psym_rbrace);
     ps.search_brace = opt.cuddle_else
-	&& ps.s_ttype[ps.tos] == if_expr_stmt
+	&& ps.s_sym[ps.tos] == psym_if_expr_stmt
 	&& ps.s_ind_level[ps.tos] >= ps.ind_level;
 
     if (ps.tos <= 1 && opt.blanklines_after_procs && ps.decl_nest <= 0)
@@ -1053,7 +1050,7 @@ process_keyword_do(bool *force_nl, bool 
 
     *force_nl = true;		/* following stuff must go onto new line */
     *last_else = false;
-    parse(tt_ps_do);
+    parse(psym_do);
 }
 
 static void
@@ -1070,15 +1067,15 @@ process_keyword_else(bool *force_nl, boo
 
     *force_nl = true;		/* following stuff must go onto new line */
     *last_else = true;
-    parse(tt_ps_else);
+    parse(psym_else);
 }
 
 static void
 process_decl(int *decl_ind, bool *tabs_to_var)
 {
-    parse(decl);		/* let parser worry about indentation */
+    parse(psym_decl);		/* let the parser worry about indentation */
 
-    if (ps.last_token == rparen_or_rbracket && ps.tos <= 1) {
+    if (ps.last_token == lsym_rparen_or_rbracket && ps.tos <= 1) {
 	if (code.s != code.e) {
 	    dump_line();
 	    ps.want_blank = false;
@@ -1092,7 +1089,7 @@ process_decl(int *decl_ind, bool *tabs_t
     }
 
     ps.init_or_struct = /* maybe */ true;
-    ps.in_decl = ps.decl_on_line = ps.last_token != type_def;
+    ps.in_decl = ps.decl_on_line = ps.last_token != lsym_typedef;
     if (ps.decl_nest <= 0)
 	ps.just_saw_decl = 2;
 
@@ -1107,11 +1104,11 @@ process_decl(int *decl_ind, bool *tabs_t
 }
 
 static void
-process_ident(token_type ttype, int decl_ind, bool tabs_to_var,
-    bool *sp_sw, bool *force_nl, token_type hd_type)
+process_ident(lexer_symbol lsym, int decl_ind, bool tabs_to_var,
+    bool *sp_sw, bool *force_nl, stmt_head hd)
 {
     if (ps.in_decl) {
-	if (ttype == funcname) {
+	if (lsym == lsym_funcname) {
 	    ps.in_decl = false;
 	    if (opt.procnames_start_line && code.s != code.e) {
 		*code.e = '\0';
@@ -1134,7 +1131,7 @@ process_ident(token_type ttype, int decl
 	*force_nl = true;
 	ps.next_unary = true;
 	ps.in_stmt = false;
-	parse(hd_type);
+	parse_hd(hd);
     }
 }
 
@@ -1336,7 +1333,7 @@ main_loop(void)
     bool tabs_to_var = false;	/* true if using tabs to indent to var name */
     bool sp_sw = false;		/* when true, we are in the expression of
 				 * if(...), while(...), etc. */
-    token_type hd_type = end_of_file;	/* the type of statement for if (...),
+    stmt_head hd = hd_0;	/* the type of statement for if (...),
 				 * for (...), etc */
     int quest_level = 0;	/* when this is positive, we have seen a '?'
 				 * without the matching ':' in a '?:'
@@ -1350,7 +1347,7 @@ main_loop(void)
 				 * reach eof */
 	bool comment_buffered = false;
 
-	token_type ttype = lexi(&ps);	/* Read the next token.  The actual
+	lexer_symbol lsym = lexi(&ps);	/* Read the next token.  The actual
 					 * characters read are stored in
 					 * "token". */
 
@@ -1360,148 +1357,146 @@ main_loop(void)
 	 * proper handling of both kinds of brace placement (-br, -bl) and
 	 * cuddling "else" (-ce).
 	 */
-	search_brace(&ttype, &force_nl, &comment_buffered, &last_else);
+	search_brace(&lsym, &force_nl, &comment_buffered, &last_else);
 
-	if (ttype == end_of_file) {
+	if (lsym == lsym_eof) {
 	    process_end_of_file();
 	    /* NOTREACHED */
 	}
 
-	if (ttype == newline || ttype == tt_lex_form_feed ||
-		ttype == preprocessing)
+	if (lsym == lsym_newline || lsym == lsym_form_feed ||
+		lsym == lsym_preprocessing)
 	    force_nl = false;
-	else if (ttype != comment)
-	    process_comment_in_code(ttype, &force_nl);
+	else if (lsym != lsym_comment)
+	    process_comment_in_code(lsym, &force_nl);
 
 	buf_reserve(&code, 3);	/* space for 2 characters plus '\0' */
 
-	switch (ttype) {
+	switch (lsym) {
 
-	case tt_lex_form_feed:
+	case lsym_form_feed:
 	    process_form_feed();
 	    break;
 
-	case newline:
+	case lsym_newline:
 	    process_newline();
 	    break;
 
-	case lparen_or_lbracket:
+	case lsym_lparen_or_lbracket:
 	    process_lparen_or_lbracket(decl_ind, tabs_to_var, sp_sw);
 	    break;
 
-	case rparen_or_rbracket:
-	    process_rparen_or_rbracket(&sp_sw, &force_nl, hd_type);
+	case lsym_rparen_or_rbracket:
+	    process_rparen_or_rbracket(&sp_sw, &force_nl, hd);
 	    break;
 
-	case unary_op:
+	case lsym_unary_op:
 	    process_unary_op(decl_ind, tabs_to_var);
 	    break;
 
-	case binary_op:
+	case lsym_binary_op:
 	    process_binary_op();
 	    break;
 
-	case postfix_op:
+	case lsym_postfix_op:
 	    process_postfix_op();
 	    break;
 
-	case question:
+	case lsym_question:
 	    process_question(&quest_level);
 	    break;
 
-	case case_label:	/* got word 'case' or 'default' */
+	case lsym_case_label:	/* got word 'case' or 'default' */
 	    seen_case = true;
 	    goto copy_token;
 
-	case colon:
+	case lsym_colon:
 	    process_colon(&quest_level, &force_nl, &seen_case);
 	    break;
 
-	case semicolon:
+	case lsym_semicolon:
 	    process_semicolon(&seen_case, &quest_level, decl_ind, tabs_to_var,
-		&sp_sw, hd_type, &force_nl);
+		&sp_sw, hd, &force_nl);
 	    break;
 
-	case lbrace:
-	    process_lbrace(&force_nl, &sp_sw, hd_type, di_stack,
+	case lsym_lbrace:
+	    process_lbrace(&force_nl, &sp_sw, hd, di_stack,
 		(int)array_length(di_stack), &decl_ind);
 	    break;
 
-	case rbrace:
+	case lsym_rbrace:
 	    process_rbrace(&sp_sw, &decl_ind, di_stack);
 	    break;
 
-	case switch_expr:	/* got keyword "switch" */
-	    sp_sw = true;
-	    hd_type = switch_expr;	/* keep this for when we have seen the
-					 * expression */
-	    goto copy_token;
-
-	case tt_lex_for:
+	case lsym_switch:
 	    sp_sw = true;	/* the interesting stuff is done after the
 				 * expressions are scanned */
-	    hd_type = for_exprs;	/* remember the type of header for
-					 * later use by parser */
+	    hd = hd_switch;	/* remember the type of header for later use
+				 * by parser */
+	    goto copy_token;
+
+	case lsym_for:
+	    sp_sw = true;
+	    hd = hd_for;
 	    goto copy_token;
 
-	case tt_lex_if:
+	case lsym_if:
 	    sp_sw = true;
-	    hd_type = if_expr;
+	    hd = hd_if;
 	    goto copy_token;
 
-	case tt_lex_while:
+	case lsym_while:
 	    sp_sw = true;
-	    hd_type = while_expr;
+	    hd = hd_while;
 	    goto copy_token;
 
-	case tt_lex_do:
+	case lsym_do:
 	    process_keyword_do(&force_nl, &last_else);
 	    goto copy_token;
 
-	case tt_lex_else:
+	case lsym_else:
 	    process_keyword_else(&force_nl, &last_else);
 	    goto copy_token;
 
-	case type_def:
-	case storage_class:
+	case lsym_typedef:
+	case lsym_storage_class:
 	    blank_line_before = false;
 	    goto copy_token;
 
-	case keyword_struct_union_enum:
+	case lsym_tag:
 	    if (ps.p_l_follow > 0)
 		goto copy_token;
 	    /* FALLTHROUGH */
-	case decl:		/* a declaration type (int, etc.) */
+	case lsym_type:
 	    process_decl(&decl_ind, &tabs_to_var);
 	    goto copy_token;
 
-	case funcname:
-	case ident:		/* an identifier, constant or string */
-	    process_ident(ttype, decl_ind, tabs_to_var, &sp_sw, &force_nl,
-		hd_type);
+	case lsym_funcname:
+	case lsym_ident:	/* an identifier, constant or string */
+	    process_ident(lsym, decl_ind, tabs_to_var, &sp_sw, &force_nl, hd);
     copy_token:
 	    copy_token();
-	    if (ttype != funcname)
+	    if (lsym != lsym_funcname)
 		ps.want_blank = true;
 	    break;
 
-	case string_prefix:
+	case lsym_string_prefix:
 	    process_string_prefix();
 	    break;
 
-	case period:
+	case lsym_period:
 	    process_period();
 	    break;
 
-	case comma:
+	case lsym_comma:
 	    process_comma(decl_ind, tabs_to_var, &force_nl);
 	    break;
 
-	case preprocessing:	/* the initial '#' */
+	case lsym_preprocessing:	/* the initial '#' */
 	    process_preprocessing();
 	    break;
 
-	case comment:		/* the initial '/' '*' or '//' of a comment */
+	case lsym_comment:	/* the initial '/' '*' or '//' of a comment */
 	    process_comment();
 	    break;
 
@@ -1510,8 +1505,9 @@ main_loop(void)
 	}
 
 	*code.e = '\0';
-	if (ttype != comment && ttype != newline && ttype != preprocessing)
-	    ps.last_token = ttype;
+	if (lsym != lsym_comment && lsym != lsym_newline &&
+		lsym != lsym_preprocessing)
+	    ps.last_token = lsym;
     }
 }
 

Index: src/usr.bin/indent/indent.h
diff -u src/usr.bin/indent/indent.h:1.48 src/usr.bin/indent/indent.h:1.49
--- src/usr.bin/indent/indent.h:1.48	Sun Oct 24 22:44:13 2021
+++ src/usr.bin/indent/indent.h	Mon Oct 25 00:54:37 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: indent.h,v 1.48 2021/10/24 22:44:13 rillig Exp $	*/
+/*	$NetBSD: indent.h,v 1.49 2021/10/25 00:54:37 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -70,49 +70,65 @@ __FBSDID("$FreeBSD: head/usr.bin/indent/
 
 #include <stdbool.h>
 
-typedef enum token_type {
-    end_of_file,
-    newline,
-    lparen_or_lbracket,
-    rparen_or_rbracket,
-    unary_op,			/* e.g. '+' or '&' */
-    binary_op,			/* e.g. '<<' or '+' or '&&' or '/=' */
-    postfix_op,			/* trailing '++' or '--' */
-    question,			/* the '?' from a '?:' expression */
-    case_label,
-    colon,
-    semicolon,
-    lbrace,
-    rbrace,
-    ident,			/* identifier, constant or string */
-    comma,
-    comment,
-    switch_expr,		/* 'switch' '(' <expr> ')' */
-    preprocessing,		/* '#' */
-    tt_lex_form_feed,
-    decl,
-    tt_lex_for,
-    tt_lex_if,
-    tt_lex_while,
-    tt_lex_do,
-    tt_lex_else,
-    if_expr,			/* 'if' '(' <expr> ')' */
-    while_expr,			/* 'while' '(' <expr> ')' */
-    for_exprs,			/* 'for' '(' ... ')' */
-    stmt,
-    stmt_list,
-    tt_ps_else,
-    tt_ps_do,
-    do_stmt,			/* 'do' <stmt> */
-    if_expr_stmt,		/* 'if' '(' <expr> ')' <stmt> */
-    if_expr_stmt_else,		/* 'if' '(' <expr> ')' <stmt> 'else' */
-    period,
-    string_prefix,		/* 'L' */
-    storage_class,
-    funcname,
-    type_def,
-    keyword_struct_union_enum
-} token_type;
+typedef enum lexer_symbol {
+    lsym_eof,
+    lsym_preprocessing,		/* '#' */
+    lsym_newline,
+    lsym_form_feed,
+    lsym_comment,
+    lsym_lparen_or_lbracket,
+    lsym_rparen_or_rbracket,
+    lsym_lbrace,
+    lsym_rbrace,
+    lsym_period,
+    lsym_unary_op,		/* e.g. '+' or '&' */
+    lsym_binary_op,		/* e.g. '<<' or '+' or '&&' or '/=' */
+    lsym_postfix_op,		/* trailing '++' or '--' */
+    lsym_question,		/* the '?' from a '?:' expression */
+    lsym_colon,
+    lsym_comma,
+    lsym_semicolon,
+    lsym_typedef,
+    lsym_storage_class,
+    lsym_type,
+    lsym_tag,			/* 'struct', 'union', 'enum' */
+    lsym_case_label,
+    lsym_string_prefix,		/* 'L' */
+    lsym_ident,			/* identifier, constant or string */
+    lsym_funcname,
+    lsym_do,
+    lsym_else,
+    lsym_for,
+    lsym_if,
+    lsym_switch,
+    lsym_while,
+} lexer_symbol;
+
+typedef enum parser_symbol {
+    psym_semicolon,		/* rather a placeholder than a semicolon */
+    psym_lbrace,
+    psym_rbrace,
+    psym_decl,
+    psym_stmt,
+    psym_stmt_list,
+    psym_for_exprs,		/* 'for' '(' ... ')' */
+    psym_if_expr,		/* 'if' '(' expr ')' */
+    psym_if_expr_stmt,		/* 'if' '(' expr ')' stmt */
+    psym_if_expr_stmt_else,	/* 'if' '(' expr ')' stmt 'else' */
+    psym_else,			/* 'else' */
+    psym_switch_expr,		/* 'switch' '(' expr ')' */
+    psym_do,			/* 'do' */
+    psym_do_stmt,		/* 'do' stmt */
+    psym_while_expr,		/* 'while' '(' expr ')' */
+} parser_symbol;
+
+typedef enum stmt_head {
+    hd_0,			/* placeholder for uninitialized */
+    hd_for,
+    hd_if,
+    hd_switch,
+    hd_while,
+} stmt_head;
 
 #define sc_size 5000		/* size of save_com buffer */
 #define label_offset 2		/* number of levels a label is placed to left
@@ -257,10 +273,10 @@ extern bool inhibit_formatting;	/* true 
 
 /* TODO: group the members by purpose, don't sort them alphabetically */
 extern struct parser_state {
-    token_type last_token;
+    lexer_symbol last_token;
 
     int tos;			/* pointer to top of stack */
-    token_type s_ttype[STACKSIZE];
+    parser_symbol s_sym[STACKSIZE];
     int s_ind_level[STACKSIZE];
     float s_case_ind_level[STACKSIZE];
 
@@ -344,7 +360,6 @@ debug_vis_range(const char *, const char
     const char *);
 void debug_printf(const char *, ...)__printflike(1, 2);
 void debug_println(const char *, ...)__printflike(1, 2);
-const char *token_type_name(token_type);
 #else
 #define		debug_printf(fmt, ...) do { } while (false)
 #define		debug_println(fmt, ...) do { } while (false)
@@ -352,12 +367,13 @@ const char *token_type_name(token_type);
 #endif
 void inbuf_skip(void);
 char inbuf_next(void);
-token_type lexi(struct parser_state *);
+lexer_symbol lexi(struct parser_state *);
 void diag(int, const char *, ...)__printflike(2, 3);
 void dump_line(void);
 void dump_line_ff(void);
 void inbuf_read_line(void);
-void parse(token_type);
+void parse(parser_symbol);
+void parse_hd(stmt_head);
 void process_comment(void);
 void set_option(const char *, const char *);
 void load_profiles(const char *);

Index: src/usr.bin/indent/lexi.c
diff -u src/usr.bin/indent/lexi.c:1.99 src/usr.bin/indent/lexi.c:1.100
--- src/usr.bin/indent/lexi.c:1.99	Sun Oct 24 22:44:13 2021
+++ src/usr.bin/indent/lexi.c	Mon Oct 25 00:54:37 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: lexi.c,v 1.99 2021/10/24 22:44:13 rillig Exp $	*/
+/*	$NetBSD: lexi.c,v 1.100 2021/10/25 00:54:37 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
@@ -43,7 +43,7 @@ static char sccsid[] = "@(#)lexi.c	8.1 (
 
 #include <sys/cdefs.h>
 #if defined(__NetBSD__)
-__RCSID("$NetBSD: lexi.c,v 1.99 2021/10/24 22:44:13 rillig Exp $");
+__RCSID("$NetBSD: lexi.c,v 1.100 2021/10/25 00:54:37 rillig Exp $");
 #elif defined(__FreeBSD__)
 __FBSDID("$FreeBSD: head/usr.bin/indent/lexi.c 337862 2018-08-15 18:19:45Z pstef $");
 #endif
@@ -218,26 +218,46 @@ cmp_keyword_by_name(const void *key, con
 }
 
 #ifdef debug
-const char *
-token_type_name(token_type ttype)
+static const char *
+lsym_name(lexer_symbol sym)
 {
     static const char *const name[] = {
-	"end_of_file", "newline", "lparen_or_lbracket", "rparen_or_rbracket",
-	"unary_op", "binary_op", "postfix_op", "question",
-	"case_label", "colon",
-	"semicolon", "lbrace", "rbrace", "ident", "comma",
-	"comment", "switch_expr", "preprocessing", "tt_lex_form_feed", "decl",
-	"tt_lex_for", "tt_lex_if", "tt_lex_while", "tt_lex_do", "tt_lex_else",
-	"if_expr", "while_expr", "for_exprs",
-	"stmt", "stmt_list", "tt_ps_else", "tt_ps_do", "do_stmt",
-	"if_expr_stmt", "if_expr_stmt_else", "period", "string_prefix",
-	"storage_class", "funcname", "type_def", "keyword_struct_union_enum"
+	"eof",
+	"preprocessing",
+	"newline",
+	"form_feed",
+	"comment",
+	"lparen_or_lbracket",
+	"rparen_or_rbracket",
+	"lbrace",
+	"rbrace",
+	"period",
+	"unary_op",
+	"binary_op",
+	"postfix_op",
+	"question",
+	"colon",
+	"comma",
+	"semicolon",
+	"typedef",
+	"storage_class",
+	"type",
+	"tag",
+	"case_label",
+	"string_prefix",
+	"ident",
+	"funcname",
+	"do",
+	"else",
+	"for",
+	"if",
+	"switch",
+	"while",
     };
 
-    assert(0 <= ttype && ttype < array_length(name));
-    assert(array_length(name) == (int)keyword_struct_union_enum + 1);
+    assert(array_length(name) == (int)lsym_while + 1);
 
-    return name[ttype];
+    return name[sym];
 }
 
 static void
@@ -250,12 +270,12 @@ debug_print_buf(const char *name, const 
 }
 #endif
 
-static token_type
-lexi_end(token_type ttype)
+static lexer_symbol
+lexi_end(lexer_symbol lsym)
 {
 #ifdef debug
     debug_printf("in line %d, lexi returns '%s'",
-	line_no, token_type_name(ttype));
+	line_no, lsym_name(lsym));
     debug_print_buf("token", &token);
     debug_print_buf("label", &lab);
     debug_print_buf("code", &code);
@@ -263,7 +283,7 @@ lexi_end(token_type ttype)
     debug_printf("\n");
 #endif
 
-    return ttype;
+    return lsym;
 }
 
 static void
@@ -343,9 +363,9 @@ probably_typename(const struct parser_st
 	goto maybe;
     return false;
 maybe:
-    return state->last_token == semicolon ||
-	state->last_token == lbrace ||
-	state->last_token == rbrace;
+    return state->last_token == lsym_semicolon ||
+	state->last_token == lsym_lbrace ||
+	state->last_token == lsym_rbrace;
 }
 
 static int
@@ -379,13 +399,13 @@ is_typename(void)
 }
 
 /* Read an alphanumeric token into 'token', or return end_of_file. */
-static token_type
+static lexer_symbol
 lexi_alnum(struct parser_state *state)
 {
     if (!(isalnum((unsigned char)*inp.s) ||
 	    *inp.s == '_' || *inp.s == '$' ||
 	    (inp.s[0] == '.' && isdigit((unsigned char)inp.s[1]))))
-	return end_of_file;	/* just as a placeholder */
+	return lsym_eof;	/* just as a placeholder */
 
     if (isdigit((unsigned char)*inp.s) ||
 	(inp.s[0] == '.' && isdigit((unsigned char)inp.s[1]))) {
@@ -397,20 +417,20 @@ lexi_alnum(struct parser_state *state)
 
     if (token.s[0] == 'L' && token.s[1] == '\0' &&
 	(*inp.s == '"' || *inp.s == '\''))
-	return string_prefix;
+	return lsym_string_prefix;
 
     while (is_hspace(inbuf_peek()))
 	inbuf_skip();
     state->keyword = kw_0;
 
-    if (state->last_token == keyword_struct_union_enum &&
+    if (state->last_token == lsym_tag &&
 	    state->p_l_follow == 0) {
 	state->next_unary = true;
-	return decl;
+	return lsym_type;
     }
 
     /* Operator after identifier is binary unless last token was 'struct'. */
-    state->next_unary = state->last_token == keyword_struct_union_enum;
+    state->next_unary = state->last_token == lsym_tag;
 
     const struct keyword *kw = bsearch(token.s, keywords,
 	array_length(keywords), sizeof(keywords[0]), cmp_keyword_by_name);
@@ -427,10 +447,10 @@ lexi_alnum(struct parser_state *state)
 
 	switch (kw->kind) {
 	case kw_switch:
-	    return switch_expr;
+	    return lsym_switch;
 
 	case kw_case_or_default:
-	    return case_label;
+	    return lsym_case_label;
 
 	case kw_struct_or_union_or_enum:
 	case kw_type:
@@ -439,40 +459,41 @@ lexi_alnum(struct parser_state *state)
 		/* inside parens: cast, param list, offsetof or sizeof */
 		state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask;
 	    }
-	    if (state->last_token == period || state->last_token == unary_op) {
+	    if (state->last_token == lsym_period ||
+		    state->last_token == lsym_unary_op) {
 		state->keyword = kw_0;
 		break;
 	    }
 	    if (kw != NULL && kw->kind == kw_struct_or_union_or_enum)
-		return keyword_struct_union_enum;
+		return lsym_tag;
 	    if (state->p_l_follow != 0)
 		break;
-	    return decl;
+	    return lsym_type;
 
 	case kw_for:
-	    return tt_lex_for;
+	    return lsym_for;
 
 	case kw_if:
-	    return tt_lex_if;
+	    return lsym_if;
 
 	case kw_while:
-	    return tt_lex_while;
+	    return lsym_while;
 
 	case kw_do:
-	    return tt_lex_do;
+	    return lsym_do;
 
 	case kw_else:
-	    return tt_lex_else;
+	    return lsym_else;
 
 	case kw_storage_class:
-	    return storage_class;
+	    return lsym_storage_class;
 
 	case kw_typedef:
-	    return type_def;
+	    return lsym_typedef;
 
 	default:		/* all others are treated like any other
 				 * identifier */
-	    return ident;
+	    return lsym_ident;
 	}
     }
 
@@ -486,24 +507,24 @@ lexi_alnum(struct parser_state *state)
 	strncpy(state->procname, token.s, sizeof state->procname - 1);
 	if (state->in_decl)
 	    state->in_parameter_declaration = true;
-	return funcname;
+	return lsym_funcname;
 not_proc:;
 
     } else if (probably_typename(state)) {
 	state->keyword = kw_type;
 	state->next_unary = true;
-	return decl;
+	return lsym_type;
     }
 
-    if (state->last_token == decl)	/* if this is a declared variable,
+    if (state->last_token == lsym_type)	/* if this is a declared variable,
 					 * then following sign is unary */
 	state->next_unary = true;	/* will make "int a -1" work */
 
-    return ident;		/* the ident is not in the list */
+    return lsym_ident;		/* the ident is not in the list */
 }
 
 /* Reads the next token, placing it in the global variable "token". */
-token_type
+lexer_symbol
 lexi(struct parser_state *state)
 {
     token.e = token.s;
@@ -515,9 +536,9 @@ lexi(struct parser_state *state)
 	inbuf_skip();
     }
 
-    token_type alnum_ttype = lexi_alnum(state);
-    if (alnum_ttype != end_of_file)
-	return lexi_end(alnum_ttype);
+    lexer_symbol alnum_lsym = lexi_alnum(state);
+    if (alnum_lsym != lsym_eof)
+	return lexi_end(alnum_lsym);
 
     /* Scan a non-alphanumeric token */
 
@@ -525,7 +546,7 @@ lexi(struct parser_state *state)
     *token.e++ = inbuf_next();
     *token.e = '\0';
 
-    token_type ttype;
+    lexer_symbol lsym;
     bool unary_delim = false;	/* whether the current token forces a
 				 * following operator to be unary */
 
@@ -534,83 +555,83 @@ lexi(struct parser_state *state)
 	unary_delim = state->next_unary;
 	state->last_nl = true;	/* remember that we just had a newline */
 	/* if data has been exhausted, the newline is a dummy. */
-	ttype = had_eof ? end_of_file : newline;
+	lsym = had_eof ? lsym_eof : lsym_newline;
 	break;
 
     case '\'':
     case '"':
 	lex_char_or_string();
-	ttype = ident;
+	lsym = lsym_ident;
 	break;
 
     case '(':
     case '[':
 	unary_delim = true;
-	ttype = lparen_or_lbracket;
+	lsym = lsym_lparen_or_lbracket;
 	break;
 
     case ')':
     case ']':
-	ttype = rparen_or_rbracket;
+	lsym = lsym_rparen_or_rbracket;
 	break;
 
     case '#':
 	unary_delim = state->next_unary;
-	ttype = preprocessing;
+	lsym = lsym_preprocessing;
 	break;
 
     case '?':
 	unary_delim = true;
-	ttype = question;
+	lsym = lsym_question;
 	break;
 
     case ':':
-	ttype = colon;
+	lsym = lsym_colon;
 	unary_delim = true;
 	break;
 
     case ';':
 	unary_delim = true;
-	ttype = semicolon;
+	lsym = lsym_semicolon;
 	break;
 
     case '{':
 	unary_delim = true;
-	ttype = lbrace;
+	lsym = lsym_lbrace;
 	break;
 
     case '}':
 	unary_delim = true;
-	ttype = rbrace;
+	lsym = lsym_rbrace;
 	break;
 
     case '\f':
 	unary_delim = state->next_unary;
 	state->last_nl = true;	/* remember this, so we can set 'state->col_1'
 				 * right */
-	ttype = tt_lex_form_feed;
+	lsym = lsym_form_feed;
 	break;
 
     case ',':
 	unary_delim = true;
-	ttype = comma;
+	lsym = lsym_comma;
 	break;
 
     case '.':
 	unary_delim = false;
-	ttype = period;
+	lsym = lsym_period;
 	break;
 
     case '-':
     case '+':
-	ttype = state->next_unary ? unary_op : binary_op;
+	lsym = state->next_unary ? lsym_unary_op : lsym_binary_op;
 	unary_delim = true;
 
 	if (*inp.s == token.s[0]) {	/* ++, -- */
 	    *token.e++ = *inp.s++;
-	    if (state->last_token == ident ||
-		    state->last_token == rparen_or_rbracket) {
-		ttype = state->next_unary ? unary_op : postfix_op;
+	    if (state->last_token == lsym_ident ||
+		    state->last_token == lsym_rparen_or_rbracket) {
+		lsym = state->next_unary ? lsym_unary_op : lsym_postfix_op;
 		unary_delim = false;
 	    }
 
@@ -620,7 +641,7 @@ lexi(struct parser_state *state)
 	} else if (*inp.s == '>') {	/* -> */
 	    *token.e++ = *inp.s++;
 	    unary_delim = false;
-	    ttype = unary_op;
+	    lsym = lsym_unary_op;
 	    state->want_blank = false;
 	}
 	break;
@@ -632,7 +653,7 @@ lexi(struct parser_state *state)
 	    *token.e++ = *inp.s++;
 	    *token.e = '\0';
 	}
-	ttype = binary_op;
+	lsym = lsym_binary_op;
 	unary_delim = true;
 	break;
 
@@ -643,7 +664,7 @@ lexi(struct parser_state *state)
 	    *token.e++ = inbuf_next();
 	if (*inp.s == '=')
 	    *token.e++ = *inp.s++;
-	ttype = state->next_unary ? unary_op : binary_op;
+	lsym = state->next_unary ? lsym_unary_op : lsym_binary_op;
 	unary_delim = true;
 	break;
 
@@ -652,7 +673,7 @@ lexi(struct parser_state *state)
 	if (!state->next_unary) {
 	    if (*inp.s == '=')
 		*token.e++ = *inp.s++;
-	    ttype = binary_op;
+	    lsym = lsym_binary_op;
 	    break;
 	}
 
@@ -674,7 +695,7 @@ lexi(struct parser_state *state)
 		ps.procname[0] = ' ';
 	}
 
-	ttype = unary_op;
+	lsym = lsym_unary_op;
 	break;
 
     default:
@@ -682,7 +703,7 @@ lexi(struct parser_state *state)
 	    /* it is start of comment */
 	    *token.e++ = inbuf_next();
 
-	    ttype = comment;
+	    lsym = lsym_comment;
 	    unary_delim = state->next_unary;
 	    break;
 	}
@@ -692,7 +713,7 @@ lexi(struct parser_state *state)
 	    token_add_char(inbuf_next());
 	}
 
-	ttype = state->next_unary ? unary_op : binary_op;
+	lsym = state->next_unary ? lsym_unary_op : lsym_binary_op;
 	unary_delim = true;
     }
 
@@ -704,7 +725,7 @@ lexi(struct parser_state *state)
     check_size_token(1);
     *token.e = '\0';
 
-    return lexi_end(ttype);
+    return lexi_end(lsym);
 }
 
 void

Index: src/usr.bin/indent/parse.c
diff -u src/usr.bin/indent/parse.c:1.38 src/usr.bin/indent/parse.c:1.39
--- src/usr.bin/indent/parse.c:1.38	Sun Oct 24 22:28:06 2021
+++ src/usr.bin/indent/parse.c	Mon Oct 25 00:54:37 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: parse.c,v 1.38 2021/10/24 22:28:06 rillig Exp $	*/
+/*	$NetBSD: parse.c,v 1.39 2021/10/25 00:54:37 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
@@ -48,6 +48,7 @@ __RCSID("$FreeBSD$");
 __FBSDID("$FreeBSD: head/usr.bin/indent/parse.c 337651 2018-08-11 19:20:06Z pstef $");
 #endif
 
+#include <assert.h>
 #include <err.h>
 #include <stdio.h>
 
@@ -55,40 +56,68 @@ __FBSDID("$FreeBSD: head/usr.bin/indent/
 
 static void reduce(void);
 
+#ifdef debug
+const char *
+psym_name(parser_symbol psym)
+{
+    static const char *const name[] = {
+	"semicolon",
+	"lbrace",
+	"rbrace",
+	"decl",
+	"stmt",
+	"stmt_list",
+	"for_exprs",
+	"if_expr",
+	"if_expr_stmt",
+	"if_expr_stmt_else",
+	"else",
+	"switch_expr",
+	"do",
+	"do_stmt",
+	"while_expr",
+    };
+
+    assert(array_length(name) == (int)psym_while_expr + 1);
+
+    return name[psym];
+}
+#endif
+
 /*
  * Shift the token onto the parser stack, or reduce it by combining it with
  * previous tokens.
  */
 void
-parse(token_type ttype)
+parse(parser_symbol psym)
 {
     debug_println("parse token: '%s' \"%s\"",
-	token_type_name(ttype), token.s);
+	psym_name(psym), token.s);
 
-    if (ttype != tt_ps_else) {
-	while (ps.s_ttype[ps.tos] == if_expr_stmt) {
-	    ps.s_ttype[ps.tos] = stmt;
+    if (psym != psym_else) {
+	while (ps.s_sym[ps.tos] == psym_if_expr_stmt) {
+	    ps.s_sym[ps.tos] = psym_stmt;
 	    reduce();
 	}
     }
 
-    switch (ttype) {
+    switch (psym) {
 
-    case decl:			/* scanned a declaration word */
+    case psym_decl:
 	ps.search_brace = opt.brace_same_line;
 	/* indicate that following brace should be on same line */
 
-	if (ps.s_ttype[ps.tos] != decl) {	/* only put one declaration
+	if (ps.s_sym[ps.tos] != psym_decl) {	/* only put one declaration
 						 * onto stack */
 	    break_comma = true;	/* while in declaration, newline should be
 				 * forced after comma */
-	    ps.s_ttype[++ps.tos] = decl;
+	    ps.s_sym[++ps.tos] = psym_decl;
 	    ps.s_ind_level[ps.tos] = ps.ind_level_follow;
 
 	    if (opt.ljust_decl) {
 		ps.ind_level = 0;
 		for (int i = ps.tos - 1; i > 0; --i)
-		    if (ps.s_ttype[i] == decl)
+		    if (ps.s_sym[i] == psym_decl)
 			++ps.ind_level;	/* indentation is number of
 					 * declaration levels deep we are */
 		ps.ind_level_follow = ps.ind_level;
@@ -96,8 +125,8 @@ parse(token_type ttype)
 	}
 	break;
 
-    case if_expr:		/* 'if' '(' <expr> ')' */
-	if (ps.s_ttype[ps.tos] == if_expr_stmt_else && opt.else_if) {
+    case psym_if_expr:		/* 'if' '(' <expr> ')' */
+	if (ps.s_sym[ps.tos] == psym_if_expr_stmt_else && opt.else_if) {
 	    /*
 	     * Reduce "else if" to "if". This saves a lot of stack space in
 	     * case of a long "if-else-if ... else-if" sequence.
@@ -105,18 +134,18 @@ parse(token_type ttype)
 	    ps.ind_level_follow = ps.s_ind_level[ps.tos--];
 	}
 	/* FALLTHROUGH */
-    case tt_ps_do:
-    case for_exprs:		/* 'for' (...) */
-	ps.s_ttype[++ps.tos] = ttype;
+    case psym_do:
+    case psym_for_exprs:		/* 'for' (...) */
+	ps.s_sym[++ps.tos] = psym;
 	ps.s_ind_level[ps.tos] = ps.ind_level = ps.ind_level_follow;
 	++ps.ind_level_follow;	/* subsequent statements should be indented 1 */
 	ps.search_brace = opt.brace_same_line;
 	break;
 
-    case lbrace:
+    case psym_lbrace:
 	break_comma = false;	/* don't break comma in an initializer list */
-	if (ps.s_ttype[ps.tos] == stmt || ps.s_ttype[ps.tos] == decl
-		|| ps.s_ttype[ps.tos] == stmt_list)
+	if (ps.s_sym[ps.tos] == psym_stmt || ps.s_sym[ps.tos] == psym_decl
+		|| ps.s_sym[ps.tos] == psym_stmt_list)
 	    ++ps.ind_level_follow;	/* it is a random, isolated stmt group
 					 * or a declaration */
 	else {
@@ -127,27 +156,28 @@ parse(token_type ttype)
 		/*
 		 * for a switch, brace should be two levels out from the code
 		 */
-		if (ps.s_ttype[ps.tos] == switch_expr && opt.case_indent >= 1)
+		if (ps.s_sym[ps.tos] == psym_switch_expr &&
+			opt.case_indent >= 1)
 		    --ps.ind_level;
 	    }
 	}
 
-	ps.s_ttype[++ps.tos] = lbrace;
+	ps.s_sym[++ps.tos] = psym_lbrace;
 	ps.s_ind_level[ps.tos] = ps.ind_level;
-	ps.s_ttype[++ps.tos] = stmt;
+	ps.s_sym[++ps.tos] = psym_stmt;
 	/* allow null stmt between braces */
 	ps.s_ind_level[ps.tos] = ps.ind_level_follow;
 	break;
 
-    case while_expr:		/* 'while' '(' <expr> ')' */
-	if (ps.s_ttype[ps.tos] == do_stmt) {
+    case psym_while_expr:	/* 'while' '(' <expr> ')' */
+	if (ps.s_sym[ps.tos] == psym_do_stmt) {
 	    /* it is matched with do stmt */
 	    ps.ind_level = ps.ind_level_follow = ps.s_ind_level[ps.tos];
-	    ps.s_ttype[++ps.tos] = while_expr;
+	    ps.s_sym[++ps.tos] = psym_while_expr;
 	    ps.s_ind_level[ps.tos] = ps.ind_level = ps.ind_level_follow;
 
 	} else {		/* it is a while loop */
-	    ps.s_ttype[++ps.tos] = while_expr;
+	    ps.s_sym[++ps.tos] = psym_while_expr;
 	    ps.s_ind_level[ps.tos] = ps.ind_level_follow;
 	    ++ps.ind_level_follow;
 	    ps.search_brace = opt.brace_same_line;
@@ -155,30 +185,30 @@ parse(token_type ttype)
 
 	break;
 
-    case tt_ps_else:
-	if (ps.s_ttype[ps.tos] != if_expr_stmt)
+    case psym_else:
+	if (ps.s_sym[ps.tos] != psym_if_expr_stmt)
 	    diag(1, "Unmatched 'else'");
 	else {
 	    /* The indentation for 'else' should be the same as for 'if'. */
 	    ps.ind_level = ps.s_ind_level[ps.tos];
 	    ps.ind_level_follow = ps.ind_level + 1;
-	    ps.s_ttype[ps.tos] = if_expr_stmt_else;
+	    ps.s_sym[ps.tos] = psym_if_expr_stmt_else;
 	    /* remember if with else */
 	    ps.search_brace = opt.brace_same_line || opt.else_if;
 	}
 	break;
 
-    case rbrace:
+    case psym_rbrace:
 	/* stack should have <lbrace> <stmt> or <lbrace> <stmt_list> */
-	if (ps.tos > 0 && ps.s_ttype[ps.tos - 1] == lbrace) {
+	if (ps.tos > 0 && ps.s_sym[ps.tos - 1] == psym_lbrace) {
 	    ps.ind_level = ps.ind_level_follow = ps.s_ind_level[--ps.tos];
-	    ps.s_ttype[ps.tos] = stmt;
+	    ps.s_sym[ps.tos] = psym_stmt;
 	} else
 	    diag(1, "Statement nesting error");
 	break;
 
-    case switch_expr:		/* had switch (...) */
-	ps.s_ttype[++ps.tos] = switch_expr;
+    case psym_switch_expr:	/* had switch (...) */
+	ps.s_sym[++ps.tos] = psym_switch_expr;
 	ps.s_case_ind_level[ps.tos] = case_ind;
 	/* save current case indent level */
 	ps.s_ind_level[ps.tos] = ps.ind_level_follow;
@@ -189,10 +219,10 @@ parse(token_type ttype)
 	ps.search_brace = opt.brace_same_line;
 	break;
 
-    case semicolon:		/* this indicates a simple stmt */
+    case psym_semicolon:	/* this indicates a simple stmt */
 	break_comma = false;	/* turn off flag to break after commas in a
 				 * declaration */
-	ps.s_ttype[++ps.tos] = stmt;
+	ps.s_sym[++ps.tos] = psym_stmt;
 	ps.s_ind_level[ps.tos] = ps.ind_level;
 	break;
 
@@ -209,14 +239,25 @@ parse(token_type ttype)
 #ifdef debug
     printf("parse stack:");
     for (int i = 1; i <= ps.tos; ++i)
-	printf(" ('%s' at %d)",
-	    token_type_name(ps.s_ttype[i]), ps.s_ind_level[i]);
+	printf(" ('%s' at %d)", psym_name(ps.s_sym[i]), ps.s_ind_level[i]);
     if (ps.tos == 0)
 	printf(" empty");
     printf("\n");
 #endif
 }
 
+void
+parse_hd(stmt_head hd)
+{
+    static const parser_symbol psym[] = {
+	[hd_for] = psym_for_exprs,
+	[hd_if] = psym_if_expr,
+	[hd_switch] = psym_switch_expr,
+	[hd_while] = psym_while_expr
+    };
+    parse(psym[hd]);
+}
+
 /*----------------------------------------------*\
 |   REDUCTION PHASE				 |
 \*----------------------------------------------*/
@@ -228,24 +269,24 @@ parse(token_type ttype)
 static bool
 reduce_stmt(void)
 {
-    switch (ps.s_ttype[ps.tos - 1]) {
+    switch (ps.s_sym[ps.tos - 1]) {
 
-    case stmt:			/* stmt stmt */
-    case stmt_list:		/* stmt_list stmt */
-	ps.s_ttype[--ps.tos] = stmt_list;
+    case psym_stmt:		/* stmt stmt */
+    case psym_stmt_list:	/* stmt_list stmt */
+	ps.s_sym[--ps.tos] = psym_stmt_list;
 	return true;
 
-    case tt_ps_do:		/* 'do' <stmt> */
-	ps.s_ttype[--ps.tos] = do_stmt;
+    case psym_do:		/* 'do' <stmt> */
+	ps.s_sym[--ps.tos] = psym_do_stmt;
 	ps.ind_level_follow = ps.s_ind_level[ps.tos];
 	return true;
 
-    case if_expr:		/* 'if' '(' <expr> ')' <stmt> */
-	ps.s_ttype[--ps.tos] = if_expr_stmt;
+    case psym_if_expr:		/* 'if' '(' <expr> ')' <stmt> */
+	ps.s_sym[--ps.tos] = psym_if_expr_stmt;
 	int i = ps.tos - 1;
-	while (ps.s_ttype[i] != stmt &&
-	       ps.s_ttype[i] != stmt_list &&
-	       ps.s_ttype[i] != lbrace)
+	while (ps.s_sym[i] != psym_stmt &&
+	       ps.s_sym[i] != psym_stmt_list &&
+	       ps.s_sym[i] != psym_lbrace)
 	    --i;
 	ps.ind_level_follow = ps.s_ind_level[i];
 	/*
@@ -255,14 +296,15 @@ reduce_stmt(void)
 	 */
 	return true;
 
-    case switch_expr:		/* 'switch' '(' <expr> ')' <stmt> */
+    case psym_switch_expr:	/* 'switch' '(' <expr> ')' <stmt> */
 	case_ind = ps.s_case_ind_level[ps.tos - 1];
 	/* FALLTHROUGH */
-    case decl:			/* finish of a declaration */
-    case if_expr_stmt_else:	/* 'if' '(' <expr> ')' <stmt> 'else' <stmt> */
-    case for_exprs:		/* 'for' '(' ... ')' <stmt> */
-    case while_expr:		/* 'while' '(' <expr> ')' <stmt> */
-	ps.s_ttype[--ps.tos] = stmt;
+    case psym_decl:		/* finish of a declaration */
+    case psym_if_expr_stmt_else:	/* 'if' '(' <expr> ')' <stmt> 'else'
+					 * <stmt> */
+    case psym_for_exprs:	/* 'for' '(' ... ')' <stmt> */
+    case psym_while_expr:	/* 'while' '(' <expr> ')' <stmt> */
+	ps.s_sym[--ps.tos] = psym_stmt;
 	ps.ind_level_follow = ps.s_ind_level[ps.tos];
 	return true;
 
@@ -282,11 +324,11 @@ static void
 reduce(void)
 {
 again:
-    if (ps.s_ttype[ps.tos] == stmt) {
+    if (ps.s_sym[ps.tos] == psym_stmt) {
 	if (reduce_stmt())
 	    goto again;
-    } else if (ps.s_ttype[ps.tos] == while_expr) {
-	if (ps.s_ttype[ps.tos - 1] == do_stmt) {
+    } else if (ps.s_sym[ps.tos] == psym_while_expr) {
+	if (ps.s_sym[ps.tos - 1] == psym_do_stmt) {
 	    ps.tos -= 2;
 	    goto again;
 	}

Index: src/usr.bin/indent/pr_comment.c
diff -u src/usr.bin/indent/pr_comment.c:1.83 src/usr.bin/indent/pr_comment.c:1.84
--- src/usr.bin/indent/pr_comment.c:1.83	Sun Oct 24 19:14:33 2021
+++ src/usr.bin/indent/pr_comment.c	Mon Oct 25 00:54:37 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: pr_comment.c,v 1.83 2021/10/24 19:14:33 rillig Exp $	*/
+/*	$NetBSD: pr_comment.c,v 1.84 2021/10/25 00:54:37 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
@@ -43,7 +43,7 @@ static char sccsid[] = "@(#)pr_comment.c
 
 #include <sys/cdefs.h>
 #if defined(__NetBSD__)
-__RCSID("$NetBSD: pr_comment.c,v 1.83 2021/10/24 19:14:33 rillig Exp $");
+__RCSID("$NetBSD: pr_comment.c,v 1.84 2021/10/25 00:54:37 rillig Exp $");
 #elif defined(__FreeBSD__)
 __FBSDID("$FreeBSD: head/usr.bin/indent/pr_comment.c 334927 2018-06-10 16:44:18Z pstef $");
 #endif
@@ -212,7 +212,8 @@ process_comment(void)
 	char *t = com.e;
 	com.e = com.s + 2;
 	*com.e = '\0';
-	if (opt.blanklines_before_block_comments && ps.last_token != lbrace)
+	if (opt.blanklines_before_block_comments &&
+		ps.last_token != lsym_lbrace)
 	    blank_line_before = true;
 	dump_line();
 	com.e = com.s = t;

Reply via email to