PHPackages                             danielsmith/alap - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. danielsmith/alap

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

danielsmith/alap
================

Alap expression parser — resolve tag-based link expressions server-side

v0.3.3(2mo ago)02Apache-2.0PHPPHP &gt;=8.1

Since Mar 26Pushed 2mo agoCompare

[ Source](https://github.com/DanielSmith/alap-php)[ Packagist](https://packagist.org/packages/danielsmith/alap)[ Docs](https://alap.info)[ RSS](/packages/danielsmith-alap/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (1)Versions (4)Used By (0)

Alap Expression Parser — PHP
============================

[](#alap-expression-parser--php)

[Alap](https://github.com/DanielSmith/alap) is a JavaScript library that turns links into dynamic menus with multiple curated targets. This is the server-side PHP port of the expression parser, enabling expression resolution in PHP servers without a Node.js sidecar.

What's included
---------------

[](#whats-included)

- **`ExpressionParser.php`** — Recursive descent parser for the Alap expression grammar, macro expansion, regex search, config merging, ReDoS validation

What's NOT included
-------------------

[](#whats-not-included)

This is the server-side subset of `alap/core`. It covers expression parsing, config merging, and regex validation — everything a server needs to resolve cherry-pick and query requests.

Browser-side concerns (DOM rendering, menu positioning, event handling, URL sanitization) are handled by the JavaScript client and are not ported here.

Supported expression syntax
---------------------------

[](#supported-expression-syntax)

```
item1, item2              # item IDs (comma-separated)
.coffee                   # tag query
.nyc + .bridge            # AND (intersection)
.nyc | .sf                # OR (union)
.nyc - .tourist           # WITHOUT (subtraction)
(.nyc | .sf) + .open      # parenthesized grouping
@favorites                # macro expansion
/mypattern/               # regex search (by pattern key)
/mypattern/lu             # regex with field options

```

Usage
-----

[](#usage)

```
use App\Alap\ExpressionParser;

$config = [
    'allLinks' => [
        'item1' => ['label' => 'Example', 'url' => 'https://example.com', 'tags' => ['demo']],
        'item2' => ['label' => 'Other',   'url' => 'https://other.com',   'tags' => ['demo', 'test']],
    ],
    'macros' => [
        'all' => ['linkItems' => '.demo'],
    ],
];

// Low-level: get matching IDs
$parser = new ExpressionParser($config);
$ids = $parser->query('.demo');              // ['item1', 'item2']
$ids = $parser->query('.demo - .test');      // ['item1']

// Cherry-pick: expression -> [id => link] associative array
$subset = ExpressionParser::cherryPick($config, '.test');
// ['item2' => ['label' => 'Other', ...]]

// Resolve: expression -> array of link objects with 'id' key
$results = ExpressionParser::resolve($config, '.demo');
// [['id' => 'item1', 'label' => 'Example', ...], ['id' => 'item2', ...]]

// Merge multiple configs
$merged = ExpressionParser::mergeConfigs($config1, $config2);
```

Installation
------------

[](#installation)

Copy `ExpressionParser.php` into your project (update the namespace as needed), or install via Composer:

```
composer require danielsmith/alap
```

Used by
-------

[](#used-by)

- [laravel-sqlite](https://github.com/DanielSmith/alap/tree/main/examples/servers/laravel-sqlite) server

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance87

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~16 days

Total

3

Last Release

64d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9d5831ad98a4b2c650af237bc685007a11efb1d08afdc82994b19f4f78bfa712?d=identicon)[danielsmith](/maintainers/danielsmith)

---

Top Contributors

[![DanielSmith](https://avatars.githubusercontent.com/u/167197?v=4)](https://github.com/DanielSmith "DanielSmith (5 commits)")

---

Tags

menulinksalapexpression-parser

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/danielsmith-alap/health.svg)

```
[![Health](https://phpackages.com/badges/danielsmith-alap/health.svg)](https://phpackages.com/packages/danielsmith-alap)
```

###  Alternatives

[mck89/peast

Peast is PHP library that generates AST for JavaScript code

19037.7M41](/packages/mck89-peast)[sauladam/shipment-tracker

Parses tracking information for several carriers, like UPS, USPS, DHL and GLS by simply scraping the data. No need for any kind of API access.

9642.0k](/packages/sauladam-shipment-tracker)[moonshine/layouts-field

Field for repeating groups of fields for MoonShine

107.9k](/packages/moonshine-layouts-field)[tcds-io/php-jackson

A lightweight, flexible object serializer for PHP, inspired by FasterXML/jackson

112.9k10](/packages/tcds-io-php-jackson)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
