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.
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.
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).
grammar.pegjs file to your own terminology.
NAME = value or NAME - value. Values can be plain numbers, numbers with multipliers/units, or objects.@NAME, @OBJ.prop, operators + - * / PER, and parentheses.| Construct | Example | Result |
|---|---|---|
| Variable reference | @GROUND_FLOOR | 400,000,000 |
| Object property | @SHOP.space | 100 |
| Thousand (×1000) | 400000 K | 400,000,000 |
| Lakh (×100,000) | 5 L | 500,000 |
| Crore (×10M) | 2 CR | 20,000,000 |
| Area annotation | 100 SQ MTR | 100 (stripped) |
| Rate annotation | 5 PER SQ MTR | 5 (stripped) |
| Division | 10 PER 2 | 5 |
| Grouping | (10 + 20) * 3 | 90 |
| Form | Example |
|---|---|
| Simple dash | GROUND_FLOOR - 400000 K SQ MTR |
| Simple equals | APARTMENT_1 = 30 SQ MTR |
| Object | SHOP = {space: 100 SQ MTR, cost: 5 PER SQ MTR} |
@NAME in expressions.
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 | Message | Suggestion |
|---|---|---|
| Unknown ref | Unknown reference: "GROND_FLOOR" | Did you mean: "GROUND_FLOOR"? |
| Missing property | Property "xyz" not found on "SHOP" | Check available props |
| Syntax | Expected "+" or "-" … | Raw PEG.js error |
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"?
name → value.{key: val, …}) are recursively parsed — each value is an expression.