Grammar: why is every call a 'power'?


I’ve been using 2to3 a lot recently, which is my first encounter with Python’s grammar definition. I’m wondering why every ‘call’ seems to be a power element?

e.g. this pattern from the zip fixer:

power< 'zip' args=trailer< '(' [any] ')' > [trailers=trailer*]

But I think that’s just trying to match any use of the zip function, and nothing to do with the ** operator. I thought maybe power meant something else in this context, but it’s listed under ‘arithmetic operators’ in the grammar spec.

The spec lists:

    | await_primary '**' factor 
    | await_primary

…so I can see why it would match things without the **, but can anyone help me understand why it’s set up like that? (It’s not causing any problems for me, I’m just curious and I haven’t been able to find any answers on Google or SO.)


The grammar reads a bit weirdly sometimes, because operator precedence is defined by what kind of thing something is. For instance, a disjunction could be conjunction or conjunction or it could simply be conjunction, and a conjunction could be inversion and inversion or just inversion, and an inversion is either not inversion or comparison. What that means is that, in a complicated expression like not a and b or not c and d or not not not not e, you can tease it apart, step by step, figuring that a disjunction can contain a conjunction but not the other way around, so it has to be (not a and b) or (not c and d) or (not not not not e). The same is true all down the precedence tree; power is the term used here because it basically can’t be some larger expression (unless parenthesized). Consider these two lines of code:

spam + zip(...)
(spam + zip)(...)

One of them is an expression involving the zip() function, but the other isn’t. You know this, as a programmer; but the way that the parser - and 2to3 - knows this is that the power syntax node can’t be thing + thing, and therefore the call expression has to include only the part after the addition.

The modern grammar is a little bit different from what you’re seeing there, but the same broad concepts apply.

Thank you Chris, that’s cleared things up a lot.

So in this context, does power actually refer to the mathematical operation? Is there another meaning of power? Or is it accidental that power happened to be the expression that ended up matching a single expression like this?

Yes it does refer to the mathematical operator, but only because that’s the particular point in the precedence table that you’re working at.

Note that, in this table, await expressions come between function calls and exponentiation. So a function call doesn’t have a power in it any more - it has a primary, and power contains an await_primary. But in the Python 2 grammar, exponentiation is immediately above function calls, so the definition of a function call includes a power node.

Makes sense to me, thanks!