Skip to content
Alexander Liao edited this page Aug 13, 2017 · 1 revision

After the lexer has tokenized the whole program, the parser then constructs an AST from that. After the lexer, everything is an expression, keyword, bracket, special component, or operator.

The first set of rules matches <open_bracket><binary_operator><close_bracket>, which will become a function that works like the operator.

The next set of rules matches <non-literal expression>(...) as a function call, <expression>[...] as an indexing call, and <expression>.<expression> as a subreference, all at the same level of precedence (left-to-right).

The next set of rules matches <open_any_bracket>...<close_bracket> and parses the contents of ...

The next set of rules matches (... : ...) and (... -> ...) for bracketed for and while loop statements. Note that something containing the wrong number of arguments inside of the brackets will cause errors that can't be easily detected in a program.

The next set of rules matches all operators in the precedence specified, binary before prefix before postfix. Finally, it matches * as a prefix operator for unpacking and then - as a prefix operator for negation.

The next set of rules matches <expression><from|as><expression> for imports.

The next set of rules matches [<expression>]to[<expression>][by<expression>] for list slices.

The next set of rules matches <expression> :> <expression> for dicts :>

The next set of rules matches <comma_expr>, <expression> to comma_expr(*(expression + [expression])) and <expression>, to comma_expr(expression).

The next set of rules matches <expression> ? <expression> : <expression> as a ternary.

The next set of rules matches <expression> => <expression|statement> as a lambda and => <expression|statement> as a generator lambda.

The next rule is for assignment, which has to come after lambdas, unlike the other binary operators, which must come before.

The next rule matches <expression>; to a statement. It does not match <statement>;.

The next set of rules matches <expression> exist[s] [not] for the special definition testing.

The next set of rules matches <import|include> <expression> for Python or Proton imports, respectively.

The next set of rules matches break and continue.

The next set of rules is quite messily defined in the program, but it matches the following things at the same precedence left-to-right, in this order:

  • for <expression> : <expression> <expression|statement> (for each loop)
  • for <expression|statement> <expression|statement> <expression|statement> <expression|statement> (for (start; condition; end) { something; })
  • for (<expression> : <expression>) <expression|statement> (for each loop)
  • for (...) <expression|statement> (for (start; condition; end) { something; })
  • while <expression> -> <expression> <expression|statement> (while loop that assigns the result of the first expression to the second one)
  • while <expression> <expression|statement> (while loop)
  • while (<expression> -> <expression>) <expression|statement> (while loop that assigns the result of the first expression to the second one)
  • while (<expression>) <expression|statement> (while loop)
  • <expression|statement> unless <expression> <expression|statement> (a unless (b) c is equivalent to if (b) {c} else {a})
  • if <expression> <expression|statement> (if)
  • else <expression|statement> (else)
  • (if statement) (else statement) (if-else)
  • try <expression|statement> except <expression> <expression|statement> (try-except, the error is assigned to the non-statement expression)

The next rule matches @f which turns on a function's memoization.

The next rule matches timeof <expression> which determines how long an expression takes to be evaluated.

Clone this wiki locally