tame/tamer
Mike Gerwitz b973d36862 tamer: xir: Initial re-introduction of AttrEnd
AttrEnd was initially removed in
0cc0bc9d5a (and the commit prior), because
there was not a compelling reason to use it over a lookahead
operation (returning a token via the a dead state transition); `AttrEnd`
simply introduced inconsistencies between the XIR reader (which produced
AttrEnd) and internal XIR stream generators (e.g. the lowering operations
into XIR->XML, which do not).

But now that parsers are performing aggregation---in particular the
attribute parser-generator `xir::parse::attr`---this has become quite a
pain, because the dead state is an actionable token.  For example:

  1. Open
  2. Attr
  3. Attr
  4. Open
  5. ...

In the happy case, token #4 results in `Parsed::Incomplete`, and so can just
be transformed into the object representing the aggregated attributes.  But
even in this happy path, it's ugly, and it requires non-tail recursion on
the parser which requires a duplicate stack allocation for the
`ParserState`.  That violates a core principle of the system.

But if there is an error at #4---e.g. an unexpected element---then we no
longer have a `Parsed::Incomplete` to hijack for our own uses, and we'd have
to introduce the ability to return both an error and a token, or we'd have
to introduce the ability to keep a token of lookahead instead of reading
from the underlying token stream, but that's complicated with push parsers,
which are used for parser composition.  Yikes.

And furthermore, the aggregation has caused me to introduce the ability to
override the dead state type to introduce both a token of lookahead and
aggregation information.  This complicates the system and is going to be
confusing to others.

Given all of this, AttrEnd does now seem appropriate to reintroduce, since
it will allow processing of aggregate operations when encountering that
token without having to worry about the above scenario; without having to
duplicate a `ParseState` stack; without having to hijack dead state
transitions for producing our aggregate object; and everything else
mentioned above.

This commit does not modify those abstractions to use AttrEnd yet; it
re-introduces the token to the core system, not the parser-generators, and
it doesn't yet replace lookahead operations in the parsers that use
them.  That'll come next.  Unlike the commit that removed it, though, we are
now generating proper spans, so make note of that here.  This also does not
introduce the concept to XIRF yet, which did not exist at the time that it
was removed, so XIRF is filtering it out until a following commit.

DEV-7145
2022-06-29 11:02:02 -04:00
..
benches tamer: xir: Introduce {Ele,Open,Close}Span 2022-06-24 14:16:29 -04:00
build-aux Copyright year update 2022 2022-05-03 14:14:29 -04:00
src tamer: xir: Initial re-introduction of AttrEnd 2022-06-29 11:02:02 -04:00
.gitignore TAMER: Initial commit 2019-11-18 14:05:47 -05:00
Cargo.lock tamer: Cargo.toml: Remove lazy_static 2022-06-24 14:18:04 -04:00
Cargo.toml tamer: Cargo.toml: Remove lazy_static 2022-06-24 14:18:04 -04:00
Makefile.am Copyright year update 2022 2022-05-03 14:14:29 -04:00
README.md Copyright year update 2022 2022-05-03 14:14:29 -04:00
autogen.sh Copyright year update 2022 2022-05-03 14:14:29 -04:00
bootstrap Copyright year update 2022 2022-05-03 14:14:29 -04:00
configure.ac Copyright year update 2022 2022-05-03 14:14:29 -04:00
rustfmt.toml tamer/rustfmt (max_width): Set to 80 2019-11-27 09:15:15 -05:00

README.md

TAME in Rust (TAMER)

TAME was written to help tame the complexity of developing comparative insurance rating systems. This project aims to tame the complexity and performance issues of TAME itself. TAMER is therefore more tame than TAME.

TAME was originally written in XSLT. For more information about the project, see the parent README.md.

Building

To bootstrap from the source repository, run ./bootstrap.

To configure the build for your system, run ./configure. To build, run make. To run tests, run make check.

You may also invoke cargo directly, which make will do for you using options provided to configure.

Note that the default development build results in terrible runtime performance! See [#Build Flags][] below for instructions on how to generate a release binary.

Build Flags

The environment variable CARGO_BUILD_FLAGS can be used to provide additional arguments to cargo build when invoked via make. This can be provided optionally during configure and can be overridden when invoking make. For example:

# release build
$ ./configure && make CARGO_BUILD_FLAGS=--release
$ ./configure CARGO_BUILD_FLAGS=--release && make

# dev build
$ ./configure && make
$ ./configure CARGO_BUILD_FLAGS=--release && make CARGO_BUILD_FLAGS=

Hacking

This section contains advice for those developing TAMER.

Running Tests

Developers should be using test-driven development (TDD). make check will run all necessary tests.

Code Format

Rust provides rustfmt that can automatically format code for you. This project mandates its use and therefore eliminates personal preference in code style (for better or worse).

Formatting checks are run during make check and, on failure, will output the diff that would be applied if you ran make fmt (or make fix); this will run cargo fmt for you (and will use the binaries configured via configure).

Since developers should be doing test-driven development (TDD) and therefore should be running make check frequently, the hope is that frequent feedback on formatting issues will allow developers to quickly adjust their habits to avoid triggering formatting errors at all.

If you want to automatically fix formatting errors and then run tests:

$ make fmt check

Benchmarking

Benchmarks serve two purposes: external integration tests (which are subject to module visibility constraints) and actual benchmarking. To run benchmarks, invoke make bench.

Note that link-time optimizations (LTO) are performed on the binary for benchmarking so that its performance reflects release builds that will be used in production.

The configure script will automatically detect whether the test feature is unstable (as it was as of the time of writing) and, if so, will automatically fall back to invoking nightly (by running cargo +nightly bench).

If you do not have nightly, run you install it via rustup install nightly.