Parsec: one formula language shared across platforms

Business formulas must produce the same result wherever they are calculated. I worked on Parsec, a C++ library that interprets equations in compiler-style stages, and independently developed parsec-web, its WebAssembly version.

Contribution
Team and individual contribution Library development; individual WebAssembly version
Context
Oxeanbits · library shared across platforms

Context

Business systems often store rules as formulas and equations. At Oxeanbits, those formulas had to be evaluated in different contexts, from the backend to web and mobile applications.

Parsec is the equation-evaluation library built for that. Its C++ core was built from muparserx, an open source library, and received contributions from other people at Oxeanbits. I do not present it as exclusively my own work.

Problem

When each platform implements its own interpretation of a formula, small differences creep in: operator precedence, type handling, error messages. The same calculation can produce different results on the server and in the app, and the difference only surfaces for the people using the system.

Invalid formulas also need to be rejected clearly before execution, instead of failing halfway through a calculation.

My responsibility

I worked on developing Parsec, whose interpretation follows typical compiler stages: tokenization, syntax analysis and semantic analysis before evaluation.

I independently developed parsec-web, the WebAssembly version that brings this interpretation to the browser. That is a specific contribution of mine; it does not mean I single-handedly built every product or integration around the library.

Decision

The architectural intention was to define a shared language for formulas and equations, interpreted by a common core and consumed across backend, web, mobile and offline scenarios, instead of letting each platform reinterpret the rules.

That describes the project's goal, not proof that every target shipped. There are public repositories for use in Ruby, the parsec gem, and on the web, parsec-web.

Alternatives and trade-offs

Present-day analysis written for this site. It is not a record of the alternatives evaluated at the time.

  • Reimplementing the interpreter in each language removes the integration layer, but multiplies the work and the chances of platforms drifting apart.
  • A shared core keeps correctness in one place. In exchange, it needs a bridge for each platform, such as WebAssembly in the browser, and tests that confirm the same behavior across environments.

Implementation

Evaluating a formula goes through stages, each with a clear responsibility.

  1. Tokenization

    The expression is split into meaningful units: numbers, variables, operators, functions and parentheses.

  2. Syntax analysis

    Tokens are arranged into a structure that respects precedence and grouping, such as an expression tree.

  3. Semantic analysis

    The structure is validated before execution: operations must make sense for the types involved, and errors are reported clearly.

  4. WebAssembly

    In parsec-web, the C++ core is compiled to WebAssembly with Emscripten and exposed through a JavaScript library. Instead of sending each formula to the backend, the browser evaluates it locally with the same logic, which also makes offline use possible.

Visualization

Stage 1 of 5: Expression

Valid formula

01 · Expression

quantity * price * (1 - discount)

02 · Tokens

  • quantityvariable
  • *operator
  • pricevariable
  • *operator
  • (parenthesis
  • 1number
  • -operator
  • discountvariable
  • )parenthesis

03 · Structure

04 · Validation

  • Variables defined: quantity, price, discount
  • The * operator receives two numbers
  • The - operator receives two numbers

05 · Result

108

3 × 40 × (1 − 0.1) = 108

Example values: quantity = 3 · price = 40 · discount = 0.1

Formula with an error

01 · Expression

quantity * price * (1 - "10%")

02 · Tokens

  • quantityvariable
  • *operator
  • pricevariable
  • *operator
  • (parenthesis
  • 1number
  • -operator
  • "10%"text
  • )parenthesis

03 · Structure

04 · Validation

  • Variables defined: quantity, price
  • The * operator receives two numbers
  • The - operator receives a number and a text value

05 · Result

The "-" operator received a number and a text value. The formula is rejected before any calculation.

Example values: quantity = 3 · price = 40

Text description

Valid formula

  1. Expression: quantity * price * (1 - discount). The formula text, as someone would write it in a business rule.
  2. Tokens: quantity (variable), * (operator), price (variable), * (operator), ( (parenthesis), 1 (number), - (operator), discount (variable), ) (parenthesis). Tokenization separates numbers, variables, operators and parentheses.
  3. Structure: Multiplication of (quantity × price) by (1 − discount). The parentheses make the subtraction happen before the final multiplication. Syntax analysis arranges the tokens into a tree that respects precedence and parentheses.
  4. Validation: Variables defined: quantity, price, discount (ok); The * operator receives two numbers (ok); The - operator receives two numbers (ok). All checks passed.
  5. Result: 3 × 40 × (1 − 0.1) = 108

Formula with an error

  1. Expression: quantity * price * (1 - "10%"). The formula text, as someone would write it in a business rule.
  2. Tokens: quantity (variable), * (operator), price (variable), * (operator), ( (parenthesis), 1 (number), - (operator), "10%" (text), ) (parenthesis). Tokenization separates numbers, variables, operators and parentheses.
  3. Structure: Multiplication of (quantity × price) by (1 − "10%"). The structure is syntactically valid: the problem only shows up in semantic analysis. Syntax analysis arranges the tokens into a tree that respects precedence and parentheses.
  4. Validation: Variables defined: quantity, price (ok); The * operator receives two numbers (ok); The - operator receives a number and a text value (fails).
  5. Result: The "-" operator received a number and a text value. The formula is rejected before any calculation. Not evaluated. The error is reported before execution.
Conceptual illustration Conceptual illustration of the stages. The syntax and values are simplified examples; this is not Parsec's actual grammar or execution. Nothing is calculated in your browser: the results were defined in advance.

Outcome

parsec-web brings formula evaluation to the browser, in line with the idea of a single language across platforms. The repository is public.

The case shows the kind of problem I enjoy: when consistency across environments depends on decisions about language, parsing and integration, not just on writing more code.

Technologies

  • C++
  • Ruby
  • WebAssembly
  • JavaScript

Tell me about the problem you need to solve

Hiring for your team or solving a product problem? Share the context and the outcome you need. We can discuss a Senior Full Stack Developer or Tech Lead role, project development or technical consulting.

WhatsApp

+55 71 99705-3401

Opens WhatsApp with a starter message you can edit. Nothing is sent automatically.

You can also find me on GitHub and LinkedIn.