Real Estate PEG.js Calculator

Demo + Docs
Try It — edit anything below

What Is This?

A real-time valuation calculator for real estate built on a PEG.js grammar parser. Write formulas using natural real-estate terminology — square meters, thousands, rates per unit — and get instant numeric results with live error feedback.

Background

I built this during my brief stint at a real estate tech company in Berlin. The team needed a way for builders and project managers to compute property valuations on the fly — mixing areas, rates, and unit conversions in a single expression — without dropping into a spreadsheet or calling an API. Traditional expression parsers couldn’t handle the domain grammar (SQ MTR, PER SQ MTR, K, L, CR), so I reached for PEG.js to define a formal grammar that speaks real estate natively.

Why PEG.js?

The same approach works for any domain — not just real estate. Swap the grammar and you get a domain-specific calculator for anything: expense splitting (@you + @friend = 45 EUR), unit conversions, invoice line-item math, or construction material estimation. PEG.js lets you define a formal grammar that speaks whatever language your domain uses — expressive and safe (no arbitrary code execution).

Parsing Expression Grammar — PEGs are unambiguous and linear-time. Each rule is an ordered-choice of alternatives, giving us crystal-clear error messages. The real-estate example here is just one grammar — adapt the grammar.pegjs file to your own terminology.

Quick Start

  1. 1.Define references using NAME = value or NAME - value. Values can be plain numbers, numbers with multipliers/units, or objects.
  2. 2.Write an expression with @NAME, @OBJ.prop, operators + - * / PER, and parentheses.
  3. 3.Read the result — updates in real time. Errors and suggestions appear instantly below.

Syntax Reference

Construct Example Result
Variable reference@GROUND_FLOOR400,000,000
Object property@SHOP.space100
Thousand (×1000)400000 K400,000,000
Lakh (×100,000)5 L500,000
Crore (×10M)2 CR20,000,000
Area annotation100 SQ MTR100 (stripped)
Rate annotation5 PER SQ MTR5 (stripped)
Division10 PER 25
Grouping(10 + 20) * 390

Definitions

Form Example
Simple dashGROUND_FLOOR - 400000 K SQ MTR
Simple equalsAPARTMENT_1 = 30 SQ MTR
ObjectSHOP = {space: 100 SQ MTR, cost: 5 PER SQ MTR}
Note: Names must be single words (letters, digits, underscores). Use @NAME in expressions.

Walkthrough

Valuing a mixed-use property:

# Definitions
GROUND_FLOOR - 400000 K SQ MTR     → 400,000,000 sq.m
APARTMENT_1 = 30 SQ MTR             → 30 sq.m
APARTMENT_2 = 60 SQ MTR             → 60 sq.m
OFFICE = 400 SQ MTR                 → 400 sq.m
SHOP = {space: 100 SQ MTR, cost: 5 PER SQ MTR}
  → SHOP.space = 100, SHOP.cost = 5

# Expression
(@GROUND_FLOOR + @APARTMENT_1 + @APARTMENT_2 + @OFFICE + @SHOP.space) * @SHOP.cost

# (400,000,000 + 30 + 60 + 400 + 100) × 5
= 2,000,002,950

Error Handling

Error Message Suggestion
Unknown refUnknown reference: "GROND_FLOOR"Did you mean: "GROUND_FLOOR"?
Missing propertyProperty "xyz" not found on "SHOP"Check available props
SyntaxExpected "+" or "-" …Raw PEG.js error
Did-you-mean uses Levenshtein distance for typo suggestions.

Grammar

View the full source (24 rules).

Start     = _ expr:Expression _          → number
Expression = head:Term tail:(_ AddOp _ Term)* → +, -
Term      = head:Factor tail:(_ MulOp _ Factor)* → *, /, PER
Factor    = Paren / PropRef / VarRef / Num
VarRef    = "@" name:Name
PropRef   = "@" name:Name "." prop:Name
Num       = num:Number _ mult:Multiplier? _ Unit?
Multiplier = "K" / "L" / "CR"
Unit      = "SQ" __ "MT" "R"? / "MTR" / "PER" __ "SQ" __ "MT" "R"?

How It Works

  1. Definition lines are parsed with a regex to extract name → value.
  2. Object values ({key: val, …}) are recursively parsed — each value is an expression.
  3. The expression is parsed by PEG.js against the resolved context.
  4. Results display instantly; errors are caught and annotated with suggestions.
The grammar is context-free, so syntax validation doesn’t need variable values. Runtime errors (unknown references) are caught during evaluation.