From 35d743c48140ea96fa56c3f63ee8dd0e032cbb2d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sun, 23 Jun 2019 10:21:14 +1000 Subject: [PATCH] parsergen: allow $$OUT to be satisfied are start-of-line. If a $$OUT (or $$NEWLINE) production is being reduced at start-of-line (with no indents), then that is satisfactory, we don't need NEWLINE etc as look-ahead. This means that in cases where this is relevant, the computed lookahead is wrong - we shouldn't have striped it. I don't think this matters as it only affects conflict warnings, and I think these will be reported at a higher level if relevant. If essense, the $$OUT marking is like a precendence marking which suppresses shift/reduce warnings as it say that decision is being made on some basis other than look-ahead. Signed-off-by: NeilBrown --- csrc/indent_test.mdc | 19 ++++++++++--------- csrc/parsergen.mdc | 10 +++++++--- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/csrc/indent_test.mdc b/csrc/indent_test.mdc index 88e9391..7e4f956 100644 --- a/csrc/indent_test.mdc +++ b/csrc/indent_test.mdc @@ -160,7 +160,7 @@ $*statement | NEWLINE Close Block -> Open Statementlist Close ${ $0 = $<2; }$ | Open SimpleStatements } ${ $0 = $<2; }$ - | : SimpleStatements $$NEWLINE ${ $0 = $<2; }$ + | : SimpleStatements ${ $0 = $<2; }$ | : StatementBlock ${ $0 = $<2; }$ StatementBlock -> Statementlist $$OUT ${ $0 = $<1; }$ @@ -185,9 +185,9 @@ $*statement $0->expr->right = $<3; }$ SSline -> SimpleStatements NEWLINE ${ $0 = $<1; }$ - | SSline NEWLINE ${ $0 = $<1; }$ Statement -> SSline ${ $0 = $<1; }$ - | IfStatement ${ $0 = $<1; }$ + | IfStatement $$NEWLINE ${ $0 = $<1; }$ + | Statement NEWLINE ${ $0 = $<1; }$ $RIGHT else @@ -197,20 +197,16 @@ $*statement $0->thenpart = $<3; }$ | IfHead NEWLINE ${ $0 = $<1; }$ - IfTail -> else Block ${ $0 = $<2; }$ - | IfTail NEWLINE ${ $0 = $<1; }$ IfStatement -> IfHead $$else ${ $0 = $<1; }$ - | IfHead IfTail ${ + | IfHead else Block ${ $0 = $<1; - $0->elsepart = $<2; + $0->elsepart = $<3; }$ | IfHead else IfStatement ${ $0 = $<1; $0->elsepart = $<3; }$ - | IfStatement NEWLINE ${ $0 = $<1; }$ - $*expression Expression -> Expression + Term ${ @@ -272,6 +268,7 @@ $*expression all = y; if true {yes=x;} else : no=x if true: yes = no; no = yes; + if false: yes=ok; else: no=ok if false { print = OK @@ -309,6 +306,10 @@ $*expression if true: (yes=no); (no=yes); + if false: + (yes=ok); + else: + (no=ok); if false: (print=OK); else: diff --git a/csrc/parsergen.mdc b/csrc/parsergen.mdc index 76fec3a..df73f51 100644 --- a/csrc/parsergen.mdc +++ b/csrc/parsergen.mdc @@ -2871,9 +2871,13 @@ checks if a given token is in any of these look-ahead sets. force_reduce: if (states[tos->state].reduce_prod >= 0 && states[tos->state].newline_only && - tk->num != TK_newline && tk->num != TK_eof && tk->num != TK_out) { - /* Anything other than newline in an error as this - * production must end at EOL + !(tk->num == TK_newline || + tk->num == TK_eof || + tk->num == TK_out || + (tos->indents == 0 && tos->since_newline == 0))) { + /* Anything other than newline or out or eof + * in an error unless we are already at start + * of line, as this production must end at EOL. */ } else if (states[tos->state].reduce_prod >= 0) { void **body; -- 2.43.0