<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 An EBNF based Parser for Arithmetic Expressions
In this notebook we implement an <span style="font-variant
Step1:  The function tokenize receives a string s as argument and returns a list of tokens.
The string s is supposed to represent an arithmetical expression. 
Note
Step2:  Implementing the Recursive Descend Parser
The function parse takes a string s as input and parses this string according to the recursive grammar
shown above.
Step3:  The function parserExpr(TL) takes a list of tokens TL and tries to parse an expresssion according to the following
<span style="font-variant
Step4:  The function parserProduct(TL) takes a list of tokens TL and tries to parse a product according to the following
<span style="font-variant
Step5:  The function parseFactor implements the following grammar rules
Step6:  Testing
<ASSISTANT_TASK:>
Python Code:
import re
Explanation: An EBNF based Parser for Arithmetic Expressions
In this notebook we implement an <span style="font-variant:small-caps;">Ebnf</span> recursive-descend parser for arithmetic expressions.  This parser implements the following <span style="font-variant:small-caps;">Ebnf</span> grammar:
$$
  \begin{eqnarray}
  \mathrm{expr}    & \rightarrow & \mathrm{product}\;\;\bigl((\texttt{'+'}\;|\;\texttt{'-'})\;\; \mathrm{product}\bigr)^ \[0.2cm]
  \mathrm{product} & \rightarrow & \mathrm{factor} \;\;\bigl((\texttt{''}\;|\;\texttt{'/'})\;\; \mathrm{factor}\bigr)^  \[0.2cm] 
  \mathrm{factor}  & \rightarrow & \texttt{'('} \;\;\mathrm{expr} \;\;\texttt{')'}                             \
                   & \mid        & \texttt{NUMBER} 
  \end{eqnarray*}
$$
The Scanner
End of explanation
def tokenize(s):
    '''Transform the string s into a list of tokens.  The string s
       is supposed to represent an arithmetic expression.
    '''
    lexSpec = r'''([ \t]+)        |  # blanks and tabs
                  ([1-9][0-9]*|0) |  # number
                  ([()])          |  # parentheses 
                  ([-+*/])        |  # arithmetical operators
                  (.)                # unrecognized character
               '''
    tokenList = re.findall(lexSpec, s, re.VERBOSE)
    result    = []
    # print(tokenList)
    for ws, number, parenthesis, operator, error in tokenList:
        if ws:        # skip blanks and tabs
            continue
        elif number:
            result += [ number ]
        elif parenthesis:
            result += [ parenthesis ]
        elif operator:
            result += [ operator ]
        else:
            result += [ f'ERROR({error})']
    return result
tokenize('12 * 13 + 14 * 4 / 6 - 7')
Explanation: The function tokenize receives a string s as argument and returns a list of tokens.
The string s is supposed to represent an arithmetical expression. 
Note: 
1. We need to set the flag re.VERBOSE in our call of the function findall
   below because otherwise we are not able to format the regular expression lexSpec 
   with whitespace.
2. The regular expression lexSpec contains 5 parenthesized groups.  Therefore,
   findall returns a list of 5-tuples where the 5 components correspond to the 5
   groups of the regular expression.
End of explanation
def parse(s):
    TL           = tokenize(s)
    result, Rest = parseExpr(TL)
    assert Rest == [], f'Parse Error: could not parse {TL}, Rest = {Rest}'
    return result
Explanation: Implementing the Recursive Descend Parser
The function parse takes a string s as input and parses this string according to the recursive grammar
shown above.
End of explanation
def parseExpr(TL):
    result, Rest = parseProduct(TL)
    while len(Rest) > 1 and Rest[0] in {'+', '-'}: 
        operator = Rest[0]
        arg, Rest = parseProduct(Rest[1:])
        if operator == '+': 
            result += arg
        else:             # operator == '-': 
            result -= arg
    return result, Rest
Explanation: The function parserExpr(TL) takes a list of tokens TL and tries to parse an expresssion according to the following
<span style="font-variant:small-caps;">Ebnf</span> grammar rule:
$$ \mathrm{expr} \;\rightarrow\; \mathrm{product}\;\;\bigl((\texttt{'+'}\;|\;\texttt{'-'})\;\; \mathrm{product}\bigr)^* $$
It returns the value of the expression and a list of all the tokens that have not been consumed during parsing.
End of explanation
def parseProduct(TL):
    result, Rest = parseFactor(TL)
    while len(Rest) > 1 and Rest[0] in {'*', '/'}:
        operator = Rest[0]
        arg, Rest = parseFactor(Rest[1:])
        if operator == '*':
            result *= arg
        else:             # operator == '/':
            result /= arg
    return result, Rest
Explanation: The function parserProduct(TL) takes a list of tokens TL and tries to parse a product according to the following
<span style="font-variant:small-caps;">Ebnf</span> grammar rule:
$$ \mathrm{product} \;\rightarrow\; \mathrm{factor} \;\;\bigl((\texttt{''}\;|\;\texttt{'/'})\;\; \mathrm{factor}\bigr)^  $$
It returns the value of the product and a list of all the tokens that have not been consumed during parsing.
End of explanation
def parseFactor(TL):
    if TL[0] == '(': 
        expr, Rest = parseExpr(TL[1:])
        assert Rest[0] == ')', "ERROR: ')' expected, got {Rest[0]}"
        return expr, Rest[1:]
    else:
        return float(TL[0]), TL[1:]
Explanation: The function parseFactor implements the following grammar rules:
$$
  \begin{eqnarray}
  \mathrm{factor}      & \;\rightarrow\; & \texttt{'('} \;\;\mathrm{expr} \;\;\texttt{')'}                \
                       & \;\mid          & \;\texttt{NUMBER} 
  \end{eqnarray}
$$
It takes one argument:
- TL is the list of tokens that still need to be consumed.
It returns a pair of the form (value, Rest) where
- value is the result of evaluating the arithmetical expression
  that is represented by TL and
- Rest is a list of those tokens that have not been consumed while trying to parse a factor.
End of explanation
def test(s: str) -> float:
    r1 = parse(s)
    r2 = eval(s)
    assert r1 == r2
    return r1
parse('12 * 13 + 14 * 4 / 6 - 7')
test('11+22*(33-44)/(5-10*5/(4-3))')
test('0*11+22*(33-44)/(5-10*5/(4-3))')
Explanation: Testing
End of explanation
<END_TASK>