From b2283a5bf4b051829f757ee84ec555f639e036ea Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sun, 8 Jun 2014 11:05:32 +0200 Subject: [PATCH 1/5] Early continue allows less indentation, more readability --- rply/parsergenerator.py | 61 +++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/rply/parsergenerator.py b/rply/parsergenerator.py index f2ed8ee..da4a165 100644 --- a/rply/parsergenerator.py +++ b/rply/parsergenerator.py @@ -323,38 +323,41 @@ def from_grammar(cls, grammar): else: laheads = p.lookaheads[st] for a in laheads: - if a in st_action: - r = st_action[a] - if r > 0: - sprec, slevel = grammar.productions[st_actionp[a].number].prec - rprec, rlevel = grammar.precedence.get(a, ("right", 0)) - if (slevel < rlevel) or (slevel == rlevel and rprec == "left"): - st_action[a] = -p.number - st_actionp[a] = p - if not slevel and not rlevel: - sr_conflicts.append((st, repr(a), "reduce")) - grammar.productions[p.number].reduced += 1 - elif not (slevel == rlevel and rprec == "nonassoc"): - if not rlevel: - sr_conflicts.append((st, repr(a), "shift")) - elif r < 0: - oldp = grammar.productions[-r] - pp = grammar.productions[p.number] - if oldp.number > pp.number: - st_action[a] = -p.number - st_actionp[a] = p - chosenp, rejectp = pp, oldp - grammar.productions[p.number].reduced += 1 - grammar.productions[oldp.number].reduced -= 1 - else: - chosenp, rejectp = oldp, pp - rr_conflicts.append((st, repr(chosenp), repr(rejectp))) - else: - raise ParserGeneratorError("Unknown conflict in state %d" % st) - else: + + if a not in st_action: st_action[a] = -p.number st_actionp[a] = p grammar.productions[p.number].reduced += 1 + continue + + r = st_action[a] + if r > 0: + sprec, slevel = grammar.productions[st_actionp[a].number].prec + rprec, rlevel = grammar.precedence.get(a, ("right", 0)) + if (slevel < rlevel) or (slevel == rlevel and rprec == "left"): + st_action[a] = -p.number + st_actionp[a] = p + if not slevel and not rlevel: + sr_conflicts.append((st, repr(a), "reduce")) + grammar.productions[p.number].reduced += 1 + elif not (slevel == rlevel and rprec == "nonassoc"): + if not rlevel: + sr_conflicts.append((st, repr(a), "shift")) + elif r < 0: + oldp = grammar.productions[-r] + pp = grammar.productions[p.number] + if oldp.number > pp.number: + st_action[a] = -p.number + st_actionp[a] = p + chosenp, rejectp = pp, oldp + grammar.productions[p.number].reduced += 1 + grammar.productions[oldp.number].reduced -= 1 + else: + chosenp, rejectp = oldp, pp + rr_conflicts.append((st, repr(chosenp), repr(rejectp))) + else: + raise ParserGeneratorError("Unknown conflict in state %d" % st) + else: i = p.lr_index a = p.prod[i + 1] From f87a8f5c430d4cd2b4d6cfa2c661040ec85c248d Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sun, 8 Jun 2014 11:08:38 +0200 Subject: [PATCH 2/5] Early continue allows less indentation, more readability --- rply/parsergenerator.py | 66 +++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/rply/parsergenerator.py b/rply/parsergenerator.py index da4a165..79b7665 100644 --- a/rply/parsergenerator.py +++ b/rply/parsergenerator.py @@ -316,47 +316,49 @@ def from_grammar(cls, grammar): st_goto = {} for p in I: if p.getlength() == p.lr_index + 1: + if p.name == "S'": # Start symbol. Accept! st_action["$end"] = 0 st_actionp["$end"] = p - else: - laheads = p.lookaheads[st] - for a in laheads: + continue + + laheads = p.lookaheads[st] + for a in laheads: + + if a not in st_action: + st_action[a] = -p.number + st_actionp[a] = p + grammar.productions[p.number].reduced += 1 + continue - if a not in st_action: + r = st_action[a] + if r > 0: + sprec, slevel = grammar.productions[st_actionp[a].number].prec + rprec, rlevel = grammar.precedence.get(a, ("right", 0)) + if (slevel < rlevel) or (slevel == rlevel and rprec == "left"): st_action[a] = -p.number st_actionp[a] = p + if not slevel and not rlevel: + sr_conflicts.append((st, repr(a), "reduce")) grammar.productions[p.number].reduced += 1 - continue - - r = st_action[a] - if r > 0: - sprec, slevel = grammar.productions[st_actionp[a].number].prec - rprec, rlevel = grammar.precedence.get(a, ("right", 0)) - if (slevel < rlevel) or (slevel == rlevel and rprec == "left"): - st_action[a] = -p.number - st_actionp[a] = p - if not slevel and not rlevel: - sr_conflicts.append((st, repr(a), "reduce")) - grammar.productions[p.number].reduced += 1 - elif not (slevel == rlevel and rprec == "nonassoc"): - if not rlevel: - sr_conflicts.append((st, repr(a), "shift")) - elif r < 0: - oldp = grammar.productions[-r] - pp = grammar.productions[p.number] - if oldp.number > pp.number: - st_action[a] = -p.number - st_actionp[a] = p - chosenp, rejectp = pp, oldp - grammar.productions[p.number].reduced += 1 - grammar.productions[oldp.number].reduced -= 1 - else: - chosenp, rejectp = oldp, pp - rr_conflicts.append((st, repr(chosenp), repr(rejectp))) + elif not (slevel == rlevel and rprec == "nonassoc"): + if not rlevel: + sr_conflicts.append((st, repr(a), "shift")) + elif r < 0: + oldp = grammar.productions[-r] + pp = grammar.productions[p.number] + if oldp.number > pp.number: + st_action[a] = -p.number + st_actionp[a] = p + chosenp, rejectp = pp, oldp + grammar.productions[p.number].reduced += 1 + grammar.productions[oldp.number].reduced -= 1 else: - raise ParserGeneratorError("Unknown conflict in state %d" % st) + chosenp, rejectp = oldp, pp + rr_conflicts.append((st, repr(chosenp), repr(rejectp))) + else: + raise ParserGeneratorError("Unknown conflict in state %d" % st) else: i = p.lr_index From 6c8ee46a62d79bbbe0c6064121561dbfd42ada40 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sun, 8 Jun 2014 11:10:15 +0200 Subject: [PATCH 3/5] Early continue allows less indentation, more readability --- rply/parsergenerator.py | 54 ++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/rply/parsergenerator.py b/rply/parsergenerator.py index 79b7665..ad81248 100644 --- a/rply/parsergenerator.py +++ b/rply/parsergenerator.py @@ -361,34 +361,38 @@ def from_grammar(cls, grammar): raise ParserGeneratorError("Unknown conflict in state %d" % st) else: + i = p.lr_index a = p.prod[i + 1] - if a in grammar.terminals: - g = cls.lr0_goto(I, a, add_count, goto_cache) - j = cidhash.get(g, -1) - if j >= 0: - if a in st_action: - r = st_action[a] - if r > 0: - if r != j: - raise ParserGeneratorError("Shift/shift conflict in state %d" % st) - elif r < 0: - rprec, rlevel = grammar.productions[st_actionp[a].number].prec - sprec, slevel = grammar.precedence.get(a, ("right", 0)) - if (slevel > rlevel) or (slevel == rlevel and rprec == "right"): - grammar.productions[st_actionp[a].number].reduced -= 1 - st_action[a] = j - st_actionp[a] = p - if not rlevel: - sr_conflicts.append((st, repr(a), "shift")) - elif not (slevel == rlevel and rprec == "nonassoc"): - if not slevel and not rlevel: - sr_conflicts.append((st, repr(a), "reduce")) - else: - raise ParserGeneratorError("Unknown conflict in state %d" % st) + if a not in grammar.terminals: + continue + + g = cls.lr0_goto(I, a, add_count, goto_cache) + j = cidhash.get(g, -1) + if j >= 0: + if a in st_action: + r = st_action[a] + if r > 0: + if r != j: + raise ParserGeneratorError("Shift/shift conflict in state %d" % st) + elif r < 0: + rprec, rlevel = grammar.productions[st_actionp[a].number].prec + sprec, slevel = grammar.precedence.get(a, ("right", 0)) + if (slevel > rlevel) or (slevel == rlevel and rprec == "right"): + grammar.productions[st_actionp[a].number].reduced -= 1 + st_action[a] = j + st_actionp[a] = p + if not rlevel: + sr_conflicts.append((st, repr(a), "shift")) + elif not (slevel == rlevel and rprec == "nonassoc"): + if not slevel and not rlevel: + sr_conflicts.append((st, repr(a), "reduce")) else: - st_action[a] = j - st_actionp[a] = p + raise ParserGeneratorError("Unknown conflict in state %d" % st) + else: + st_action[a] = j + st_actionp[a] = p + nkeys = set() for ii in I: for s in ii.unique_syms: From 4d9003e4ac0acb1c3e77d4d0b7eb42ee952adee3 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sun, 8 Jun 2014 11:10:57 +0200 Subject: [PATCH 4/5] Early continue allows less indentation, more readability --- rply/parsergenerator.py | 46 +++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/rply/parsergenerator.py b/rply/parsergenerator.py index ad81248..84b039b 100644 --- a/rply/parsergenerator.py +++ b/rply/parsergenerator.py @@ -369,29 +369,31 @@ def from_grammar(cls, grammar): g = cls.lr0_goto(I, a, add_count, goto_cache) j = cidhash.get(g, -1) - if j >= 0: - if a in st_action: - r = st_action[a] - if r > 0: - if r != j: - raise ParserGeneratorError("Shift/shift conflict in state %d" % st) - elif r < 0: - rprec, rlevel = grammar.productions[st_actionp[a].number].prec - sprec, slevel = grammar.precedence.get(a, ("right", 0)) - if (slevel > rlevel) or (slevel == rlevel and rprec == "right"): - grammar.productions[st_actionp[a].number].reduced -= 1 - st_action[a] = j - st_actionp[a] = p - if not rlevel: - sr_conflicts.append((st, repr(a), "shift")) - elif not (slevel == rlevel and rprec == "nonassoc"): - if not slevel and not rlevel: - sr_conflicts.append((st, repr(a), "reduce")) - else: - raise ParserGeneratorError("Unknown conflict in state %d" % st) + if j < 0: + continue + + if a in st_action: + r = st_action[a] + if r > 0: + if r != j: + raise ParserGeneratorError("Shift/shift conflict in state %d" % st) + elif r < 0: + rprec, rlevel = grammar.productions[st_actionp[a].number].prec + sprec, slevel = grammar.precedence.get(a, ("right", 0)) + if (slevel > rlevel) or (slevel == rlevel and rprec == "right"): + grammar.productions[st_actionp[a].number].reduced -= 1 + st_action[a] = j + st_actionp[a] = p + if not rlevel: + sr_conflicts.append((st, repr(a), "shift")) + elif not (slevel == rlevel and rprec == "nonassoc"): + if not slevel and not rlevel: + sr_conflicts.append((st, repr(a), "reduce")) else: - st_action[a] = j - st_actionp[a] = p + raise ParserGeneratorError("Unknown conflict in state %d" % st) + else: + st_action[a] = j + st_actionp[a] = p nkeys = set() for ii in I: From c71c3bb7536ef02f6bad5fbc90b5e33406c32d97 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sun, 8 Jun 2014 11:11:41 +0200 Subject: [PATCH 5/5] Early continue allows less indentation, more readability --- rply/parsergenerator.py | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/rply/parsergenerator.py b/rply/parsergenerator.py index 84b039b..5df004a 100644 --- a/rply/parsergenerator.py +++ b/rply/parsergenerator.py @@ -372,28 +372,29 @@ def from_grammar(cls, grammar): if j < 0: continue - if a in st_action: - r = st_action[a] - if r > 0: - if r != j: - raise ParserGeneratorError("Shift/shift conflict in state %d" % st) - elif r < 0: - rprec, rlevel = grammar.productions[st_actionp[a].number].prec - sprec, slevel = grammar.precedence.get(a, ("right", 0)) - if (slevel > rlevel) or (slevel == rlevel and rprec == "right"): - grammar.productions[st_actionp[a].number].reduced -= 1 - st_action[a] = j - st_actionp[a] = p - if not rlevel: - sr_conflicts.append((st, repr(a), "shift")) - elif not (slevel == rlevel and rprec == "nonassoc"): - if not slevel and not rlevel: - sr_conflicts.append((st, repr(a), "reduce")) - else: - raise ParserGeneratorError("Unknown conflict in state %d" % st) - else: + if a not in st_action: st_action[a] = j st_actionp[a] = p + continue + + r = st_action[a] + if r > 0: + if r != j: + raise ParserGeneratorError("Shift/shift conflict in state %d" % st) + elif r < 0: + rprec, rlevel = grammar.productions[st_actionp[a].number].prec + sprec, slevel = grammar.precedence.get(a, ("right", 0)) + if (slevel > rlevel) or (slevel == rlevel and rprec == "right"): + grammar.productions[st_actionp[a].number].reduced -= 1 + st_action[a] = j + st_actionp[a] = p + if not rlevel: + sr_conflicts.append((st, repr(a), "shift")) + elif not (slevel == rlevel and rprec == "nonassoc"): + if not slevel and not rlevel: + sr_conflicts.append((st, repr(a), "reduce")) + else: + raise ParserGeneratorError("Unknown conflict in state %d" % st) nkeys = set() for ii in I: