We don't need to store the indent_depth if we just shift the bit-stack
up and down. <<1 pushes a zero, >>1 pops, |=1 changes the zero to one.
Signed-off-by: NeilBrown <neil@brown.name>
Indents (IN) are sometimes shifted and sometimes only accounted.
Whatever decision is made must apply equally to the matching OUT. To
Indents (IN) are sometimes shifted and sometimes only accounted.
Whatever decision is made must apply equally to the matching OUT. To
-ensure this we keep a stack of bits in `ignored_indents` and
-`indent_depth`. When we process an IN, we record if it was ignored.
-When we see an out, we pop of the relavant bit and use it to decide how
-to handle the OUT.
+ensure this we keep a stack of bits in `ignored_indents`. When we
+process an IN, we record if it was ignored. When we see an out, we pop
+of the relavant bit and use it to decide how to handle the OUT.
###### parser state
unsigned long ignored_indents;
###### parser state
unsigned long ignored_indents;
NEWLINE/EOL is ignored when in an indented section of text which was not
explicitly expected by the grammar. So if the most recent indent is
NEWLINE/EOL is ignored when in an indented section of text which was not
explicitly expected by the grammar. So if the most recent indent is
###### try shift or ignore
if ((tk->num == TK_newline || tk->num == TK_out) &&
###### try shift or ignore
if ((tk->num == TK_newline || tk->num == TK_out) &&
- (p.ignored_indents & (1 << p.indent_depth))) {
+ (p.ignored_indents & 1)) {
/* indented, so ignore OUT and NEWLINE */
if (tk->num == TK_out)
/* indented, so ignore OUT and NEWLINE */
if (tk->num == TK_out)
+ p.ignored_indents >>= 1;
free(tk);
tk = NULL;
parser_trace_action(trace, "Ignore");
free(tk);
tk = NULL;
parser_trace_action(trace, "Ignore");
switch (shift(&p, tk->num, tk, states)) {
case 1:
if (tk->num == TK_out)
switch (shift(&p, tk->num, tk, states)) {
case 1:
if (tk->num == TK_out)
- p.indent_depth -= 1;
- if (tk->num == TK_in) {
- p.indent_depth += 1;
- p.ignored_indents &= ~(1 << p.indent_depth);
- }
+ p.ignored_indents >>= 1;
+ if (tk->num == TK_in)
+ p.ignored_indents <<= 1;
+
tk = NULL;
/* fallthrough */
case 2:
tk = NULL;
/* fallthrough */
case 2:
/* No indent expected here, so ignore IN */
free(tk);
tk = NULL;
/* No indent expected here, so ignore IN */
free(tk);
tk = NULL;
- p.indent_depth += 1;
- p.ignored_indents |= (1 << p.indent_depth);
+ p.ignored_indents <<= 1;
+ p.ignored_indents |= 1;
parser_trace_action(trace, "Ignore");
continue;
}
parser_trace_action(trace, "Ignore");
continue;
}