Skip to main content

Arithmetic calculator which uses a Pratt parser

Project description

Introduction

An arithmetic expression calculator in Python, demoing the Pratt parsing algorithm.

This takes inspiration from this 2010 blog post by Eli Bendersky, as well as a few other sources:

  1. Simple but Powerful Pratt Parsing
  2. Pratt Parsers: Expression Parsing Made Easy
  3. Compiling Expressions (Chapter 17 of Crafting Interpreters)

Requirements

Requires Python 3.13 or greater.

Installation

pip

Set up and activate a virtual environment, then:

pip install pratt-calc

pipx (recommended)

Using pipx enables you to globally install the application without worrying about virtual environments.

pipx install pratt-calc

In some cases it may be necessary to specify the Python version manually:

PIPX_DEFAULT_PYTHON=python3.13 pipx install pratt-calc

Or, if you have uv installed:

uvx pipx install pratt-calc

Contributing

Install uv, then run:

git clone https://github.com/BrandonIrizarry/pratt-calc
cd pratt-calc
uv sync --locked

Usage

Pratt Calc supports three modes of usage:

  1. Evaluating expressions from inside a REPL;
  2. evaluating the contents of a source file, and
  3. evaluating an expression given at the command line.

Also see

pratt-calc --help

REPL

To launch the REPL:

pratt-calc

Use the exit command (or Ctrl+D) to quit the REPL.

Loading a file

To execute the contents of a file:

pratt-calc FILENAME

Evaluating an expression on the fly

To evaluate a one-off expression:

pratt-calc -e EXPRESSION

Single quotes surrounding the expression are recommended, to prevent the shell from expanding * and so on. Example:

pratt-calc -e '3-4*5'

This should print -17 at the console.

Combining switches (the -i flag)

If neither a filename argument nor -e are provided, the REPL will launch. Conversely, if either one is present, the REPL will not launch. However, you can use -i to force the REPL to launch in such a case.

Basic Arithmetic

Pratt Calc is at its most basic level an arithmetic expression calculator over integers and floats. It currently supports +, -, *, and \ with their usual meanings of addition, subtraction, multiplication, and division respectively. In addition, unary negation (e.g. -2.5), as well as exponentiation (^) and factorial (!) are supported.

Note that an expression like 3.2! is first truncated to an integer before evaluation, that is, 3.2! would evaluate to 6.

Parentheses are used to enforce precedence, viz.,

pratt-calc -e '(3 + 5) * 2' => 16

Semicolons

Semicolons enable side-effect-based programming, which currently are a work in progress. For now, semicolons discard the result of whatever is to the left of them:

pratt-calc -e '3 + 3 ; 3 * 3; 3 ^ 3' => 27.0

That is, the result of the above expression is simply the value of the last subexpression, namely, 3 ^ 3.

Note: for now, semicolons can't terminate an expression, since they're technically infix operators, and thus require a right-hand argument! I have some ideas for workarounds, but I'm not focused on that right now.

Trigonometric Functions

pratt-calc supports the following trigonometric functions:

  1. sin
  2. cos
  3. tan
  4. csc
  5. sec
  6. cot

The constant 𝝿 is also available as pi. Examples:

pratt-calc -e 'pi' => 3.141592653589793

pratt-calc -e 'cos(pi)' => -1.0

pratt-calc -e 'sin(1)^2 + cos(1)^2' => 1.0

A Note on the Implementation of Trig Functions

Trig functions are implemented as unary operators, as opposed to function calls. Hence the parentheses used by sin and so forth are merely there to enforce precedence, even though they conveniently evoke the intuition of a function call.

Hence sin²(1) + cos²(1) can be written (somewhat misleadingly) as follows:

sin 1^2 + cos 1^2

This evaluates to 1.0.

For this reason, parentheses in this case are always recommended.

A Note on Libraries Used

Pratt Calc, as a command-line app, is built using Typer.

It also uses the more-itertools library to implement the token stream used to drive expression evaluation.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pratt_calc-1.0.0.tar.gz (20.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pratt_calc-1.0.0-py3-none-any.whl (20.7 kB view details)

Uploaded Python 3

File details

Details for the file pratt_calc-1.0.0.tar.gz.

File metadata

  • Download URL: pratt_calc-1.0.0.tar.gz
  • Upload date:
  • Size: 20.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pratt_calc-1.0.0.tar.gz
Algorithm Hash digest
SHA256 8d3c0c57517769c600ca4ad4e6fc4defa8f804b81cf3bf171633833cf542c6e5
MD5 014700eba9b60b5e783325a1e17cd664
BLAKE2b-256 606f32f874e532287c846bfcd01507900695f34e1ecc4f1000e84d83b5854fbb

See more details on using hashes here.

File details

Details for the file pratt_calc-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: pratt_calc-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 20.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pratt_calc-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b3cbc52d8168ed26a4dd65b47fed47ed795df5d585f15411b579157a966689a7
MD5 44650e7ddc89de28f3bd3d3dd2905b58
BLAKE2b-256 519aacd5d9f3a2d9a237a5bdf9084e5552b5abe4456b86fdf4e9b8a8d246626d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page