Giter Club home page Giter Club logo

trieste's Introduction

Project Trieste

Project Trieste is an experimental term rewriting system for experimental programming language development.

This research project is at an early stage and is open sourced to facilitate academic collaborations. We are keen to engage in research collaborations on this project, please do reach out to discuss this.

The project is not ready to be used outside of research.

Getting Started

If you want to dive right into understanding how to use Trieste, take a look at the infix tutorial language, which will walk you through implementing a simple calculator language in Trieste.

Using Trieste

Trieste is a header-only C++20 library. To get started, you'll need to define your own trieste::Driver, and run it from main:

#include <trieste/driver.h>

int main(int argc, char** argv)
{
  // Define your driver...
  trieste::Driver driver(...);
  return driver.run(argc, argv);
}

Building the Samples

Here's an example of how to build the infix sample and run the self-tests. Other build systems and compilers may work as well.

git clone https://github.com/microsoft/trieste
cd trieste
mkdir build
cd build
cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=clang++-14
ninja install
./dist/infix/infix test

Using Trieste in Your Project

You can use Trieste via FetchContent by including the following lines in your CMake:

FetchContent_Declare(
  trieste
  GIT_REPOSITORY https://github.com/microsoft/Trieste
  GIT_TAG        a2a7fada4ab5250a4f8d1313b749ad336202841b
)

FetchContent_MakeAvailable(trieste)

And then adding it as a target link library, e.g.

target_link_libraries(verona
  Threads::Threads
  CLI11::CLI11
  trieste::trieste
  )

Contributing

If you are interested in contributing to Trieste, please see our contributing document.

trieste's People

Contributors

matajoh avatar matteb10 avatar microsoftopensource avatar mjp41 avatar sblessing avatar seantallen avatar sylvanc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

trieste's Issues

Semantics of predicate patterns

The pattern matching semantics has some surprising corner cases related to predicate patterns, i.e., patterns that do not consume tokens. I take predicate patterns to mean lookahead (++p and --p) as well as the "positional" patterns In(ty), Start and End.

For example, let's look at what happens when negating predicates with the ! pattern:

!(Start) * T(Foo) >>
  [](Match&) { return NodeDef::create(Bar); }

Running this on foo foo bar results in bar bar, since !(Start) matches on the first foo and consumes it together with the subsequent foo. I would say the expected result here is foo bar bar. If we instead match on T(Bar) * !(Start), nothing happens since ! only matches if there is a term to consume in that position.

More generally, I would expect the negation of a zero-width pattern to consume zero terms. The semantics for negation of patterns longer than one is also unintuitive:

!(T(Foo) * T(Bar)) * T(Bar) >>
  [](Match&) { return NodeDef::create(Baz); }

Running this on foo bar bar currently results in foo baz, whereas running it on foo foo bar does nothing. In the first case, the negation pattern is successfully matched against bar bar and then the first bar is consumed, after which T(Bar) matches on the second bar. In the second case, although foo foo matches the negation pattern, only the first foo is consumed, so the second foo does not match T(Bar). After advancing the cursor foo bar fails to match the negation pattern.

Another corner case is pattern matching the children of a zero-width sequence:

Start >> T(Foo)[Foo] >>
  [](Match& _) { return _(Foo); }

This example currently causes a segfault, since there are no children in the sequence matched by Start. More reasonable would be to fail matching, or possibly to (ideally statically) disallow the pattern since it will never succeed.

A related question is how to interpret matching on the the children of a sequence of more than one term:

(T(Foo) * T(Bar)) << (Any[Any]) >>
  [](Match& _) { return _(Any); }

Currently, Any binds to the first child of whatever comes first in the sequence (here Foo) which might be what we want. Other possible semantics include failing, or letting Any bind to the first child of every node in the parent pattern. If we go for requiring well formedness, we could disallow any <<-pattern where the parent pattern does not match exactly one term.

The `++` pattern is too greedy?

I was expecting the pattern Any++ * T(Bar) to match the sequence Foo Foo Foo Bar, just as the regular expression .*b matches aaab, but it seems like the Any++ matches all of Foo Foo Foo Bar, meaning the whole pattern fails to match (since there is no Bar after that sequence). I don't know if this is by design, nor what the consequences would be of making it more like the kleene star, but I thought I would bring it up for discussion.

My use case was for matching a Y inside an X, where the last child of Y is a Z (for reasonable values of X, Y, and Z):

In(X) * T(Y) << (Any++ * T(Z) * End)

If I didn't care about both the X and the Y I could just have T(Z) * End, but I now it's important that the Y is in an X and has the children specified. In this particular case I can do (!T(Z))++ * T(Z), but in general this might not be satisfactory.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.