Patchwork [2,of,6] parser: resolve ambiguity where both prefix and primary actions are defined

login
register
mail settings
Submitter Yuya Nishihara
Date July 17, 2015, 12:34 p.m.
Message ID <2fc4729950f03b90585d.1437136443@mimosa>
Download mbox | patch
Permalink /patch/10024/
State Accepted
Headers show

Comments

Yuya Nishihara - July 17, 2015, 12:34 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1436065767 -32400
#      Sun Jul 05 12:09:27 2015 +0900
# Node ID 2fc4729950f03b90585d237be6422cd63e926ca9
# Parent  157e255b1970bd21b24eecdc76d9108c84279ef7
parser: resolve ambiguity where both prefix and primary actions are defined

If both actions are defined, a primary-expression action is accepted only if
the next token never starts new term. For example,

  parsed as primary expression:
  ":"   # next token 'end' has no action
  "(:)" # next token ')' has no action
  ":+y" # next token '+' is infix operator

  parsed as prefix operator:
  ":y"  # next token 'y' is primary expression
  ":-y" # next token '-' is prefix operator

This is mostly the same resolution as the infix/suffix rules.

Patch

diff --git a/mercurial/parser.py b/mercurial/parser.py
--- a/mercurial/parser.py
+++ b/mercurial/parser.py
@@ -49,9 +49,9 @@  class parser(object):
         return expr
     def _parse(self, bind=0):
         token, value, pos = self._advance()
-        # handle prefix rules on current token
+        # handle prefix rules on current token, take as primary if unambiguous
         primary, prefix = self._elements[token][1:3]
-        if primary:
+        if primary and not (prefix and self._hasnewterm()):
             expr = (primary, value)
         elif prefix:
             expr = (prefix[0], self._parseoperand(*prefix[1:]))