Atoms, Identifiers, and Primaries

Bruce McGoveran bruce.mcgoveran at gmail.com
Wed Apr 17 13:15:02 EDT 2013


Thank you all for your thoughtful replies.  I appreciate your collective insight.  I didn't mean to cast the concept of recursion in a negative light - I'm actually comfortable with the concept, at least to some extent, and I appreciate the need for its use in this documentation.  I also appreciate the need to play with expressions at the command line, to gain a feel for how expressions are evaluated.  My interest in the language's formal description arises merely out of a desire to understand as precisely as possible what happens when I hit enter at the command line, or when I run a module.  
Your answers to my initial questions in this thread and the ones I posed in another thread ("Understanding Boolean Expressions") have lead me to some follow-up questions.  Suppose I'm working at the command line, and I bind x to the value 1 and y to the value 0.  Suppose I next type x and y and hit enter.  Python returns 0 (zero).  I'm glad I checked this before sending in this post because I thought it would return a value of False based on the presence of the and operand.  My question:  what did the interpreter have to do to evaluate the expression x and y and return a value of zero?
I know the lexical analyzer has to parse the stream of characters into tokens.  I presume this parsing generates the toxens x, y, and, and a NEWLINE.  Beyond that, things get a little fuzzy, and it occurs to me that this fuzziness is the result of my looking at the expression x and y knowing full well what each token means and what I want done with them, whereas the interpreter won't know these things until it can parse the character stream and sort the tokens into some recognizable (and syntactically correct) order.
As I look at it, the expression x and y has two atoms, namely x and y.  x and y are also primaries, and they represent the most tightly bound parts of this expression (meaning they bind more tightly to their underlying objects than to the and operator).   Incidentally, how does Python figure out that the x and y in this expression refer to the x and y I previously bound to integer values?  I know there's a symbol table in each execution frame.  How does Python know to go to that table and check for x and y?
The and token represents an operator, a boolean operator to be specific.  As I look at the grammar for and_test in section 5.10 of the documentation, it would appear that the and_test resolves via not_test's definition to two comparisons, which in turn resolve to or_expr, and then via a series of binary bitwise definitions to shift_expr, then to a_expr, then to m_expr, then to u_expr, to power, and then primary, and then to atom, which lands us finally at non-terminal identifiers (i.e. x and y themselves).  
Questions:  In working through these steps, what I have actually demonstrated?  Is this how Python deconstructs an and statement with two operands?  Do I take from the fact that the progression from and_test to identifier involved reference to bitwise operators that the boolean testing of x and y involves a bitwise comparison of x and y?  I have to admit these questions are a little confusing; this may reflect the fact I am not exactly sure what it is I am trying to ask.  In general terms, I am trying to understand how Python evalutes the expression x and y in this context.
For my sanity's sake (and, perhaps, for yours) I will stop there.  I send thanks in advance for any thoughts you have on my questions.



On Tuesday, April 16, 2013 10:57:25 PM UTC-4, Bruce McGoveran wrote:
> These are terms that appear in section 5 (Expressions) of the Python online documentation.  I'm having some trouble understanding what, precisely, these terms mean.  I'd appreciate the forum's thoughts on these questions:
> 
> 
> 
> 1.  Section 5.2.1 indicates that an identifier occurring as an atom is a name.  However, Section 2.3 indicates that identifiers are names.  My question:  can an identifier be anything other than a name?
> 
> 
> 
> 2.  Section 5.3 defines primaries as the most tightly bound operations of Python.  What does this mean?  In particular, if an atom is a primary, what operation is the atom performing that leads to the label "most tightly bound"?  To put it a different way, I think of atoms as things (i.e. identifiers).  The documentation makes me think atoms actually do something, as opposed to being things (I think I have in my mind the difference between a noun and a verb as I write this).  Perhaps the doing in this case (or binding, if you like) is linking (binding) the identifier to the underlying object?  I think it might help if I had a better working notion of what a primary is.
> 
> 
> 
> 3.  Section 5.3.1 offers this definition of an attributeref:
> 
>     attributeref ::= primary "." identifier
> 
> 
> 
> Now, I was at first a little concerned to see the non-terminal primary on the right hand side of the definition, since primary is defined to include attributeref in section 5.3 (so this struck me as circular).  Am I correct in thinking attributeref is defined this way to allow for situations in which the primary, whether an atom, attributeref (example:  an object on which a method is called that returns another object), subscription, slicing, or call, returns an object with property identifier?
> 
> 
> 
> These are, I know, long-winded questions.  I appreciate in advance any thoughts the group can offer.
> 
> 
> 
> The relevant documentation link is:  http://docs.python.org/2/reference/expressions.html#expressions
> 
> 
> 
> Thanks,
> 
> Bruce



More information about the Python-list mailing list