Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Expressif.Syntax

Expressif.Syntax provides the Tree-sitter parser for the Expressif expression language, together with bindings for supported programming languages.

The parser defines the concrete syntax of Expressif independently from its runtime implementations. It is intended to provide a common syntax foundation for the C#, Python and TypeScript implementations of Expressif, as well as editor tooling and language-server support.

About | Repository structure | Development | Releases

About

Project: Expressif Tree-sitter

Releases: GitHub Release GitHub Release Date licence badge

Dev. activity: GitHub last commit Still maintained GitHub commit activity

Continuous integration builds: CI

Status: stars badge Bugs badge Features badge

Purpose

Expressif.Syntax separates the syntax of the Expressif language from its runtime semantics.

The Tree-sitter grammar parses source text into a syntax tree while preserving syntactic constructs such as shorthands. Language-specific bindings can then translate this tree into the semantic representation expected by an Expressif implementation.

For example:

.foo

is represented syntactically as a field-access construct, while:

field(foo)

is represented as a regular function call. Both can later be bound to the same semantic operation:

field(foo)

This separation allows the same parser to support:

  • Expressif for C#
  • Expressif for Python
  • Expressif for TypeScript
  • language servers
  • syntax highlighting and other editor tooling

Structural access

Expressif distinguishes record fields from elements of ordered values:

.name       named field of the current record
.0          positional field of the current record
^.name      named field of the original immutable input record
^.0         positional field of the original immutable input record
$0          first element of the current tuple or array
$1          second element of the current tuple or array
$^0         last element of the current tuple or array
$^1         second-to-last element of the current tuple or array

Record access always uses . for navigation. A leading ^ changes the root from the current pipeline value to the original immutable input; it does not change how fields are selected. Access can be chained for nested records, for example .customer.address or ^.customer.0. The former bracket forms [name] and [0] are replaced by ^.name and ^.0 respectively.

Element positions are zero-based. $n counts from the beginning and $^n counts from the end. The parser represents both tuple and array access with the same positional_element_access node; downstream binders decide whether the runtime value supports positional access and how invalid or out-of-range access is handled.

Repository structure

.
├── grammar.js
├── tree-sitter.json
├── package.json
├── src/
│   ├── parser.c
│   ├── grammar.json
│   └── node-types.json
├── bindings/
│   ├── csharp/
│   ├── python/
│   └── typescript/
├── queries/
│   └── highlights.scm
└── test/

grammar.js is the source definition of the Expressif grammar.

The files under src/ are generated by Tree-sitter and are committed to source control so consumers do not need the Tree-sitter CLI to build the parser.

Language-specific integration is located under bindings/.

Development

Install the dependencies:

npm install

Generate the parser:

npx tree-sitter generate

Run the grammar tests:

npx tree-sitter test

The grammar should remain independent from the Expressif function catalogue. Parsing determines the syntactic structure of an expression; resolution of functions, predicates, accumulators and their accepted arguments belongs to the language-specific semantic binding layer.

Releases

For every push to main, the release workflow independently validates the parser and all bindings, builds the release packages, and calculates the repository version with GitVersion. When validation succeeds and the calculated semantic version has a patch component of 0, it creates the corresponding vX.Y.0 tag and GitHub release. Other versions complete package validation without creating a tag or release.

Each GitHub release contains every validated package produced by scripts/package.ps1:

  • the TypeScript/Node package
  • the Python wheel and source distribution
  • the C# NuGet package
  • the native parser source archive

Only the C# package is currently published to an external registry. NuGet publication uses GitHub OIDC trusted publishing to obtain a short-lived API key, so no long-lived NuGet API key is stored in the repository. Configure the trusted publishing policy on NuGet.org with these values:

  • Repository Owner: Seddryck
  • Repository: Expressif.Syntax
  • Workflow File: release.yml
  • Environment: leave blank

The policy's NuGet user must be Seddryck, matching the NuGet/login step in the workflow. Python and TypeScript/Node packages remain available as GitHub release artifacts until PyPI and npm publishing are implemented.

Related projects

About

Parser and language bindings for the Expressif language.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages