Compare commits

...
887 Commits
Author SHA1 Message Date
Ulya Trofimovich 9682dcd2b2 Github Actions: try 'oracle-openjdk' as 'redhat' has no macOS support. 2026-09-06 22:07:26 +01:00
Ulya Trofimovich 745a042652 Github Actions: also fix JDK version.
Pick the most recent one supported by 'redhat' distribution: 21.
2026-09-06 21:49:30 +01:00
Ulya Trofimovich b1720e831c Github Actions: fix infra error with setup-java@v6.
Pick 'redhat' distribution that packages OpenJDK, as the previously used
'adopt' distribution is no longer supported with setup-java@v6.
2026-09-06 21:44:31 +01:00
dependabot[bot] 1022a1cb0f Actions(deps): Bump actions/setup-java from 5 to 6
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5 to 6.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-31 21:03:12 +01:00
Ulya Trofimovich e485c5d572 Release 4.6. 2026-08-29 22:26:02 +01:00
Ulya Trofimovich 957bc5359b Update CHANGELOG for release 4.6. 2026-08-29 22:15:34 +01:00
Ulya Trofimovich c117b7d1c9 Revert "Avoid new features added in 4.0 in C/C++ examples."
This reverts commit 5cea17c8fe.

Reason for revert: enough time has passed and most distributions have
updated to re2c version 4.0 or higher.

This fixes bug #507 "Update C/C++ examples".
2026-08-29 21:20:36 +01:00
Chun Pong Lam bda3544af9 Add Zig computed-continue optimization 2026-08-26 14:46:23 +01:00
dependabot[bot] dcc7411099 Actions(deps): Bump actions/setup-python from 6 to 7
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6 to 7.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-20 19:47:54 +01:00
94xhn 9baaabbf4a Fix negative char2class[] index on high-byte input in libre2c DFA matchers
lib/regexec_dfa.cc (regexec_dfa(), regparse_dfa()) and
lib/regexec_dfa_multipass.cc (forward_pass(), shared by
regexec_dfa_multipass<>, regparse_dfa_multipass<>, and
regtstring_dfa_multipass<>) read the next input character as
`*p++` into a plain `int32_t`/`chr`, then use it directly to index
`preg->char2class[]`. On platforms where `char` is signed (the
default for x86/x64), any input byte >= 0x80 sign-extends to a
negative value, so `char2class[c]` reads before the start of the
257-element `size_t` array allocated in regcomp() -- an
out-of-bounds heap read (observed to segfault in a minimal
regcomp()/regexec() reproduction with a high-byte input string).

Fix by reading the byte through `static_cast<uint8_t>(...)` before
using it as an index, matching the pattern already used for the
same purpose in the NFA matchers (regexec_nfa_leftmost.cc,
regexec_nfa_leftmost_trie.cc, regexec_nfa_posix.cc,
regexec_nfa_posix_trie.cc). The `== 0` end-of-input check is
unaffected since 0 is unchanged by the cast.

Verified: rebuilt libre2c (RE2C_BUILD_LIBS=ON) and confirmed
test_libre2c passes before and after the change; a targeted
regcomp()/regexec() check over all 254 non-newline byte values
0x01-0xFF segfaults on the pre-fix code and passes cleanly after
the fix.
2026-07-19 22:51:50 +01:00
dependabot[bot] f1a46ca73a Actions(deps): Bump actions/cache from 5 to 6
Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-29 21:09:51 +01:00
dependabot[bot] fccdffc979 Actions(deps): Bump actions/checkout from 6 to 7
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-24 21:49:44 +01:00
Ulya Trofimovich ae610e4ecf CMakePresets.json: update VS version.
The former VS 17 2022 version is no longer supported by Github Actions.
2026-06-23 21:17:58 +01:00
Ryan Carsten Schmidt 86137ce914 Use std::max_align_t instead of max_align_t.
Fixes build with old versions of clang.
2026-04-24 21:26:36 +01:00
Ulya Trofimovich c028cdd42b TDFA paper: apply corrections by Lisa Felidae. 2026-03-29 22:09:29 +01:00
Ulya Trofimovich 8a44906f5c Release 4.5.1. 2026-03-27 21:29:04 +00:00
Ulya Trofimovich 3122b9a415 Update CHANGELOG for release 4.5.1. 2026-03-27 21:09:25 +00:00
Ulya Trofimovich 2ab394e9d5 Docs: mention the new include files for Unicode blocks and properties. 2026-03-27 21:06:50 +00:00
Ulya Trofimovich e63ad223f5 Add missing include files to the distribution.
This fixes #573.
2026-03-27 21:01:55 +00:00
Ulya Trofimovich 3e3b91d75a Release 4.5. 2026-03-23 20:55:16 +00:00
Ulya Trofimovich 7059b54eb9 Update CHANGELOG for release 4.5. 2026-03-22 22:39:16 +00:00
Ulya Trofimovich c88a723fc4 Remove obsolete Unicode files generator. 2026-03-22 22:22:51 +00:00
Ulya Trofimovich 44d56c2804 Implement Unicode case mapping for case-insensitive string literals.
Do this for all Unicode encodings (UTF8, UTF16 and UTF32), and also for UCS2.

This addresses bug #235 "Unicode character classes".
2026-03-22 22:22:51 +00:00
Ulya Trofimovich 4685c639cd Clean up Unicode generator using tags instead of blocks. 2026-03-22 22:22:51 +00:00
Ulya Trofimovich 6a71463d6d Add derived Unicode properties to include/unicode_properties.re. 2026-03-22 22:22:51 +00:00
Ulya Trofimovich 79596e186d Generate include file for Unicode properties.
This partially addresses bug #235 "Unicode character classes".
2026-03-22 22:22:51 +00:00
Ulya Trofimovich 94d1ceb2e9 Update Unicode files to the latest standard. 2026-03-22 22:22:51 +00:00
Ulya Trofimovich e4ba9a90b2 Remove Unicode category tests for encoding policies "fail" and "substitute".
They mostly duplicate the "ignore" policy (except for the categories that
include surrogates). These policies are also covered by the Unicode block tests.
2026-03-22 22:22:50 +00:00
Ulya Trofimovich fce0e9cbd1 Implement generation of Unicode categories tests in the new generator. 2026-03-22 22:22:50 +00:00
Ulya Trofimovich 8fcbced4e4 Clean up Unicode generator code (split large functions). 2026-03-22 22:22:50 +00:00
Ulya Trofimovich 92a98bcf1e Implement generation of Unicode blocks tests in the new generator.
Tests have changed due to the changes in the Unicode standard - the old test
were generated using Haskell "Charset" library, which supports unknown version
of Blocks.txt (none of the existing version matches exactly, but Unicode 4.0 is
somewhat close). There are also other changes in the tests, mostly
simplification and cleanup of the generated code.
2026-03-22 22:22:50 +00:00
Ulya Trofimovich a76b9f592c Use uint16_t for UTF-16 code points in utf16::{lead,trail}_surr.
Previously uint32_t was used to avoid static_cast on 16-bit results of
arithmetic operations on 32-bit values.
2026-03-22 22:22:50 +00:00
Ulya Trofimovich c30687f0f1 Use uint8_t for UTF-8 code points in utf8::rune_to_bytes.
Previously uint32_t was used to avoid static_cast on 8-bit results of
arithmetic operations on 32-bit values.
2026-03-22 22:22:50 +00:00
Ulya Trofimovich dd05aab240 Implement new generator for unicode_blocks.re.
The new generator is based on the official Blocks.txt file from the unicode.org
website. The generated result has changed; it's unclear why some of the blocks
are missing in the Haskell "Charset" library - most likely the library was not
updated for Unicode 15.1.0 (although the categories' definitions correspond to
Unicode 15.1.0).

This partially addresses bug #235 "Unicode character classes".
2026-03-22 22:22:50 +00:00
Ulya Trofimovich 5b0e960177 Add Unicode include file unicode_blocks.re.
Don't use it in auto generated tests, because that creates a problem with
include paths: they are relative to the test directory, which makes the
error messages different based on the build directory (so the tests fail).

Use the old generator based on haskell "Charset" library in order to avoid
changes in the generated code - the library has some discrepancies with
https://unicode.org/Public/15.1.0/ucd/Blocks.txt.

Update test results - the changes have been verified with
test/__run_unicode_tests.sh.

This partially addresses bug #235 "Unicode character classes".
2026-03-22 22:22:50 +00:00
Ulya Trofimovich 04e7048069 Implement new generator for unicode_categories.re.
The new generator is based on the official UnicodeData.txt file from the
unicode.org website. After some experimentation, I found that the the
Unicode standard supported by the previously used Haskell "Charset" library
is 15.1.0, so this is the version used in the new generator. The generated
include file unicode_categories.re is identical to the old one, which
verifies correctness of the new generator.

This partially addresses bug #235 "Unicode character classes".
2026-03-22 22:22:50 +00:00
Ulya Trofimovich a92dad12d8 Render characters compactly in Unicode header and tests.
Previously edge cases like 0xFF were rendered as \u0ff rather than \xff.

The difference in the generated files was verified with:
  `git diff --word-diff=color --word-diff-regex='-?\\[a-zA-Z0-9]+'`
2026-03-22 22:22:50 +00:00
Ulya Trofimovich 0011cab9f9 Render one-character ranges compactly in Unicode header and tests.
Previously even if lower and upper characters were the same, the range
would still be rendered with a dash rather than a single character.
This commit removes useless duplication.

The difference in the generated files was verified with:
  `git diff --word-diff=color --word-diff-regex='-?\\[a-zA-Z0-9]+'`
2026-03-22 22:22:50 +00:00
Ulya Trofimovich f1694c513f Regenerate Unicode tests and include header to support a newer standard.
Regenerate files using haskell script test/encodings/unicode_groups.hs
that is based on Data.Charset library (charser-0.3.12 package). The
script generates tests in test/unicode directory inplace and include
file unicode_categories.re.inc that needs to be copied to
include/unicode_categories.re.

Update test results. As there are substantial changes in the standard,
updates are also nontrivial. They have been verified with
test/__run_unicode_tests.sh.

The example for C was werified with examples/c/__run_all.sh scripts.
2026-03-22 22:22:50 +00:00
dependabot[bot] 55802e3b40 Actions(deps): Bump actions/upload-artifact from 6 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 11:13:01 +00:00
Ulya Trofimovich 18fc5091b9 Add tests for #571. 2026-02-03 21:48:21 +00:00
Ulya Trofimovich febeb97793 Fix null pointer dereference when actions are used without rules.
Null pointer dereference happened because the root TNFA state was null:
there were no rules for a block, but determinization still happened.

In this case re2c should emit an error and never even attempt
determinization. It was properly handled for blocks with start
conditions, but not for normal blocks.

This addresses #571 "[Bug] Segmentation Fault (NULL Dereference) in
re2c::closure_leftmost_dfs during determinization".
2026-02-03 21:33:11 +00:00
Ulya Trofimovich 04f1424210 TDFA paper: apply corrections by https://github.com/Raekye. 2026-01-16 21:50:29 +00:00
Ulya Trofimovich 1f8d826558 TDFA paper: apply corrections by Lisa Felidae. 2026-01-16 21:50:29 +00:00
Ulya Trofimovich 1dc02f7b70 Dot: use "dashed" style for non-consuming states.
This addresses bug #569 "Invalid DFA in -D output".
2025-12-28 14:12:10 +00:00
Gui Andrade 37350f906c [re2c.bzl] Always pass --no-generation-date
This prevents non-deterministic file generation which can cause a lot of issues in Bazel.
2025-12-23 21:00:53 +00:00
Ulya Trofimovich 8c758c7649 Release 4.4. 2025-12-20 20:36:43 +00:00
Ulya Trofimovich d46322fb89 Update CHANGELOG for release 4.4. 2025-12-20 13:14:52 +00:00
Ulya Trofimovich 5811f5ad65 Docs: add description of YYEND, code:yyend and .yyfill.enable. 2025-12-17 22:56:50 +00:00
Ulya Trofimovich ee0b1f6daf Docs: regenerate following recent changes in examples. 2025-12-17 21:53:03 +00:00
Ulya Trofimovich 82915e38ba Add tests for generalized $.
Note: for Haskell and monadic lexers in general I considered adding `yyend`
variable in order to allow monadic YYEND (similar to the existing `yyfill`
variable). However, this is not yet useful even for Haskell, because it's always
easy to store the end in a record field and define YYEND as a simple non-monadic
comparison expression. It won't be late to add `yyend` variable later in a
backwards compatible way (if the variable is empty, generate code the old way,
otherwise do it the new way), therefore I decided to postpone `yyend`addition
until such time when it's needed.
2025-12-17 21:44:14 +00:00
Ulya Trofimovich 67f50f6907 Allow tags after $ in regular expressions.
This is necessary in order to accommodate negative tags, which are added at the
end of the other alternative (the one that doesn't have tags). During TNFA
construction $ is moved past negative tags and placed immediately before the
final TNFA state. This ensures that there are no tags on the $-transition and we
don't have to append tag operations to incoming transitions when getting rid of
the $-transitions in TDFA.
2025-12-17 21:44:14 +00:00
Ulya Trofimovich bc5c3022d1 Rework detection of shadowed end-of-input rules.
Do it right after TDFA construction. This is only strictly necessary for
self-shadowed rules, but it's better to handle all end-of-input rules
together (especially since the previous analysis was still a hack in
the reversed-TDFA structure).
2025-12-17 21:44:14 +00:00
Ulya Trofimovich 827682202e Fix handling of self-shadowed end-of-input rules.
Also, add tests for generalized end-of-input symbol $ and tags.
2025-12-17 21:44:14 +00:00
Ulya Trofimovich 6fcfa14e15 Fix YYEND generation for "bounds checks with padding" method.
Generate YYEND before YYFILL. This order is makes sense because YYEND should be
faster than YYFILL. In fact, it is the only possible order, as YYFILL may not
return if it's impossible to supply enough input characters.

Don't generate YYEND on transition in the case of "sentinel with bounds checks"
method; instead, generate it in state. This doesn't make any difference on the
tests because YYEND is only needed in the "end" states that have a single
transition.
2025-12-17 21:44:14 +00:00
Ulya Trofimovich 0b5185c03a Allow $ to be used with any end-of-input handling method.
Prevously end-of-input symbol $ was only allowed with "sentinel with
bounds check" method (when `re2c:eof` configuration is set to a
nonnegative value). This commit removes the above restriction and
enables YYEND checks for all end-of-input handling methods. Code
generation is not quite right yet, as in some of the cases YYEND checks
are emitted after YYFILL, while they should go before it.

Internally the main challengege was adding $-transitions in TDFA for all
end-of-input handling methods, and to hide them when necessary depending
on the method. E.g. -Wunreachable-rules analysis must ignore them except
for the $-final states, unless "sentinel with bounds checks" method is
used.
2025-12-17 21:44:14 +00:00
Ulya Trofimovich 07d6f5f7f5 Initial implementation of YYEND check.
For the moment, YYEND is only supported for the "bounds checks with sentinel"
end-of-input handling method (the case of `re2c:eof` configuration). In this
case states that have transitions on symbos do not need YYEND check, as they
have the sentinel transition with YYLESSTHAN / YYFILL pair.
2025-12-17 21:44:14 +00:00
Ulya Trofimovich ab2d4b2504 Change default implementation of YYEND to be like YYLESSTHAN.
Namely, use `YYLIMIT <= YYCURSOR` rather than `YYLIMIT == YYCURSOR`.

The goal is to bridge the gap between YYEND and YYLESSTHAN in the case
of `re2c:eof`. $-final states that have outgoing transitions defer the
end of input check until matching `re2c:eof` symbol range on transition
(and then use YYLESSTHAN in the same way as non-$-final state would do).
But $-final states that are terminal (have no outgoing transitions on
symbols) use YYEND.

We can only bridge this gap in simple / record (not generic) API, and
only if YYFILL is disabled. Otherwise it has to be YYEND and YYLESSTHAN
as macros, and the distinction remains.

This commit does not compromise correctness of the generated code, as
YYCURSOR cannot read past YYLIMIT in a correct lexer, so if it was
correct before this commit it will be as correct after it.
2025-12-17 21:44:14 +00:00
Ulya Trofimovich 299bfc7fe0 Add a new API primitive YYEND.
Also, add the corresponding syntax file configuration `code:yyend` and
syntax file conditional `.yyfill.enable`.

The new API primitive will be used in the implementation of generalized
$ (the end of input symbol). If YYFILL is disabled, and the API used is
either simple or record (not generic API), then YYEND defaults to a
comparison `YYCURSOR == YYLIMIT`, otherwise it remains a macro to be
defined by the user.

We don't use a combination of YYLESSTHAN and YYFILL instead of the new
primitive for a number of reasons:

  - Using YYEND allows us to unify all codegen cases instead of having
    many different implementations based on YYFILL, storable state,
    generic API, etc.

  - Involving YYFILL would add runtime overhead: a possible function
    call instead of a simple inplace check, useless reiteration via
    YYFILL label (which is currently not even generated in these states)
2025-12-17 21:44:14 +00:00
Ulya Trofimovich 2ad0561e4f Move re2c:yyfill config in syntax files closer to the yyfill group. 2025-12-17 21:44:14 +00:00
Ulya Trofimovich 59677b5eb4 Change precedence for conflicting end of input rules.
This change breaks backwards compatibility. This is intentional, following
a period when -Wdeprecate-eof-rule has been a warning by default, now the
default is an error (-Werror-deprecate-eof-rule).

There are code generation changes: end of input rule is now handled as a
normal rue with positional precedence / inheritance order (it is no longer
a special rule like the default rule *). The changes in the code can be
observed with -Wno-error-deprecate-eof-rule (applied to the tests).
2025-12-17 21:44:14 +00:00
dependabot[bot] 82bfcce637 Actions(deps): Bump actions/cache from 4 to 5
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 20:52:09 +00:00
dependabot[bot] 6eb9718a67 Actions(deps): Bump actions/upload-artifact from 5 to 6
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 09:54:01 +00:00
Ulya Trofimovich 5513aff4c0 Revert "Go backend: add test for signed YYCTYPE."
This reverts commit b0d740994c.

Reason for revert: don't keep signed YYCTYPE examples for languages
that don't allow the user to do the incorrect thing (Go, Swift forbid
comparison of signed 8-bit type to literals that overflow it, like 0xFF;
Python, JS, OCaml don't even have a signed 8-bit type).
2025-12-09 21:55:02 +00:00
Ulya Trofimovich 43c7512c31 V backend: add test for signed YYCTYPE.
There's no need to fix examples, as they use `u8` and `u32`.

This addresses bug #561 "Incorrectness with ASCII signedness and range
(in C/C++)".
2025-12-08 21:40:40 +00:00
Ulya Trofimovich 28cca31af9 V backend: more updates in the examples/tests for the new version of V. 2025-12-08 21:21:11 +00:00
Ulya Trofimovich e98dbd359a V backend: specify type in variable initializer.
The code without exact types in variable initializers used to compile
in older versions of V, but not anymore.
2025-12-08 20:39:53 +00:00
Ulya Trofimovich eece38b1e6 Zig backend: add test for signed YYCTYPE.
There's no need to fix examples, as they use `u8` and `u32`.

This addresses bug #561 "Incorrectness with ASCII signedness and range
(in C/C++)".
2025-12-07 13:51:57 +00:00
Ulya Trofimovich 7553c68cb4 Zig backend: port one remaining test to ZIg 0.15. 2025-12-07 13:38:06 +00:00
Ulya Trofimovich 69ffc41706 Zig backend: port examples to Zig 0.15.
This fixes bug #565 "Migrate Zig examples to Zig 0.15".
2025-12-06 22:48:16 +00:00
Ulya Trofimovich 1a26160b69 Java backend: make YYCTYPE/YYPEEK work correctly with signed bytes.
Use `int` instead of `byte` for `YYCTYPE`, as `byte` is signed and therefore
incapable of holding the full range of literals generated by re2c (e.g. 0xFF).

use `Byte.toUnsignedInt` in YYPEEK in order to convert correctly from signed
bytes to `yych` of type `int`. Add a test that demonstrates the need for this.

Using `char` is fine, as it is 2-byte in Java and thus capable of holding
ASCII and UTF-8 range used in the examples.

This addresses bug #561 "Incorrectness with ASCII signedness and range
(in C/C++)".
2025-12-03 22:17:28 +00:00
Ulya Trofimovich 0b7572c30d Haskell backend: use unsigned YYCTYPE in examples. Add a test.
Only one example required fixing `Int` -> `Word`, others use `Word8`.

This addresses bug #561 "Incorrectness with ASCII signedness and range
(in C/C++)".
2025-12-02 22:14:51 +00:00
Ulya Trofimovich 5393573711 Rust backend: add test for signed YYCTYPE.
The generated code compiles only with `#[allow(overflowing_literals)]`,
and it requires `re2c:yych:conversion = 1`.

There's no need to fix examples, as they use `u8` and `u32`.

This addresses bug #561 "Incorrectness with ASCII signedness and range
(in C/C++)".
2025-12-02 21:32:45 +00:00
Ulya Trofimovich b0d740994c Go backend: add test for signed YYCTYPE.
The generated code for the test does not compile - Go rejects it:
    signed_yyctype.go:34:9: cannot use yyinput[yycursor] (value of type byte)
                            as int8 value in assignment
    signed_yyctype.go:35:14: 0xFF (untyped int constant 255) overflows int8

There's no need to fix examples, as they use `byte` (which is unsigned
8-bit type) or `uint32`.

This addresses bug #561 "Incorrectness with ASCII signedness and range
(in C/C++)".
2025-12-02 21:28:17 +00:00
Ulya Trofimovich e2ee1bfa9d D backend: add test for signed YYCTYPE.
There's no need to fix examples, as they use `char` (which is unsigned
8-bit type according to https://dlang.org/spec/type.html#basic-data-types)
or `uint8_t`/`uint32_t`.

This addresses bug #561 "Incorrectness with ASCII signedness and range
(in C/C++)".
2025-12-02 21:23:30 +00:00
Ulya Trofimovich 600717ad6a Fix CHANGELOG formatting. 2025-12-01 22:59:46 +00:00
Ulya Trofimovich af13e1d896 Release 4.3.1. 2025-12-01 22:53:31 +00:00
Ulya Trofimovich f760dccc55 Update CHANGELOG for release 4.3.1. 2025-12-01 22:28:01 +00:00
Ulya Trofimovich 9d76662c22 Regenerate docs. 2025-12-01 22:15:42 +00:00
Ulya Trofimovich 5ed46a79a1 release.sh: Add option --ignore-examples.
This is needed as a last resort to allow releasing re2c on a system where some
of the language toolchains are broken (as it becomes excessively hard to keep
them all working and to keep the examples up to date for languages that don't
care about backwards compatibility, such as Zig).
2025-12-01 22:13:08 +00:00
Ulya Trofimovich dcf934fb33 Allow tags after $ in regular expressions.
This addresses bug #564 "End of input ($) rule deemed invalid when Posix
captures enabled". It is needed t allow implicit capture tags after $ in a
regexp, which was inadvertently forbidden in release 4.3.

It will also be necessary in order to accommodate negative tags added at the
end of alternatives that don't have tags.

During TNFA construction $ is moved past negative tags and placed immediately
before the final TNFA state. This ensures that there are no tags on the
$-transition and we don't have to append tag operations to incoming transitions
when getting rid of the $-transitions in TDFA.
2025-12-01 21:07:53 +00:00
Ulya Trofimovich 55487d4ab8 Fix YYCTYPE to be unsigned in the examples for C/C++. Add a test.
This addresses bug #561 "Incorrectness with ASCII signedness and range
(in C/C++)".
2025-11-26 22:47:09 +00:00
dependabot[bot] 59de285996 Actions(deps): Bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 10:57:38 +00:00
Ulya Trofimovich da7d8fe924 Use ptrdiff_t instead of non-standard ssize_t.
This fixes the build on windows.
2025-11-20 22:04:41 +00:00
Ulya Trofimovich 325db7adfd Rework handling of conditions that have no rules.
This addresses bug #560 'Illformed C/C++ code due to missing "final"
conditions in generated enumeration'.

After much discussion (see the bug) it was decided that aborting in the initial
state dispatch for conditions without rules doesn't play well with the existing
configuration `re2c:cond:abort`. Some language backends (notably, C/C++ backend)
have it disabled by default, so the general-case default (no abort) would be at
odds with the special-case default for empty conditionss (abort).

This commit takes a different approach: always raise an error on conditions
without rules, but before doing that check if there are any `<*>` rules that
can be merged to them.
2025-11-20 21:21:25 +00:00
Ulya Trofimovich ccb1d45431 Revert "Always explicitly initialize condition enum members."
This reverts commit 34f6e5269f.

Reason for revert: to make sure we don't break existing code, e.g. if
the numeric constants are incompatible with the user-defined enum type.
2025-11-17 22:48:43 +00:00
Ulya Trofimovich deaabdd4ca Fix check for conditions with the same name in goto/label mode.
This check should not compare condition numbers in goto/label mode,
as conditions get renumbered anyway. Previously it used to work because
all numbers were set to zero in goto/label mode, but it was broken by
a recent commit 8a4e4ebd54.

This addresses bug #560 'Illformed C/C++ code due to missing "final"
conditions in generated enumeration'.
2025-11-15 22:37:48 +00:00
Ulya Trofimovich 550451d8b4 Check for conditions that have no rules.
Check that all conditions referenced by `=>` and `:=>` exist (have rules).
In the case of `:=>`, raise an error on non-existent conditions (because
the autogenerated semantic action would go to a nonexistent condition start
label). In the case of `=>` add the nonexistent condition to condition enum
(the user may want to set condition variable and return from the lexer to
handle it in user code), but make the initial dispatch abort on it (in case
it was a typo).

This addresses bug #560 'Illformed C/C++ code due to missing "final"
conditions in generated enumeration'.
2025-11-13 22:51:24 +00:00
Ulya Trofimovich 34f6e5269f Always explicitly initialize condition enum members.
Historically in goto/label mode conditions weren't assigned explicit
numeric identifiers - the numbers were assigned implicitly based on
position in the condition enumeration. This affected language backends
for C/C++, D, Go, V (those supporting goto/label model).

In loop/switch and rec/func modes condition numbers correspond to TDFA
state indices, so they are not consecutive and require explicit
initializers.

This commit makes the enumeration always have explcit initializers
regardless of the code model. The generated initializers are backwards
compatible (identical to the implicitly assigned ones).
2025-11-12 22:32:02 +00:00
Ulya Trofimovich 8a4e4ebd54 Unify handling of numeric condition identifiers across code models.
Historically in goto/label mode conditions aren't assigned explicit
numeric identifiers - the numbers are assigned implicitly based on
position in the condition enumeration. However, this correlation is
erroneous: there's no guarantee that the languages that support `goto`
also have enums with implicit numbers.

For now, keep the erroneous correlation (to avoid changing the generated
code), but move it from re2c code to syntax file definitions.
2025-11-12 21:10:34 +00:00
dependabot[bot] 79831797ff Actions(deps): Bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 12:32:46 +00:00
dependabot[bot] 0bfddb867b Actions(deps): Bump actions/setup-python from 5 to 6
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 11:35:27 +01:00
Alexey Abramov 7563ecaec0 Use maximum alignment to ensure compatibility across all architectures. 2025-08-31 12:22:56 +01:00
dependabot[bot] e74cef8655 Actions(deps): Bump actions/setup-java from 4 to 5
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-25 21:00:13 +01:00
dependabot[bot] 26f01b60ee Actions(deps): Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-18 15:46:44 +01:00
Stefan A. Haubenthal 6662452bde Fixed minor typos 2025-08-04 06:19:13 +01:00
Ulya Trofimovich ffdc69dc2e Release 4.3. 2025-06-30 14:17:05 +01:00
Ulya Trofimovich 8bc53228ff Update changelog for release 4.3. 2025-06-30 07:02:33 +01:00
Ulya Trofimovich 2a64e74ff7 Docs: add description of -Wdeprecated-eof-rule warning. 2025-06-30 07:02:33 +01:00
Ulya Trofimovich 76e14817fb Allow to use $ in a regexp.
Previously $ was a special end-of-input rule with precedence and
inheritance order similar to the special default rule *.

Now $ can be used in a regexp as part of a normal rule with normal
position-based precedence and inheritance order. However, this change would
break backwards compatibility in some cases, so for now there's a workaround
that enforces the old order and gives a warning. In the future the warning
will be turned to error, and the old order will no longer be enforced.

New options that control this behavior:

    -Wdeprecated-eof-rule          (turn on warning, on by default)
    -Wno-deprecated-eof-rule       (turn off warning)
    -Werror-deprecated-eof-rule    (turn on error, off by default for now)
    -Wno-error-deprecated-eof-rule (turn off error)

The case when $ is in the middle of a regexp (like `[a] $ [b]`) are forbidden
and raise an error. The case when $ is at the end but not standalone (like
`[a] $ | [b]`) are forbidden at the moment, as they are not handled properly in
codegen, but they will be allowed later. For now, only the old-style standalone
rule `$` is handled properly.

This is the first part of the work needed for issue
https://github.com/skvadrik/re2c/issues/525.
2025-06-29 06:45:13 +01:00
Ulya Trofimovich e89281382f Store rules (not rule locations) in the shadow set.
This will be used later to check if a shadowing rule is an end-of-input rule.
2025-06-29 06:45:13 +01:00
Ulya Trofimovich 83b1f8769a Fix analysis that determines if default state is needed with re2c:eof.
Use fallthrough states, not fallback states.

The added test used to SIGSEGV before the change.
2025-06-29 06:45:13 +01:00
Ulya Trofimovich 325c102712 Use correct union member.
The code happened to work correctly because the two union members had
identical layout.
2025-06-29 06:45:13 +01:00
Ulya Trofimovich f15465cd60 Do not emit -Wunreachable-rules for <*> if a rule is alive in some conditions. 2025-06-29 06:45:13 +01:00
Ulya Trofimovich 9cfdb736c6 Fix incorrect comment in the test and add another test case.
The comment was initially consistent with the generated code, but it got
inconsistent after commit 277f0295fc which
fixed code generation.
2025-06-29 06:45:13 +01:00
Ulya Trofimovich 9601d30173 Don't forget to add fallback tags with end-of-input rule $.
If end-of-input rule `$` is used, re2c takes a different approach and
uses a different set of subroutines to find unreachable rules.
Previously these lacked "fallthough" analysis that is normally performed
without the `$` rule. As a result, some code was generated incorrectly
(as can be seen on the updated tests and the newly added test).
2025-06-29 06:45:13 +01:00
Peter Kokot ffefa3914d CMake: Add CheckPIESupported
The CMAKE_POSITION_INDEPENDENT_CODE variable enables PIC when building
objects, and the CheckPIESupported module provides a
check_pie_supported() command, which enables position independent code
for executables (PIE) at the link step. Without this module, for
example, building at the link step in some cases might fail. For
example, on Haiku.
2025-06-26 06:31:33 +01:00
Ulya Trofimovich d528489324 Unify clos_t with conf_t from libre2c.
After a recent rework of `clos_t` it has become identical to `conf_t`, so
there's no need for using a different type in libre2c.
2025-05-16 22:41:09 +01:00
Ulya Trofimovich 862eee4570 Speed up core determinization algorithm by another ~42%.
Avoid popping/pushing on-stack closure items and patch them in place if
possible. Note that using `emplace` instead of `push_back` method on
`std::vector` instead of this change is not nearly as much helpful: it adds
only a ~6% speedup compared to the ~42% speedup caused by this change.

It only affects leftmost greedy closure construction (which is the default).

This addresses bug https://github.com/skvadrik/re2c/discussions/544
"Unicode characters in UTF8 and generation performance".

The 42% speedup was measured on examples/c/unicode_identifier.re modified as
suggested in the comment
https://github.com/skvadrik/re2c/discussions/544#discussioncomment-13011740.
2025-05-16 17:24:49 +01:00
Ulya Trofimovich 3734d5bdd7 Speed up core determinization algorithm by ~10%.
Make closure items smaller - don't store transition tags and tag versions
in them, as they can be retrieved from the origin kernel using origin TNFA
state for each closure item. Making the items smaller reduces the amount
of copying during closure construction.

Also, avoid extra copy between the main and auxiliary closure vectors;
construct the new TDFA state kernel right from the main vector. This required
a lot of changes in the code, as the kernel stores information as a struct of
arrays (this allows fast comparison and hashing of only the relevant parts of
the kernel), while the closure is an array of structs (this is more convenient
for closure construction and sorting).

Also, make the conditional in the kenel hashing function compile-time rather
than run-time.

There are no algorithmic changes; only the way information is organized and
propagated.

This addresses bug https://github.com/skvadrik/re2c/discussions/544
"Unicode characters in UTF8 and generation performance".

The 10% speedup was measured on examples/c/unicode_identifier.re modified as
suggested in the comment
https://github.com/skvadrik/re2c/discussions/544#discussioncomment-13011740.
2025-05-16 17:19:24 +01:00
Ulya Trofimovich e461e348b1 Disable Swift in builds configs that are used for bootstrap and need only C. 2025-04-23 22:32:06 +01:00
Ulya Trofimovich 7bc7c1980a Release 4.2. 2025-04-23 11:26:04 +01:00
Ulya Trofimovich d5484f0443 Update changelog for release 4.2. 2025-04-23 11:16:07 +01:00
Ulya Trofimovich 74be826d3a Update docs: add code:type_yyctable description. 2025-04-23 11:11:07 +01:00
Ulya Trofimovich 49c1417d12 Make build directory name explicit in the instructions.
This is to avoid confusion as in
https://github.com/skvadrik/re2c/issues/541#issuecomment-2816606364
2025-04-21 06:46:12 +01:00
Ulya Trofimovich 17905e7bf5 GitHub Actions: update Java version 11 -> 24. 2025-04-21 06:46:12 +01:00
Ulya Trofimovich 4c7c00c9d2 Update docs: add description of YYFN throw specs in syntax files.
Also, fix a small formatting issue from the previous commit.
2025-04-18 16:04:54 +01:00
Ulya Trofimovich cf8788cc18 Rework syntax file templates for computed goto (again).
Replace `code:cgoto_target` (which was the target expression in the computed
`goto` statement) with `code:cgoto` (which is the full statement).

Rename `code:cgoto_init` to `code:cgoto_data`.

Add `code:yytarget_filter` (similar to existing `code:yybm_filter`).
2025-04-17 06:38:07 +01:00
Ulya Trofimovich 9ab6a13cb3 Update docs for computed goto options / configurations. 2025-04-14 16:23:58 +01:00
Ulya Trofimovich a37a530555 Fix -Wreorder warning. 2025-04-14 16:23:36 +01:00
Ulya Trofimovich 420a976fdb Fix stack-use-after-scope error found by AddressSanitizer.
Local varaible of type `const char*` was passed as `const std::string&`
constructor parameter (so a temporary `std::string` had to be created)
and stored in a class. Fixed by storing the `const char*` pointer directly.
2025-04-13 16:45:10 +01:00
Ulya Trofimovich 52fa88db7b Rework syntax file templates for computed goto.
Previously we had `code:yytarget_goto`, `code:yyctable_goto` for computed
`goto` target expression, and  `code:yytarget_elem`, `code:yyctable_elem`
for table initializers. The defintions for `yytarget` and `yyctable` were
almost identical, and the decision to keep them separate was taken only
so that each set of code templates could specify a different underlying
type for table elements. It was impossible to pass the type using
`code:type_yyctarget`, `code:type_yyctable` because these configurations
included type qualifiers like `static const`.

For the full discussion see this thread:
https://github.com/skvadrik/re2c/pull/537#issuecomment-2693462138

Now that we've got rid of type qualifiers in commit
a94d39b112, it has become possible to merge
code templates for `yytarget` and `yyctable` and avoid the duplication.
2025-04-12 22:52:25 +01:00
Ulya Trofimovich 9498443133 Update docs for syntax file conditional .const. 2025-04-09 17:10:53 +01:00
Ulya Trofimovich a94d39b112 Add syntax file conditional .const to array definitions.
Code templates `code:array_local` and `code:array_global` can now use local
conditional `.const`, which is true if the array is immutable.

This also has the side-effect that type qualifiers such as `static const` in
C/C++ have been removed from type definitions `code:type_yybm`,
`code:type_yytarget` and `code:type_yyctable` (where they did not belong in
the first place).

Also, rename `yybm` to `YYBM` in Rust by default (this is an inner variable,
so changing default definition should not break backwards compatibility).

Rust and Java have been affected by this change, as their bitmap definitions
have been constified (which is reflected by the updated tests). Other language
backends either have used constant bitmaps already, or they don't have a notion
of immutable arrays.
2025-04-09 17:09:04 +01:00
Ulya Trofimovich a66644dad3 Docs: add configuration description for relative computed goto.
Configurations `re2c:computed-gotos:relative`, `re2c:cgoto:relative`.
2025-04-06 16:43:06 +01:00
Ulya Trofimovich 1b24830363 Add re2c:yyfn:throw to the all-config test, update docs.
While at it, fix description of `re2c:yyfn:sep` in the docs.

Regenerate bootstrap manpages and help (incorporates some earlier updates
for Java manpage that were omitted by mistake in commit
47afb07f90 that updated manpages for other
languages).
2025-04-06 16:27:59 +01:00
Ulya Trofimovich cac9f0e75e Swift: make examples compile with Swift 5.8.
Temporarily drop `@retroactive` attribute that was added in Swift 6.
2025-04-05 06:58:11 +01:00
Ulya Trofimovich 58b687e527 Zig: support yyfn:throw configuration.
This is useful for --recursive-functions code model, as it's necessary to use
different syntax for function calls with an additional `try` keyword before the
call expression (which would be impossible to do before this change).

The test/codegen/zig/recursive_functions/basic.re test has been updated to
demonstrate the new functionality.
2025-03-24 16:56:39 +00:00
Ulya Trofimovich 7f624d2a42 Clean up some minor formatting issues in Swift syntax file. 2025-03-24 16:30:14 +00:00
a dinosaur ac37222644 swift: Support yyfn:throw
Adds support for yyfn:throw to the Swift syntax, allowing the user to throw
types that conform to the Error protocol within functions generated by the
recursive-functions code model. Non-empty settings of the `re2c:yyfn:throw`
property are appended to generated function definitions between parameters
and the return type, and generated function calls are prefixed with "try ".

The 'test/codegen/swift/recursive_functions/advanced.re' test has been updated
to test the new functionality as well as demonstrate practical use of throwing
functions in the recursive-functions model for handling runtime errors.
2025-03-23 21:36:12 +00:00
Ulya Trofimovich 73636c66c5 Add configuration re2c:yyfn:throw.
Also, add syntax variable `throw` and conditional `.yyfn.throw` to be used by
code templates for function definitions and function calls.
2025-03-22 23:05:12 +00:00
Ulya Trofimovich e536d7129f Revert "Add syntax variable attrs for code:fndecl and code:fndef configurations."
This reverts commit 85d9384b2f.

Reason for revert: the main motivation for this change was to support Swift
`throw` annotations. However, it turns out that attributes are unfit for the
purpose, since functions that throw also require slightly different call
expressions (they need to be prefixed with `try`). Although attributes may be
useful, let's remove them until we find a real-world use case.

For details, see the full conversation:
https://github.com/skvadrik/re2c/pull/538#discussion_r2008079095
2025-03-22 16:41:03 +00:00
Ulya Trofimovich 85d9384b2f Add syntax variable attrs for code:fndecl and code:fndef configurations.
Use it for C/C++ fuction attributes as an example.

The main motivation for doing this was discussed in
https://github.com/skvadrik/re2c/pull/538#discussion_r2005503221.
2025-03-21 17:10:05 +00:00
a dinosaur f60219b6e1 Add support for Swift 2025-03-20 22:32:00 +01:00
a dinosaur 47afb07f90 Regenerate bootstrap from master 2025-03-20 22:32:00 +01:00
Ulya Trofimovich 8f9c628201 Benchmarks(C/C++): use the same benchmark names as filename infixes.
run.py depends on it when it generates .json report, as it uses filenames for
binary size measurements and symbolic names for CPU time measurements.
2025-03-18 16:50:44 +00:00
Tai Chi Minh Ralph Eastwood 2cf658310c Add code:yytarget_elem, code:yytarget_goto to syntax files.
code:yytarget_elem specifies the how the table elements for computed
goto tables are generated.  If cgoto:relative = 1, then the table
entries contain an offset from a calculated base address.
code:yytarget_goto specifies the computed goto tables are generated.

code:yyctable_elem and code:yyctable_goto are used for the
corresponding computed gotos for conditions.

Bootstrap code has been regenerated.
2025-03-15 23:00:09 +00:00
Ulya Trofimovich feb94108f3 Benchmarks(C/C++): add a few benchmarks without submatch. 2025-03-02 16:25:13 +00:00
Tai Chi Minh Ralph Eastwood afabf6e416 Generalize the computed-gotos code generation for C/C++ backend
Previously the code-generation did similar table generation across
the normal states, accept states and condtional variables.
This refactor introduces some utility functions that provides the same
logic across the different tables.
2025-02-27 06:32:55 +00:00
Tai Chi Minh Ralph Eastwood f505631d46 Regenerate bootstrap for relative computed gotos. 2025-02-25 19:48:55 +00:00
Tai Chi Minh Ralph Eastwood 25fe63beb6 Update the docs about cgoto:relative and --computed-gotos-relative 2025-02-25 19:48:55 +00:00
Tai Chi Minh Ralph Eastwood 1f60bcf49f Add cgoto:relative to enable generating relative offset tables
Instead of using absolute pointers are used in the cgoto tables,
we generate relative offsets from the earliest label offset
within the code.  This offset type is hardcoded as `int' currently.
2025-02-25 19:48:55 +00:00
Ulya Trofimovich 8baaca5774 Release 4.1. 2025-02-16 16:49:48 +00:00
Ulya Trofimovich bdf3e8958a Update Zig examples for newer compiler version. 2025-02-16 16:41:00 +00:00
Ulya Trofimovich ee033adfb6 Update CHANGELOG for release 4.1 (plus a small fix in the manual). 2025-02-15 22:35:14 +00:00
Ulya Trofimovich d3db8a17a5 Update docs (add description of actions). 2025-02-15 10:19:36 +00:00
Ulya Trofimovich 28cb6b8572 Benchmarks(C/C++): use pkg-config in CMake to link with google benchmark. 2025-02-10 08:29:01 +00:00
Ulya Trofimovich 5d4b79275b Benchmarks(C/C++): fix linkage with google benchmark. 2025-02-07 22:20:32 +00:00
Ulya Trofimovich bbf1cb2604 Benchmakrs(C/C++): fix CMake build system.
This was necessary following the rewrite using google-benchmark.
2025-02-05 22:36:56 +00:00
Ulya Trofimovich 6b67aac3e9 Benchmarks(C/C++): update benchmark results. 2025-02-05 22:36:56 +00:00
Ulya Trofimovich cca3ca4151 Benchmarks(C/C++): don't use bit vectors for re2c.
This is because bit vectors are not suppotred with.end of input rule $,
to make the comparison fair between re2c variants.
2025-02-05 22:36:56 +00:00
Ulya Trofimovich de8bf67c32 Benchmarks(C/C++): add simple variants without buffer refill. 2025-02-05 22:36:56 +00:00
Ulya Trofimovich ca18e43710 Benchmarks (C/C++): rewrite using google-benchmark.
This way we can have more reliable measurements for the future benchmarks that
read input from a string rather than a file, and so run much faster and are
more affected by measurement errors.
2025-02-05 22:36:56 +00:00
Ulya Trofimovich 17d7d8c618 Benchmarks (C/C++): remove Kleenex benchmarks.
They are interesting from the academic standoint (to compare DSST vs. TDFA),
but Kleenex is not flexible enough: it assumes fixed program template. The
generated code cannot be adapted to google-benchmark, which it important to
get precise time measurements.

Kleenex benchmarks results are available in the paper by Borsotti and
Trafimovich "A Closer Look at TDFA" (https://arxiv.org/abs/2206.01398).
2025-02-05 22:36:56 +00:00
Ulya Trofimovich ec64527e36 Benchmarks (C/C++): limit Kleenex benchmarks to submatch-only. 2025-02-05 22:36:56 +00:00
Ulya Trofimovich 7e25fb759f Benchmarks (C/C++): remove deprecated TDFA(0) and StaDFA algorithms.
For anyone interested, see the paper by Borsotti and Trafimovich
"A Closer Look at TDFA" (https://arxiv.org/abs/2206.01398). It has benchmark
results that cover the removed algorithms.
2025-02-05 22:36:56 +00:00
Ulya Trofimovich ba31855356 Zig backend: use const for yych declaration in rec/func mode.
Previously re2zig generated `var`, but `yych` is not modified in this mode and
newer Zig versions fail with `error: local variable is never mutated`.
2025-02-05 16:13:48 +00:00
Ulya Trofimovich 6c0d89a238 Allow escaped double quote in the generic lexer rules for char literals.
Some languages have special escape `\"` in character literals, so re2c should
recognize it as well.

This addresses bug #529 "[Rust] Escaped double-quotes in character literal
results in EOF error".
2025-02-04 22:48:10 +00:00
Gregg Reynolds 705a029b8f delete bazel lock file 2025-02-03 09:23:33 +00:00
Gregg Reynolds 7c5eac5982 support WORKSPACE; use lastest skylib
* tested with Bazel 8.0.1 and 7.0.0 on linux and macos
2025-02-03 09:23:33 +00:00
Gregg Reynolds f2e6668e9a migrate to Bazel 8 using bzlmod 2025-02-03 09:23:33 +00:00
Ulya Trofimovich 0e97d4917b Add !pre_rule and !post_rule actions. Add tests for actions.
!pre_rule action is emitted immediately *before* any semantic action in the
current block / condition (it can be useful to have some common initialization
code). !post_rule action is the same, except that it is emitted *after* every
semantic action (it can be useful e.g. to emit unreachability checks).

This addresses bug #521 "Add special entry/exit rules".
2025-01-24 16:28:13 +00:00
Ulya Trofimovich 5a9be34734 BUILD.md: add a list of prebuilt packages on Repology.
This addresses bug #526 "[doc]: Add other install methods on official webpage".
2025-01-21 17:01:11 +00:00
Ulya Trofimovich 71517f1bf9 Change syntax for the entry action: use !entry instead of ^.
This way it is possible to add new named special actions without having
to worry about exhausting all special symbols. Also, if we add mid-rule
actions in the future, this syntax can be used for them as well.
2025-01-20 22:37:58 +00:00
Ulya Trofimovich 787a7a306a Rename "initial" state to "start" state.
Rename `initial_state` to `start_state` and `initial_label` to
`custom_start_label` (so that it's clear that it is a special case).
Update comments.
2025-01-19 16:10:45 +00:00
Ulya Trofimovich e2a2eca01b Rename class field for clarity. 2025-01-18 16:10:12 +00:00
Ulya Trofimovich 596c3d9484 Clean up code that sets default state.
Remove incorrect assignment of default state to default rule state; it was
overwritten later, so it had no effect at all. Rule state should be kept
separate, as default state may be used for different things (e.g. it may be
used as the accept state that has `yyaccept` dispatch).

No changes in the generated code.
2025-01-18 10:35:23 +00:00
Ulya Trofimovich a65419d89a Simplify handling of state actions. Set initial state for all code models.
Previously initial state was marked using special initial action, which was set
only in rec/func mode. Now we explicitly store a pointer to initial state and
set it for all code models.
2025-01-18 07:03:31 +00:00
Ulya Trofimovich f52b642f8e Swap YYBACKUP and YYFILL in the initial state to unify it with other states.
The order of these operations doesn't matter, provided that YYFILL is correct.
2025-01-16 21:43:06 +00:00
Ulya Trofimovich b8406137d6 Tweak precondition for marking used labels with end-of-input rule $.
It's unclear where the previous condition came from; the intention seems to be
to exclude final states that have no outgoing transitions on symbols. With the
end-of-input rule `$` even if all characters fall into the same range as in
`[^]`, a separate range is split for the sentinel symbol, so the previous
condition could not capture any match states.
2025-01-15 16:04:10 +00:00
Ulya Trofimovich 4fedb068c1 When using end-of-input rule $, mark targets of rematch transitions as used.
This is only needed in loop/switch and rec/func modes, as goto/label mode uses
special YYFILL labels, not the state labels. And most of the states were already
marked as used due to other transitions going into them. So the bug was not
revealed until the recent addition of the entry rule.

This addresses bug #521 "Add special entry/exit rules".
2025-01-15 10:54:40 +00:00
Ulya Trofimovich c1537de331 Check that tags on all transitions going to bitmap state are the same.
Previously we only checked that tags are parwise equal between two mapped
transitions, not between all transitions going to the bitmap state. This was a
regression caused by optimization 98f2a41393.

This fixes #523 "Possible regression with bit-vector optimizations between 3.x
and 4.x".
2025-01-14 17:00:39 +00:00
Ulya Trofimovich f3dc6fe0e9 Don't pass invalid location to error reporting function.
When all rules were inherited from other blocks, re2c failed to find correct
rule location and passed an invalid location, which caused a SIGSEGV in the
error reporting function.

This fixes bug #522 "Segfault when !use is present in a block with conditions".
2025-01-14 10:07:32 +00:00
Ulya Trofimovich 19d771fd3d Don't lose jump to the initial state when the entry rule is used.
In goto/label mode, if there is a loop via initial state, YYSKIP must be
bypassed when entering the DFA (visiting initial state for the first time).
Other modes generate YYSKIP on transitions, so they were not affected.

The bug was found by skeleton tests.

This addresses bug #521 "Add special entry/exit rules".
2025-01-12 23:05:07 +00:00
Ulya Trofimovich 4afd9776dc Add entry rule ^ that allows one to execute code at lexer entry.
Also, rename "setup" to "exit action" to match the added "entry action"
(and also because it makes more sense).

This addresses bug #521 "Add special entry/exit rules".

Drop some not very useful debug checks.
2025-01-12 16:40:00 +00:00
Ulya Trofimovich 41411f5c8a Don't write null for missing YYFN type, as it makes output truncated. 2025-01-12 16:39:48 +00:00
Ulya Trofimovich 543aaab356 A few clean-ups.
- remove obsolete `if` branch
- make assertins more precise
- factor out codegen function for semantic actions
- rename variables
2025-01-10 22:07:21 +00:00
Ulya Trofimovich 814a544eff Don't use YYGETCOND() for yystate initialization in non-conditional blocks. 2025-01-10 15:55:27 +00:00
Ulya Trofimovich 5fa1dbd576 Clean up code that handles zero condition <>. 2024-12-30 10:10:46 +00:00
Ulya Trofimovich 90bd3158e1 Don't fail when zero condition <> has no end-of-inpt rule $.
Previously re2c failed with an error in the case when end-of-input rule `$` was
enabled and the special zero condition `<>` was used. Now it no longer fails and
generates code withot end-of-input check for the zero condition (which is
handled in a special way by the code, bypassing some of the transformations that
rely on the presence of end-of-input rule).
2024-12-28 10:25:49 +00:00
Ulya Trofimovich 2b80343e4d Don't try to generate names for fictive tags.
With captvars (either leftmost or POSIX ones) we need to generate names for the
variables that correspond to capturing parentheses. The difference between
leftmost and POSIX cases is that POSIX disambiguation algorithm is more complex
and it requres additional imlicit tags inserted in the regular expression.
These so-called "fictive" tags don't have valid submatch group indices, so
trying to use them caused integer overflow and a very long loop.

This is a fix for issue #519 "re2c hangs if posix-captvars is used".
2024-12-27 16:15:32 +00:00
Ulya Trofimovich 972d7874e2 Add a test for condition with the end-of-input rule $.
Currently re2c fails with error, as the special zero condition `<>` has no
end-of-inpt rule `$`.
2024-12-27 11:09:48 +00:00
Ulya Trofimovich 83b135699f Allow using lookahead operator with captures.
This is a fix for #518.
2024-12-27 10:18:00 +00:00
Ulya Trofimovich 2ecbbce7d9 Fix error message for the case when standalone tags are mixed with captures.
We now have many options for captures, so we cannot assume that the
--posix-captures option is the one causing conflicts.

This partially addresses issue #518.
2024-12-27 09:54:16 +00:00
Ulya Trofimovich e2d249f839 OCaml: use unsafe_get instead of get as the default YYPEEK implementation.
The generated code already handles the end of input, so it should use
`unsafe_get` to avoid redundant bounds checks. If the user wants to use `get`,
they can always do so by overriding YYPEEK.

Update all examples and remove '\x00' character at the end of string literals,
as they are already NULL-terminated.
2024-12-25 16:42:26 +00:00
Ulya Trofimovich 54d0eaa4b5 Generate correct escape sequences for each language.
Previously C escape sequences were used for all languages, which resulted in
incorrect escapes generated for some languages, e.g. `\f` in OCaml is not a
valid escape, while in C it is.

This commit adds syntax configuration `special_escapes` to all syntax files.
Its value is a string of all special characters that require escaping.

This is a fix for #516 "re2ocaml can generate invalid escape sequences".
2024-12-24 16:56:15 +00:00
Ulya Trofimovich cf302ed2bd Add a test for raw newlines in syntax files. 2024-12-23 16:40:16 +00:00
Ulya Trofimovich 32e11d9904 Do not consider space characters printable.
0x20 (space ' ') is printable, but others like '\f' are not. And 0x20 is already
covered by the `is_print` part of the check.

This patch does not change existing behavior, as the code handled all
non-printable space characters as escape sequences before the check, so they
were printed correctly.
2024-12-22 16:42:11 +00:00
Ulya Trofimovich 2fc1f0b0bc Release 4.0.2. 2024-12-11 15:56:41 +00:00
Ulya Trofimovich 4d5f6d6722 Restructure benchmark layout (prepare to add new benchmarks).
Update pre-generated benchmark files (trivial line directive changes).

Disable regeneration of Kleenex files, as Kleenex is not actively maintained and
fails to build with the recent cabal and Haskell ecosystem.
2024-12-11 07:38:40 +00:00
Ulya Trofimovich bec027b7ae build/__distcheck.sh: add missing -j $(nproc) to some build commands. 2024-12-11 07:21:27 +00:00
Ulya Trofimovich a780025238 Update changelog. 2024-12-11 07:20:14 +00:00
Ulya Trofimovich 05298b1210 Makefile.am: don't forget to clean up autogenerated syntax files. 2024-12-10 22:01:45 +00:00
Ulya Trofimovich 70409e3966 Makefile.am: remove non-syntax headers from BUILT_SOURCES.
Only syntax headers have rules that autogenerate them.
2024-12-10 18:12:00 +00:00
Ulya Trofimovich c65b9766ac Update changelog for 4.0.2. 2024-12-10 18:01:01 +00:00
Ulya Trofimovich 6aa98843c7 Automake.am: use headers instead of source files for default syntax configs.
This is a follow-up on the change needed to fix CMake (bug #511).
2024-12-10 18:00:41 +00:00
Ulya Trofimovich 0b7be55aec CMake: pick correct default syntax config for language specific binaries.
2nd attempt to fix issue #515 "version 4.0.1 re2rust default generate C code".
This time, instead of trying to split the object library, the code that needs
the split has been moved out of the problematic library.

Also there are some small improvements in the way default syntax strings are
declared (added `static constexpr`) and linked (moved them to header files).
Generation script has been fixed to generate correct string names.
2024-12-10 18:00:34 +00:00
Ulya Trofimovich 436a6cbeaa Revert "CMake: split object library by language, pass correct options to each."
This reverts commit 9cfb87edaf.

Reason for revert: it's no good trying to build multiple object libraries for
different languages in parallel, as they all try to copy files to the same
bootstrap directory, causing conflicts and build errors. Avoiding such conflicts
was the reason the object library got added in the first place (so that
autogenerated sources could be built once before all other sources).
2024-12-10 16:49:50 +00:00
Ulya Trofimovich 9cfb87edaf CMake: split object library by language, pass correct options to each.
Previously target compile definitions weren't properly added to the
autogenerated sources, as they were built into a separate object library
(to ensure that they are built before the rest of the sources). Now the
object library is built separately for each language with proper options.

This addresses issue #515 "version 4.0.1 re2rust default generate C code".
2024-12-10 16:18:28 +00:00
Ulya Trofimovich 170ffa39b8 Restructured benchmark layout (preparing to add new benchmarks). 2024-12-03 17:21:47 +00:00
Ulya Trofimovich e5cb9a1ebd Release 4.0.1. 2024-11-25 07:20:45 +00:00
Ulya Trofimovich 1357b3c3d9 Update CHANGELOG for release 4.0.1. 2024-11-25 06:56:34 +00:00
Ulya Trofimovich 61c88fbf5a Rebuild syntax files when checking the distribution. 2024-11-24 16:30:29 +00:00
PolarGoose 162b9c5a8b Increase the Cmake minimum version to allow using CMAKE_MSVC_RUNTIME_LIBRARY flag 2024-11-24 06:42:14 +00:00
Ulya Trofimovich 5eb464f8e8 Docs: update contributors list. 2024-11-23 17:21:04 +00:00
Ulya Trofimovich e1148b4a7b Makefile.am: add dependency on RST sources and custom build scripts.
The added rule has no command part, so it does not conflict with existing
suffix rules that build docs.
2024-11-23 17:19:17 +00:00
Ulya Trofimovich 3a40b3d4bb Make most of the C/C++ examples truly C compatible.
Some of the examples use C++ data structures like `std::ifstream`, `std::vector`
etc. Leave them as is for now.

Update docs.

This addresses bug #484 "Example is not C".
2024-11-23 11:39:57 +00:00
Ulya Trofimovich a75eb2b3fd Avoid C++ templates in some examples to make them work in C.
This addresses bug #484 "Example is not C".
2024-11-22 16:17:54 +00:00
Ulya Trofimovich 5cea17c8fe Avoid new features added in 4.0 in C/C++ examples.
Keep examples compatible with older re2c versions until most of the world has
updated to re2c-4.0 or later. When it happens, this commit should be reverted.
2024-11-22 07:17:01 +00:00
Ulya Trofimovich b4dc9f69b1 Regenerate docs with typo fixes.
This picks up typo fixes in commit 92c3ae5a99.
2024-11-22 07:16:35 +00:00
jcfp 92c3ae5a99 fix typos 2024-11-21 17:22:38 +00:00
Ulya Trofimovich a1c42047da Makefile.am: add some missing doc sources to distribution tarball.
This fixes bug #503 "[4.0] build failure with --enable-docs".
2024-11-21 17:14:00 +00:00
Ulya Trofimovich b8a4cddf80 Release 4.0. 2024-11-19 07:00:21 +00:00
Ulya Trofimovich 7f26edd716 Makefile.am: avoid POSIX-incompatible pattern rules.
This is to fix building with bmake on FreeBSD.

Replace all pattern rules with POSIX-compatible suffix rules. As the latter are
much less flexible than pattern rules, this required creating copies or symlinks
with appropriate names for source files that don't fit into the naming scheme
implied by suffix rules.

Also, dependencies on custom build scripts had to be dropped, as suffix rules
don't allow additional prerequisites.
2024-11-18 22:36:14 +00:00
Ulya Trofimovich cf7e2c7639 CMake: align disabled warnings with configure.ac. 2024-11-14 10:55:48 +00:00
Ulya Trofimovich 555331f6e7 Disable Clang warning -Wexit-time-destructors.
This warns on `static const std::map<...>`.

re2c is single-threaded, so there's no risk of race conditions when one
thread is terminating and the other one tries to access the object.
2024-11-14 07:08:27 +00:00
Ulya Trofimovich efc527c2ac Fix Clang warning -Wweak-vtables. 2024-11-13 23:01:05 +00:00
Ulya Trofimovich a5e37dcb8a Fix Clang -Wshadow-uncaptured-local warning. 2024-11-13 17:38:34 +00:00
Ulya Trofimovich bce5d21288 Fix Clang -Wshadow warning. 2024-11-13 17:36:31 +00:00
Ulya Trofimovich d85f08ac1f Disable a few warnings in Bison-generated code, as we cannot fix them.
Disabled warnings are: -Wdisabled-macro-expansion and -Wused-but-marked-unused
2024-11-13 17:29:39 +00:00
Ulya Trofimovich 01b78d8db7 Fix Clang warning -Wextra-semi-stmt. 2024-11-13 17:27:03 +00:00
Ulya Trofimovich 91f265b9f3 Makefile.am: add autogenerated help sources to CLEANFILES. 2024-11-13 16:21:51 +00:00
Ulya Trofimovich 61c14ce5e5 Fix some typos in documentation. 2024-11-13 06:07:18 +00:00
Sergei Trofimovich c4e779cab5 *.ypp: use api.prefix in all bison-generated parsers
Mostly a cospetic change. I hope to get to the state when `re2c` can be
built with `-flto -Werror=odr`. Right now it fails as:

    src/parse/parser.cc:121:6: error: type 'yysymbol_kind_t' violates the C++ One Definition Rule [-Werror=odr]

This change does not fix it, but at least it clearly solits the exposed
API namespace:

    https://www.gnu.org/software/bison/manual/html_node/Multiple-Parsers.html
2024-11-11 06:03:15 +00:00
Ulya Trofimovich a2d5361545 CHANGELOG: add online playground to the list. 2024-11-07 16:26:41 +00:00
Ulya Trofimovich 0dfc64d6ff Makefile.am: fix autogenerated header paths used by make bootstrap.
This is a fix for https://github.com/skvadrik/re2c/issues/498.
2024-11-04 15:49:43 +00:00
Ulya Trofimovich 59bec481e3 Docs: add description of syntax files. 2024-11-02 16:02:32 +00:00
Ulya Trofimovich cffecf2bc5 Use C-tyle comments in .dot output regardless of the target language.
This fixes #495.
2024-10-31 16:11:45 +00:00
Ulya Trofimovich 04eb0ae86d Remove unused variables from the allowed set for code:yyrestoretag. 2024-10-30 22:45:01 +00:00
Ulya Trofimovich 2228e8f6d0 Get rid of syntax configuration code:type_cond_enum.
There's no need for it, as YYCONDTYPE can be either the name of the
enumeration, or an integer type if there is no enumeration.
2024-10-29 22:56:14 +00:00
Ulya Trofimovich d85e7e97fd Docs: add descriptions of new block types and warning. 2024-10-27 22:19:35 +00:00
Ulya Trofimovich 2bbd803796 Docs: update configurations an API descriptions. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 1a050e0eb8 Docs: update option list and descriptions. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 8571400c7f Examples: replace re2c:api = default with --api simple. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich a73bb4cddd Update configuration descriptions in the docs and CHANGELOG. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 181bfe95cc Use simplified configuration syntax in examples for Zig. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 73637f91a8 Use simplified configuration syntax in examples for V. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich d6c2a60f88 Use simplified configuration syntax in examples for Rust. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 48435b5a1b Use simplified configuration syntax in examples for Python. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 103271952c Use simplified configuration syntax in examples for OCaml. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 27e0855534 Use simplified configuration syntax in examples for JS. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich cec1803ac0 Use simplified configuration syntax in examples for Java. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 06c0ffa90d Use simplified configuration syntax in examples for Haskell. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 960cd7dee5 Use simplified configuration syntax in examples for Go. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich f3f3194a35 Use simplified configuration syntax in examples for D. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 25b3626c38 Use simplified configuration syntax in examples for C/C++. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 9218113a8e Allow dropping define: and variable: part in configurations.
These parts are used inconsistently in configuration names, e.g. we have
`re2c:tags:expression` which has to be scoped under `tags:` but it's also a
definition, so it should be scoped under `define:` (and other examples like
this). In fact, most of the string configurations are defines of some sort.

Also, change `conf:` prefix in syntax files to `re2c:`, as in
configurations. From now on, "c" in "re2c" stands not for C/C++ language,
but rather "code" or "compiler", so it's good for all languages.

Also, use prefix `.` (dot) for conditionals in syntax files to make it
easy to distinguish them from variables in code templates.

Also, fix warnings and error messages to use backtick quotes consistently.

Also, fix some comments in the code that still used the word "directive" for
special-purpose blocks.
2024-10-27 16:07:27 +00:00
Ulya Trofimovich f3ecbb16ae Docs: rearrange manual section layout.
Also, use the word "blocks" consistently instead of "directives".
2024-10-27 16:07:27 +00:00
Ulya Trofimovich fea7f92b2a CMake: factor out common helper function for docs generation. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 2c5c5003e8 Docs (help): use language-specific program name instead of "re2c".
Split help source file for all language backends.
2024-10-27 16:07:27 +00:00
Ulya Trofimovich 85f7d36227 Docs (manpage): use language-specific program name instead of "re2c".
Perform substitutions throughout the whole manual.
2024-10-27 16:07:27 +00:00
Ulya Trofimovich 77735b9f67 Docs: merge "blocks and directives" section into "syntax" section. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich d7c0cc09bc Update BUILD.md. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 2b349129eb Add manpages for new languages.
Automake: generalize generation rules for docs (make split_man.py infer
language from its second argument, as POSIX make does not seem to have a way
to pass languge name to the rule). Explicitly list all example files (provide
a `find` command to generate the list in a comment).

CMake: Add forgotten install files for re2java and re2js. Use GLOB_RECURSIVE
with CONFIGURE_DEPENDS to add examples to the list of source file.

Also, update description of submatch extraction and change captures example:
use the one without POSIX-style array `yypmatch`, as not all languages support
it (Haskell doesn't, as it has no mutable arrays in the standard library).
2024-10-27 16:07:27 +00:00
Ulya Trofimovich 2027021c1a Unify filename for Haskell example with other languages, fix run script. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 650c4bc0c2 Docs: update API descriptions. 2024-10-27 16:07:27 +00:00
Ulya Trofimovich 77eb8fbaa1 Rename files. 2024-10-27 16:07:26 +00:00
Ulya Trofimovich ff9f27c6f7 Update split_man.py for new languages. 2024-10-27 16:07:26 +00:00
Ulya Trofimovich b6803c4a88 Drafted changelog for the upcoming release. 2024-10-27 16:07:26 +00:00
Ulya Trofimovich f310f6d635 Docs: separate authors into its own RST file. Regenerate.
This is to avoid duplication of the contents on gh-pages-gen branch.
2024-10-27 16:07:26 +00:00
Ulya Trofimovich db1a4d6951 Update CONTRIBUTING.md. 2024-10-27 16:07:26 +00:00
Ulya Trofimovich c03459572b Use new configuration aliases in syntax files (for better readability). 2024-10-27 16:07:26 +00:00
Ulya Trofimovich 0936b3aa72 Rearrange the order of configurations in syntax files (cosmetic). 2024-10-27 16:07:26 +00:00
Ulya Trofimovich c641280e1c Add syntax configuration code:continue. Use labelled loops for Zig. 2024-10-27 16:07:26 +00:00
Ulya Trofimovich a543138bd1 Clean up label definitions in syntax files. Use labelled loops fpr D. 2024-10-27 16:07:26 +00:00
PolarGoose 3f0f46ff75 Fix a static analysis warning: "trie.next" is assigned with the same value 2024-10-24 20:53:42 +01:00
PolarGoose c8e8ab51dd Fix a static analysis warning: "input" file is not closed before returning 2024-10-24 20:53:42 +01:00
PolarGoose 7aba30555d Fix a static analysis warning: useless null check 2024-10-24 20:53:42 +01:00
PolarGoose 95dde201b8 Fix a static analysis warning: unusual code formatting 2024-10-24 20:53:42 +01:00
PolarGoose 10bd44025e Fix a static analysis warning: "oneline" is always true 2024-10-24 20:53:42 +01:00
Ulya Trofimovich 5c84dfc5aa Use spaces instead of tabs for Rust. 2024-09-23 16:20:09 +01:00
Ulya Trofimovich ddb1add809 Use spaces instead of tabs for OCaml. 2024-09-23 16:15:31 +01:00
Ulya Trofimovich dfae2f2361 Use spaces instead of tabs for D. 2024-09-23 16:11:44 +01:00
Ulya Trofimovich 08ce33838b Rename char_or_hex to char-or-hex to align with other option values. 2024-09-23 16:02:07 +01:00
Ulya Trofimovich 409dcabf7d Add bitmaps support (Haskell backend).
Also, mark some incorrect but unused syntax definitions as undefined.
2024-09-21 17:20:10 +01:00
Ulya Trofimovich da97854a4a Use code:array_global instead of code:array_local in rec/func mode. 2024-09-21 17:16:01 +01:00
Ulya Trofimovich eac735f66d Add bitmaps support (OCaml backend). 2024-09-20 16:05:20 +01:00
Ulya Trofimovich 5a4afb1bfb Add syntax configurations code:yybm_filter, code:yybm_match.
Remove syntax configurations `code:bit_and`, `implicit_bool_conversion`
as they are no longer needed. Strictly speaking, `code:bit_and` was also
used in generation of computed goto, but it's fine to hardcode `&` for
now, as computed goto are only implemented in C/C+. Later they will be
reimplemented using a syntax configuration similar to the bitmap ones.
2024-09-19 22:31:35 +01:00
Ulya Trofimovich 5830f0387e Use CodeGoIfL (linear IF) for bitmap transition.
This unifies bitmap transition with other transitions that are constructed
during the analyze phase and removes the need for special handling during
the generate phase.
2024-09-16 15:49:32 +01:00
Ulya Trofimovich da5e4c947c Move bitmap initialization to analyze phase.
This commit splits table initialization (populating it with values) and code
generation for the initialized table. The former is moved to analyze phase, and
the latter remains in the generate phase.

Bitmap values are needed when generating preconditions for bitmap transitions.
Currently this is done during generate phase, but there is a plan to move it to
analyse phase so that bitmap transitions could be generated using the same code
primitives as other transitions (linear IF).
2024-09-15 21:56:00 +01:00
Ulya Trofimovich 4103ae3737 Replace CodeOp with a string generated during the analyze phase. 2024-09-15 21:56:00 +01:00
Ulya Trofimovich e045138660 Match IF with ELSE when generating bitmap transition in rec/func mode.
Some functional languages like OCaml require that IF statement has an ELSE part.
This requirement may be relaxed if the statement under IF returns void, but this
is not necessarily the case in re2c-generated code (it depends on how the user
defines YYFN: they may choose it to be a void or non-void function). Besides,
other functional languages like Haskell do not have this relaxation.
2024-09-10 15:08:34 +01:00
Ulya Trofimovich 0d25d42c03 Fail with a comprehensible error if bitmaps are used in rec/func mode. 2024-08-26 06:54:36 +01:00
Ulya Trofimovich a0c1968ede Add bitmaps support (Zig backend). 2024-08-25 16:12:49 +01:00
Ulya Trofimovich 8c3d145276 Add bitmaps support (Python backend). 2024-08-25 06:56:28 +01:00
Ulya Trofimovich 4bcbd2a60a Add bitmaps support (JS backend). 2024-08-25 06:40:44 +01:00
Ulya Trofimovich 1d8320afe2 Add bitmaps support (Java backend). 2024-08-25 06:40:29 +01:00
Ulya Trofimovich 319da16127 Add bitmaps support (Rust backend). 2024-08-25 06:39:36 +01:00
Ulya Trofimovich d885f95f23 Use configuration code:array_elem for bitmap elements. Add cast if needed. 2024-08-24 07:47:23 +01:00
Ulya Trofimovich e4566bc7ce Add syntax configuration code:bit_and and use it for bitmap checks. 2024-08-23 06:40:16 +01:00
Ulya Trofimovich 0f79acd852 Generalize comparison operations to binary operations in codegen. 2024-08-23 06:39:56 +01:00
Ulya Trofimovich 98f2a41393 Allow tags on transitions with --eager-skip, if tags are identical.
The added test works correctly both before and after this change, however
it shows incorrect behavior if tags are not checked for equivalence at all
(in that case some URI fragments are missing in the test output).
2024-08-20 16:46:21 +01:00
Ulya Trofimovich 11b400ac0e Rewrite code that creates bitmap transition to use CodeJump. 2024-08-20 10:23:33 +01:00
Ulya Trofimovich 377758aa1e Allow bitmap optimization with --eager-skip.
Limit it to the cases when there is YYSKIP on both transitions or neither.
2024-08-19 07:07:24 +01:00
Ulya Trofimovich 399be1f9df Add syntax file features "tags", "captures", "captvars".
Also add an unsupported feature test for "captures" in Haskell.
2024-08-15 16:47:46 +01:00
Ulya Trofimovich 205ad4e098 Use let keyword instead of var in JS syntax file and examples. 2024-08-15 16:10:51 +01:00
Ulya Trofimovich 223dbc9599 Add directives svars and mvars.
These directives allow the user to simplify declaration of tags variables,
which is especially useful when the variables are for capturing paretheses.

Also, adjust commnets in submatch examples.
2024-08-15 16:10:51 +01:00
Ulya Trofimovich aca50bb123 Rename POSIX submatch examples, add examples for captures with variables. 2024-08-15 16:10:51 +01:00
Ulya Trofimovich d539bc3da2 Save boolean configuration value in a field.
Previously it was recomputed from the numeric value every time. Although
the recomputation was trivial (comparing against zero), it made the code
more verbose and less readable.
2024-08-12 07:12:04 +01:00
Ulya Trofimovich 5fc38030e1 Add capturing groups with variables instead of array.
This commit adds the following options and the corresponding configurations:
    --captures (alias for existing --leftmost-captures)
    --leftmost-captvars, --captvars (alias for --leftmost-captvars)
    --posix-captvars

Variables are named `yytl<n>` and `yytr<n>` for the left and right
parentheses of n-th capturing group.
2024-08-11 16:36:21 +01:00
Ulya Trofimovich 6246dbde8f Print undefined configuration name in the stub to make debugging easier. 2024-08-10 13:31:10 +01:00
Ulya Trofimovich d360fb41e8 Add missing Haskell test for unsupported case ranges. 2024-08-09 06:56:42 +01:00
Ulya Trofimovich 87a031fc85 Turn on some warnings by default.
Warnings like -Wundefined-control-flow should be on by default, as they report
severe issues with the code that should be fixed. If the user wants to suppress
such warnings, they will have to do it explicitly on the command-line.
2024-08-08 16:08:47 +01:00
Ulya Trofimovich 497fedc5c9 Remove configuration standalone_single_quotes.
The only purpose of this configuration was to make the lexer fail on standalone
single quotes for languages that do not allow them. Removing it does not affect
how the lexer works: it still attempts to lex single quote as the beginning of a
char literal and looks for a matching closing quote. The only thing changed is
that now the lexer does not raise an error on standalone single quotes for
languages that do not allow them; it simply ignores them in the same way it does
for languages that do allow them (e.g. identifiers in Haskell/OCaml, numbers in
C++, labels/lifetimes in Rust, etc.). This goes along with the general re2c
behaviour: it does not attempt to parse any languge - it only does the bare
minimum of work needed to parse re2c blocks correctly.

This takes care of bug #482 "Handle single quotes correctly in the lexer".
2024-08-07 15:16:02 +01:00
Ulya Trofimovich a3f619e6ab Handle Vlang backtick-quoted strings correctly. 2024-08-07 14:43:02 +01:00
Ulya Trofimovich e256f5012e Add syntax configuration single_quoted_strings and set it for Python. 2024-08-07 14:43:02 +01:00
Ulya Trofimovich ed0f2124ff Set standalone_single_quotes configuration for C. Add some tests.
The lexer does not attempt to lex all lexemes that may contain a standalone
single quote - those would differ a lot for different languages. Instead, it
tries to lex paired single quotes (character literals) which are similar enough
in different languages to allow a single generic lexer rule. If this attempt
fails, lexer checks if standalone single quotes are allowed (if yes, it just
skips the single quote and resumes lexing; if not, it fails with a syntax
error). This way lexer doesn't need to know about different types of lexemes
that may contain a standalone single quote.
2024-08-06 06:45:07 +01:00
Ulya Trofimovich 1b5ae59fa5 Set backtick_quoted_strings configuration for languages that need it. 2024-08-06 06:45:07 +01:00
Ulya Trofimovich ffb70cfa47 Add option --lang none to inhibit loading any default syntax file. 2024-08-05 15:30:54 +01:00
Ulya Trofimovich 675e94eaf7 Search for syntax files relative to the current directory.
Paths relative to the current directory should work without any additional
include paths.
2024-08-05 06:21:28 +01:00
Ulya Trofimovich 82e91b6646 Rename supported features to match configuration names. 2024-08-03 22:13:35 +01:00
Ulya Trofimovich 2d773639be Allow setting immutable configurations in syntax files.
This fixes a problem with libre2c introduced by the previous commit
8e9bfda737 which required that all code options
are defined (non-null). The problem was caused by testing if `line_dirs` option
is defined: the test happened in the code that is shared with libre2c, while
normally such tests happen in the code that is not shared. This commit moves
`line_dirs` initialization to config files, so the faulty test is removed
entirely.

It also changes the way that implied imuutable options are set: former
`set_default_*` functions that soft-set an option (mark it as not user-defined)
are replaced with `set_*` functions that hard-set the option (mark it as
user-defined). It shouldn't matter for immutable options, as they cannot be
redefined by the user.

an option  only set an option specified in a syntax
file if it's not explicitly defined by the user. No tests have changed.
2024-08-03 22:07:36 +01:00
Ulya Trofimovich 8e9bfda737 Don't crash on undefined configurations. Give a warning.
This commit adds a new warning: -Wundefined-syntax-config. It is not an
error, so that old syntax files stay valid as new syntax configurations
are added. Warnings allow the user notice that new configurations are
available and it's time to update their syntax file.
2024-08-01 22:45:59 +01:00
Ulya Trofimovich 1fb357c20f Make yych:conversion language-specific. Add tests.
Not all languages support `yych:conversion` (this commit adds support
for it in C/C++, D, Go, Rust and Zig backends). Conversion is only
useful for backends that implement simple/record API and have a type
system strict enough to prevent implicit conversion.
2024-07-30 22:04:35 +01:00
Ulya Trofimovich 0efd012137 Rename "default" API to "simple", and "custom" to "generic".
Keep old options and configurations for backwards compatibility.

Update all examples to use the new configurations.
2024-07-29 16:38:46 +01:00
Ulya Trofimovich 9714371ecb Unify syntax file definitions for code:yy{g,s}et{accept,cond,state}.
Add some comments for C, where we cannot provide useful defaults for
code:yy{g,s}et{cond,state} without breaking backward compatibility.
2024-07-28 22:18:42 +01:00
Ulya Trofimovich 67e2f080b0 Don't reset yycond variable based on code model.
The reset code wa added by mistake.
2024-07-28 22:14:57 +01:00
Ulya Trofimovich c76135cd6b Add syntax configurations for relational operators.
The following configurations were added:

    code:cmp_eq
    code:cmp_ne
    code:cmp_lt
    code:cmp_gt
    code:cmp_le
    code:cmp_ge
2024-07-28 07:05:48 +01:00
Ulya Trofimovich 7fd5ec66fb Don't set file pointers past the end of include file.
Don't adjust file start/end pointers in cases when we reached the end of
the include file when reading from it, as YYLIMIT may point outside of
the portion of the input buffer occupied by this file. It may happen if
the previous `read()` invocation drained this file, then read some data
from the parent file (the one that contains include directive), and then
YYFILL got triggered while YYCURSOR was still in this file, so this file
could not be popped off the stack yet.

The error was rare - I found it by a lucky accident when the buffer got
resized to a certain size due to a change in syntax file. This triggered
YYFILL in the right moment (in encodings/unicode_identifier.re example).
2024-07-27 06:43:47 +01:00
Ulya Trofimovich 29d5c87957 Update GitHub Actions config and CMake presets for new languages. 2024-07-24 22:34:52 +01:00
Ulya Trofimovich e7de8841fd Rename a few more syntax file variables. 2024-07-24 18:02:34 +01:00
Ulya Trofimovich da8d553052 Rename syntax file variables to match API names. 2024-07-23 23:04:27 +01:00
Ulya Trofimovich 1f644a0438 Provide default YYCTYPE definition for OCaml. 2024-07-22 22:54:52 +01:00
Ulya Trofimovich 02a133fba1 Provide default YYCTYPE definition for V. 2024-07-22 22:30:43 +01:00
Ulya Trofimovich 13249489b2 Provide default YYCTYPE definition for Zig. 2024-07-22 22:30:43 +01:00
Ulya Trofimovich fff50f785f Update example run scripts to use language-specific program name.
They were broken by commit 7dfe119353.
2024-07-22 22:30:43 +01:00
Ulya Trofimovich 39f1becb62 Adjust comments in examples. 2024-07-22 15:39:01 +01:00
Ulya Trofimovich b609e814b3 Add some forgotten Zig tests. 2024-07-22 10:28:20 +01:00
Ulya Trofimovich 7dfe119353 Make program name in the fingerprint comment language-specific.
Use re2c for C/C++, re2hs for Haskell, etc.
2024-07-22 10:25:34 +01:00
Ulya Trofimovich bf61e090d3 Always apply default syntax file, but allow overriding it.
This way the user may provide a syntax file with only a few overrides
instead of copy-pasting default definitions for all configurations.

As an example, add a test for the Haskell backend that pretends to be a
test for the Python backend, but overrides default Python config with
Haskell config. We don't use default C config in this case as it
defines a few optional configurations for oneline switch cases/ifs that
are not overridden by the Haskell config. The generated code is
identical to examples/haskell/01_basic.re.

Also, remove a stale TODO comment.
2024-07-22 06:49:29 +01:00
Ulya Trofimovich f06c17ef32 Add configuration tags:negative for the negative tag constant.
This should be configurable, as in some languages type system is strict
and defaulting to any particular constant means that tags must have the
type of this constant (and by extension cursor, marker, ctxmarker and
limit). It would still be possible to override them, but it would
require using generic API and providing definitions for all primitives.

In generic API `tags:negative` defaults to the tag variable that is set
to the negative tag value (substituited by re2c). We keep this behaviour
for backwards compatibility.
2024-07-21 07:01:28 +01:00
Ulya Trofimovich f2395c2998 Allow raw digits in regular expressions in Flex mode.
This fixes bug #483 "handling digits in flex mode".
2024-07-19 22:37:17 +01:00
Ulya Trofimovich d4df07f7ce Use flex-style block start/end markers for Zig examples. 2024-07-19 16:51:51 +01:00
Ulya Trofimovich 1c27fd45d4 Use flex-style block start/end markers for OCaml examples. 2024-07-19 16:51:51 +01:00
Ulya Trofimovich 940349f50a Use flex-style block start/end markers for Haskell examples. 2024-07-19 16:51:51 +01:00
Ulya Trofimovich a5e547794e Use flex-style block start/end markers for Python examples.
Also, add a missing directive in one of examples and remove a few
useless semicolons.
2024-07-19 16:51:51 +01:00
Ulya Trofimovich dd7a7a2044 Add flex-style braces for all directives / block openings.
Also, slightly change parser rules for `%{`: instead of requiring that
it is on a new line (possibly preceded by whitespace), allow arbitrary
text before it on the same line, but require a newline immediately after
it. This simplifies parser rules, and it should be good enough to avoid
parsing `%{` occurrences in the middle of a string or comment by mistake
in most of the cases.
2024-07-19 16:51:51 +01:00
Ulya Trofimovich d3f727cd8c Add basic support for Zig (no documentation). 2024-07-16 06:55:26 +01:00
Ulya Trofimovich 11075509c6 Add basic support for JavaScript (no documentation). 2024-07-16 06:55:26 +01:00
Ulya Trofimovich ba9cfabc49 Add basic support for Java (no documentation). 2024-07-16 06:55:26 +01:00
Ulya Trofimovich f6c7f3a8e3 Fix extenstion in python example run script. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich d3b83eb329 Implement default API for V and switch examples to it. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich e64c45ba83 Implement default API for Rust, switch of the examples to it.
Note that is cannot be enabled by default due to backwards compatibility.
2024-07-16 06:55:26 +01:00
Ulya Trofimovich b2e11e1e64 Implement default API for Python and switch examples to it. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich 7e924d6e9b Implement default API for Go, switch of the examples to it.
Note that is cannot be enabled by default due to backwards compatibility.
2024-07-16 06:55:26 +01:00
Ulya Trofimovich 8197f6d5b8 Check if skip/peek/backup specializations are defined before using them. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich d1732352f1 Add new API primitive YYINPUT and update all the tests/examples.
The new primitive is used for the input string (for languages that use
array / string indices rather than pointers).
2024-07-16 06:55:26 +01:00
Ulya Trofimovich 8a632a3d69 Make cursor, marker, limit, ctxmarker configurable fields in record API.
Previously their names were hardcoded in syntax files, now they delegate to
configurations `define:YYCURSOR`, `define:YYMARKER`, `define:YYLIMIT` and
`define:YYCTXMARKER`. This results in slightly longer field names, but also
more consistent with default and generic APIs.

In some cases it may be necessary to override the default names, e.g. Go
requires public struct fields to be uppercase, while private ones should be
lowercase.
2024-07-16 06:55:26 +01:00
Ulya Trofimovich 7ef8e672e2 Make accept, condition and state configurable fields in record API.
Previously their names were hardcoded in syntax files, now they delegate to
configurations `variable:yyaccept`, `variable:yycond` and `variable:yystate`.
2024-07-16 06:55:26 +01:00
Ulya Trofimovich 49c5388b2f Allow negation and logical AND / OR in syntax file conditionals. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich a33065033d Rename syntax file conditionals to avoid name collision with variables. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich fbd5a8621e Add configuration variable:cond, update tests. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich 2e3a312466 Add missing example for D. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich 7dddb5843a Allow newlines before and after the equals sign in configurations.
Previously only spaces were allowed.
2024-07-16 06:55:26 +01:00
Ulya Trofimovich c5493a3e4d Switch D backend to pointer API by default, fix examples and tests. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich a3c9b1963d Implement record API for D and switch some examples to it. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich 77503713d3 Implement record API for V and switch some examples to it. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich a65cde175a Implement record API for Go and switch some examples to it. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich a44f902312 Implement record API for Rust and switch some examples to it. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich 2cb7706148 Implement record API for Python and switch some examples to it. 2024-07-16 06:55:26 +01:00
Ulya Trofimovich 9aa7766037 Implement record API for OCaml and make it the default one. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich 608910d419 Implement record API for Haskell and make it the default one. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich ab8a5f0098 Don't reset API definitions to defaults if generic/default API is not used.
With the new record API defined via syntax files, it may actually be useful to
delegate some `code:` syntax configurations to generic API primitives. It allows
one to customize the generated code for record API by redefining only a few
selected primitives.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 7df5fe0994 Add record API.
Add a new option `--api record` and a new configuration `re2c:api = record`.

Use the new record API in syntax file for C. Switch some C examples to it.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich d2a7b9320b Use code templates instead of strings for API primitives in syntax files.
Previously API definitions like YYPEEK, YYSKIP etc. were always strings, both in
syntax files and in source files. Now in syntax files they are code templates;
in particular, they should use variable `sigil` instead of substring `@@`. In
source files they are still strings: there's no need for code templates there,
and if fact it's not possible for them to become code templates, as source files
allow unquoted strings which would be mis-parsed as variables in code templates.

Using code templates in syntax files allows one to make conditional language-
specific defaults for APIs depending on mutable options, such as the current
API, API style, etc. Previously it was only possible to use immutable options as
predicates. Using variable substitution for `sigil` allows us to automatically
replace default sigil `@@` with a user-defined one.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 736f608e3e Simplify macros in option lists, add some comments. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich 1d931b7a23 Clean up syntax configuration definitions.
Add "yy" prefix to configuration identifiers. Also, deduplicate
configuration identifiers and the associated strings.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 7d0e7a725f Add syntax configuration code:yylessthan. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich 6b93da5c82 Rename local syntax file conditional multival -> many.
The new name is more generic, so it can be reused in other
configurations
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 066e2b7d7e Do substitutions in the API primitives regardless of the API style.
Previously sustitutions were always done in the free-form API style,
while the function style was inconsistent: for most primitives
substitutions weren't done, but for a few primitives they were done.
This doesn't matter in real life, as the function style assumes that the
primitives are function names, which cannot contain the sigil string
"@@" (unless it was redefined to some alphanumeric string by the user,
which is unlikely).
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 753ffe4622 Add syntax configurations code:yygetcond/code:yysetcond and code:yygetstate/code:yysetstate. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich 07f7532567 Use RecordWildcards instead of OverloadedRecordDot in Haskell examples.
This extension results in more concise syntax and configuration
defintitons that are easier to understand.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 7c16c52239 Change the meaning of the optional 3rd component in YYFN elements.
Previously it was used to specify optional modifiers. Syntax configs for
some languages utilized modifiers for mutability annotations (Rust) or
strictness annotations (Haskell). More generally, it was used in cases
when the formal parameter syntax differs from the argument syntax.
However, modifiers were not flexible enough: they can only be added on
one side, while sometimes both left and right context is needed.

This patch makes the 3rd component mean the whole formal parameter. It's
still optional: when not specified, 3rd component defaults to the 1st
component (argument). However, if parameter syntax differs from the
argument syntax, it is now possible to specify arbitrary text in each.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 99c5a7a3a6 Use backend-specific re2c binary name when reporting generic errors.
Instead of always emitting error prefix `re2c:` emit `re2go:`  for
re2go, `re2rust:` for re2rust, etc. Note that this doesn't affect the
runtime --lang option, e.g. for `re2c --lang go` the error still starts
with `re2c:`.

No tests, as the testing script replaces all binary names with --lang.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich b53103c9d4 Break long lines with configuration strings in Haskell examples/tests. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich 60ba7d8ec0 Allow configuration strings to span across multiple lines.
Long configuration strings can now be broken into parts that are
separated with spaces and newlines. Each part should be a double-quoted
string.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 74e510800a Move YYDEBUG implementation to syntax files.
As in the case of all other API primitives, YYDEBUG logic for default
or generic API should be in the syntax file for each language.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 457092c89a Add basic support for Haskell (no documentation). 2024-07-16 06:55:25 +01:00
Ulya Trofimovich cd4e9be142 Simplify syntax-based expression rendering in "generate" codegen pass.
Provide a less verbose interface for generating language-specific expressions
during "generate" codegen pass. Encapsulate some of the details in helper
methods of the `opt_t` class.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 9d5091b3e3 Add API primitives SETACCEPT/GETACCEPT and configurations code:yysetaccept/code:yygetaccept.
The new primitives and configurations allow one to override `yyaccept`
syntax for a single source file or for a given language backend.

For existing languages the new primitives have default definitions:
nothing changes in the code generation, and no new definitions are
required from the user. The change is fully backwards compatible.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 8e3f03cdb9 Add missing OCaml example of s-tags with YYFILL. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich 8a51834851 Remove some examples of custom end-of-input checks, rename files.
Namely, remove examples that use end-of-input rule `$`, and leave
examples that are based on the sentinel method (as they are simpler and
demonstrate the technique well enough.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 44a091a18f Provide multival condition in configurations code:if_then_else{,_oneline}.
This condition is true when there's more than one IF branch. It is
needed for Haskell, which uses a different syntax for one-branch IF
(the `when` statement).
2024-07-16 06:55:25 +01:00
Ulya Trofimovich a12eb0f5c6 Slightly tweak OCaml example for m-tags. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich e67b1afb2e Add configurations variable:yynmatch and variable:yypmatch.
Don't generate `yynmatch` assignment in case the configuration is set
to empty string.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich b1b797a866 Move the logic that checks if a fixed tag is negative into syntax files.
This is needed because the check itself is language-specific, and also
the IF construct is problematic in some languages (e.g. in Haskell it
would be impossible to get the updated state out of the IF branch
without making the IF expression part of the YYSHIFTSTAG operation.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 7e316e1b8a Get rid of the "materialize no-match value" comment.
This is language-specific (comment syntax differs for different
languages), but adding it to syntax files seems an overkill.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 0ad6a8205c Add syntax configurations for tag operations.
The following configurations have been added:
    - code:shiftstag
    - code:shiftmtag
    - code:stagp
    - code:stagn
    - code:mtagp
    - code:mtagn
    - code:copystag
    - code:copymtag

Mark `code:shiftstag` and `code:shiftmtag` as oneline configurations
(in fact they should be named one-statement, not oneline).

Note that the user can define YYSHIFTSTAG/YYSHIFTMTAG as multi-statement
without the curly braces, and thus break the assumption re2c makes about
the generated code. But it is also the case with YYFILL (and has always
been), so we don't make the situation much worse. This requirement
should be documented, though.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 49faa46c38 Unify the way tag operations are generated with default and generic API.
Previously default API had some shortcuts, e.g. in case of fixed tags
the operations of copying base tag and subtracting offset were fused
into one. This is no longer the case.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich b27dbc9be7 Prepare YYSHIFT implementation for handling default API. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich 653bb7440e Clean up code generation for tag operations. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich d1424e57bd Add missing copy operations for nested fixed tags with generic API. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich 1a1ce4bf3b Slightly simplify helper functions that accept is_mtag parameter. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich a6e8bca983 Move common codegen logic out of syntax files.
Replace the complex `code:yyrestorectx` configuration that had many
conditionals with a few simple configurations `code:yyrestorectx`,
`code:yyrestoretag`, `code:yyshift`. Common language-independent logic
belongs in the re2c source code (to avoid duplicating it in each syntax
file, and also to avoid unecessarily complicating syntax files).
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 9b9d762de6 Simplify code generation for tag assignment.
Previously re2c generated assignment chains like this:

    t1 = t2 = ... = tN = YYCURSOR;

Now it generates a sequence of simple statements:

    t1 = YYCURSOR;
    t2 = YYCURSOR;
    ...
    tN = YYCURSOR;

Syntax configuration `code:assign` has been updated accordingly:
the `lhs` variable no longer needs to be a list variable.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 60b167b710 Drop support for function-like API style for all languages except C and Go.
This breaks backwards compatibility for Rust, but it was hard to use
function-like API with Rust anyway (if at all possible).
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 9415c7ab1b Add syntax configurations code:yyrestore and code:yyrestorectx.
Also, drop `code:assign_op`, as it is useless now.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 637110ada6 Add syntax configuration code:yybackupctx. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich 2a4b846696 Drop configuration code:yyaccept, use generic code:assign instead. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich b0f43dec71 Add API primitives YYCOPYSTAG, YYCOPYMTAG.
For most languages they have default values (in syntax files) that never
need to be configured manually by the user. However, for languages like
haskell it is impossible to provide a reasonable default value - that's
why we need these primitives.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich fb450d3054 Revert "Rename apis YY{S,M}TAG{N,P} -> YYSET{S,M}TAG{N,P}. Keep old aliases for compatibility."
This reverts commit 8fb3d50f8d6dd8aace87631bb1a961b6e13c4536.

Reason for revert: change of plans: no need to rename these primitives
unless we add YYGET{S,M}TAG, and the latter can be avoided if we use the
3rd component of YYFN elements for arguments (as opposed to parameters).
2024-07-16 06:55:25 +01:00
Ulya Trofimovich c536ef0770 Pass boolean param instead of recomputing it in nested function calls. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich 1311331e0a Replace default sigil with user-defined one in default API definitions.
E.g. if some API primitive X is defined as "...@@..." in syntax file,
and the user specifies sigil "$" instead of "@@", then default X
definition should become "...$...".

Previously this was only done for `re2c:cond:goto`, as no API primitives
have default definitions that contain sigil. But we don't really know
default API definitions, as the user may provide a custom syntax file
with custom definitions.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 0bb4569f33 Fix MTAG{N,P} defaults in syntax files. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich 73fb142345 Rename apis YY{S,G}ETCONDITION -> YY{S,G}ETCOND. Keep old aliases for compatibility. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich b4537dbed3 Rename apis YY{S,M}TAG{N,P} -> YYSET{S,M}TAG{N,P}. Keep old aliases for compatibility. 2024-07-16 06:55:25 +01:00
Ulya Trofimovich c27f521f3d Mark case_ranges feature as supported for backends that enable it by default.
Add tests for unsupported `case_ranges` feature.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 197ff08f00 Move and rename backend specific tests.
Add some trivial tests for unsupported features. Update runner scripts.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 42b50636d3 Make checks for unsupported features stricter.
Error on disabling unsupported features (previously re2c only errored
on enabling them).

Add `unsafe` and `monadic` features and tests for them.

Update tests for existing unsupported features.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich c0721980e1 Add configurations monadic and variable:yyfill.
The new configurations are needed to support monadic lexers in the
upcoming Haskell backend.

Configuration `monadic` affects control flow constructs: when it is on,
the "do" keyword is generated before nested blocks.

Configuration `variable:yyfill" allows one to decouple YYFILL invocation
from the check whether YYFILL has failed. This is needed becausse YYFILL
performs I/O (like reading from file), so it should return the updated
state of the world together with the status whether it has failed or not.
2024-07-16 06:55:25 +01:00
Ulya Trofimovich 9703f0088b Add basic support for V (no documentation). 2024-07-16 06:55:24 +01:00
Ulya Trofimovich c5b5ed735e Add syntax option wrap_blocks_in_braces.
The new option cotrols whether to strip curly braces from semantic
actions, and whether to wrap the whole program in curly braces.
Previously this was deduced from other options, e.g. from
`indentation_sensitive` in Python. However, in some other languages this
cannot be so easily deduded (e.g. Vlang uses curly bracees in constructs
like `if`, `switch`, etc., but it rejects a compound statement wrapped
in curly braces, unless it's separated from the previous statement with
a semicolon).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 1da9c2eb64 Clean up codegen tests.
Replace many copies of examples for each language/codegen model
combination with just two tests for all auxiliary code models: a basic
one and an advanced one that covers storable states, conditions, tags,
end-of-input rule $ and `yyaccept`. Other tests are left only for C/C++
backend, as it is sufficient to have them for one backend (e.g. to test
errors specific to this codegen model).

The rationale for this change is: when new backends are added to re2c,
the amount of tests grows significantly, slowing down test run time for
no good purpose (most of the new backends are experimental). Also, it
slows down the addition of new languages (e.g. Vlang supports all three
codegen models --- goto/label, loop/switch and rec/func --- but adding
three full sets of examples for it is an overkill).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich c490dfda00 Ensure that code:abort is a one-line configuration.
Also, remove semicolon from `code:abort` definition in Rust syntax file,
so that it can be used in one-line switch-case context.

Update test results accordingly.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 47527697e7 Verify that certain syntax configurations are one-line, as expected by codegen. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 321e57917f Add syntax configuration code:goto.
This is needed to wrap `goto` in `unsafe { ... }` block for the
upcoming V backend. Currently it is used in goto/label mode for C, D and
Go backends.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 8f1f11def4 Provide initializer for yych.
It may be used in syntax file - but not necesarily. C, D and Go backends
don't use it. Rust, on the other hand, requires that all variables are
initialized.

Previously there was a hardcoded 0 constant in the syntax file for Rust.
Now the initializer is 0 or '\x00' depending on `variable:yych:literals`
configuration and the current encoding (the same condition which is used
to decide how to print YYCTYPE literals).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 8592b84deb Python backend: enable -s (nested ifs) by default.
They are usually faster than switch cases on the tests, e.g. on the
newly added test/switch_vs_ifs.re

    nested ifs took 0.17752790451049805
    switch cases took 0.6691319942474365
2024-07-16 06:55:24 +01:00
Ulya Trofimovich ff3350e51a Add basic support for Python (no documentation). 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 2703a077d6 Add syntax option indentation_sensitive.
With this option, strip curly braces from semantic actions and adjust
indentation to match the rest of the generated code.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 85d8b5b560 Add checks for more features (nested ifs and bitmaps). Add tests. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich a3b9f460ca Rename cgoto syntax file feature into computed_gotos.
Configuration `re2c:cgoto` is still supported for backwards
compatibility.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 76b3938ddc Add helper methods to simplify option checks. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich a4545f966c Specialize std::hash for enum classes.
This is needed for some toolchains (e.g it fixes the build on masOS
12.7.3).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 89d1fa1767 Disable some Clang warnings globally. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 3d2c1c2c07 Fix Clang warning -Wmissing-variable-declarations. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich a84087bc02 Remove extra semicolon. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 5dc4461d04 Add missing override keyword. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 5ed9d68cda Rewrite switch case to get rid of Clang -Wimplicit-fallthrough warning.
As this case is trivial, it's easier to copy-paste the following case
than to add a portable fallthrough annotation (I'm not aware of an easy
way to do it in C++11).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich aff269bc12 Add a few missing static keywords to local functions. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 5ef3d700b2 Fix Clang warning -Wshadow. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich c8bacb2dc0 Fix Clang's warning -Wdeprecated-literal-operator. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 80030878f9 Silence Clang warnings in bison-generated code. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 07b0148337 Merge syntax.{h,cc} into opt.{h,cc} and get rid of Stx struct.
Syntax file handling is completely tied up with option handling, there's
no need to maintain separate infrastructure for syntax configurations.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 5afd992238 Rework syntax file lexer/parser and the way configurations are stored.
Put syntax configurations in a struct and make it part of the immutable
options instead of storing them in a map. This simplifies their handling
and access, as there's no need to check if a key is in the map, etc.

Merge syntax file lexer/parser into configuration lexer/parser, reuse
existing methods.

Rename list syntax configurations and define them as lists of strings in
quotes (rather than words) so that we can reuse configuration parser for
lists.

Remove separate "features" syntax configurations and replace them with a
single list  of features (to be augmented in future commits).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 283d970655 Use numbers instead of strings to handle syntax file identifiers. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 62cb5b2cdd Check that the chosen code model is supported for the given backend. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 4b149addab Go backend: fix syntax configuration for constants.
For some reason constants were previously generated as variables.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich ebbf84f9f3 Split syntax configurations for variables/constants/arrays into local and global. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich e3670059f6 Allow aliasing another code:* configuration in syntax file.
Referencing another `code:*` configuration in the middle of a definition
is not allowed (that would be hard to implement, as appending/prepending
to `StxCodes` list when using it in another configuration would alter
the original list). However, referencing another configuration as an
entire definition is ok, as it doesn't alter the existing configuration.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 04725305d2 Add configurations for YYMAXFILL and YYMAXNMATCH.
For OCaml, set defaults to `yymaxfill` and `yymaxnmatch`, as capitalized
identifiers are reserved for constructors. Update OCaml tests.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 231bc8e25a OCaml backend: render case ranges compactly for char type.
OCaml supports character ranges like 'a'..'z', but it does not support
numeric ranges like 0..9, therefore previously all ranges were rendered
in expanded form, like 'a'|'b'|'c'|...|'z'. This results in sometimes
very long lines with a lot of alternatives in match expressions.

This commit fixes it by adding a conditional into syntax file
definition. It checks if the range is of char type. If so, then the
range is rendered compactly.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 364fed920f OCaml backend: render YYCTYPE literals as chars, not integers.
One exception is the case of multibyte encoding: in that case
YYCTYPE literals are rendered as numbers (because in many languages
char type cannot hold values more than 1-byte).

Replace syntax configuration `yyctype_literals` with
`variable:yych:literals` that may have values `char`, `hex` and
`char_or_hex`.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich abf813d324 Configuration lexer: replace some functions with re2c blocks. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich c418aa1717 Add basic support for OCaml language (no documentation). 2024-07-16 06:55:24 +01:00
Ulya Trofimovich a3deb57658 Add syntax configuration code:array_elem. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 688565f922 Add syntax configurations code:assign, code:assign_op. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich d015911fb7 Fix spurious parser error on backticks in user-defined code.
Don't give a syntax error on backticks if the language does not support
backtick-quoted strings. Instead, simply skip them and move on.

Incorrect behaviour was introduced in commit
624aa6d72059e6180bab7298128e86b5f337e07c.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 3631e7ed3a Don't try to omit tag operation for empty trailing context.
This is a very unlikely and useless case (trailing context that is
always empty), it is not worth specializing the code. In such case we
might as well generate a no-op operatio that decrements cursor by zero.
(Previously the operation was omitted, but an empty statement was still
generated.)
2024-07-16 06:55:24 +01:00
Ulya Trofimovich a664f57331 In rec/func mode, strip curly braces around semantic actions.
This is safe because each semantic action is placed into a separate
function, so there won't be any name collisions with local variables.

It is needed for language backends that don't use curly braces for
compound statements (like OCaml).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 52ce445326 run_tests.py: respect warnings set by individual tests. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 1840d22061 Add tests for --recursive-functions mode (Go backend). 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 8072b3acc6 Add tests for --recursive-functions mode (Rust backend). 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 751358f5cf Allow one to specify return value in function call configurations.
Add `have_retval` conditional to `code:fncall`/`code:tailcall` and
`retval` variable to `code:fncall` only (it is not needed in
`code:tailcall` as the latter returns immediately).

Also, change `code:fncall` to be a statement, like `code:tailcall`
(generate `retval = ...` if there is a return value).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich ca01df5bde Handle '\r' characters as whitespace in configuration lexer.
They may appear in newline sequences on windows.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 621f29c918 Generate comma in oneline match arms in Rust.
This was problematic because previously newline was always rendered in
oneline statements (when rendering the statement itself, without any
knowledge of the surrounding context).

Now newline is no longer considered part of the oneline statement: if
needed, it should be added in the surrounding syntactic construct (in a
syntax file).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 42fe7163cb Change YYFN format to allow type modifiers.
In some languages type modifiers go on the left of function parameters,
while the type itself is on the right (like `mut n: usize` in Rust). For
such cases, we need to allow optional third component of an argument
descriptor in YYFN. So, change its format from a list of 2*N strings to
a list of N strings with semicolon-separated parts (name, type, optional
modifiers).

Add `fn:sep` configuration to allow the users configure the separator.

Precompute function parameters and arguments, as they are common for all
function definitions / calls.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 892359a77c Add tests for --recursive-functions mode (C/C++ backend). 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 2d575a3907 In rec/func mode, don't pass yych to functions that don't use it.
Some state functions don't check `yych` value because all possible
transitions go to the same destination (for any `yych` value).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 883b7008ba Don't print first letter of an option in error messages, it's confusing. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich ef86a22304 Add a helper function to generate abort statement. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich e0c1fffee6 Add configuration cond:abort (similar to state:abort).
Enable them both in rec/func mode for C, and in other modes as well for
other languages.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich b7597813e9 Initialize configuration defaults in syntax files (part 2).
Move individual configuration initialization from re2c code to syntax
configs (previously it ws done in a post-initialization fixup step, but
now there's no need for it).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 977b0a2c52 Initialize configuration defaults in syntax files (part 1).
Add defaults to syntax files. Be careful not to override user-defined
command-line options with defaults.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 46882167bc Correctly handle empty header file specified in configurations.
Previously empty header filename was concatenated with directory path,
resulting into incorrect header filepath. Change this to only prepend
directory path if the header filename is nonempty.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 8aed8322e8 Match conditionals in syntax files during parser phase.
Previously this was done after parsing, and conditionals were stored as
strings. Nuw they are converted to enum values by the parser.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 3aadda2292 Use a boolean var to determine if the lexer is lexing syntax file.
Previously this was done by comparing filepaths, however it broke on
windows as one of the filepaths was escaped (and on windows filepaths
have backslashes, so the escaped name differed from the original).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich df692885a9 GitHub Actions: add relative path to upload artifacts step (to get some artifacts on Windows).
This only works for in-tree builds, but it's usually enough to debug
Windows-only failures.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 1ad3831c4d Use maximum YYMAXFILL among all lexer files.
The same lexer state is used for all lexer files, so YYMAXFILL must be
the maximum of the individual YYMAXFILL values for each file. Previously
YYMAXFILL value for the main lexer was used everywhere, but this is
incorrect and may cause unexpected end of input errors on other lexers.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich e509ed1cc7 Rename files (configuraton lexer, main lexer and autogenerated header). 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 895c3f33fe Add configuration parser that allows conditionals.
Previously all configurations were handled by the lexer, but the
grammar for conditionals is more complex (it allows nested conditional
expressions). These will be used in syntax files to set configuration
defaults for a language based on the global options.

One part of the old lexer still remains: the lexer for string
configurations in source files. Unlike syntax files, source files may
have raw (unquoted) string configurations, which may contain special
symbols used in other parts of the grammar (e.g in the new syntax for
conditionals). Switching to the new parser would require excluding these
symbols and thus breaking backwards compatibility.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 0a8629dbf0 Fix link error in libre2c. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 71294d38f6 Add all configurations allowed in source files to syntax configs.
The added configurations are named in the same way as in source files,
except that they use prefix `conf:` rather than `re2c:`. E.g. for a
source file configuration `re2c:state:abort` the corresponding syntax
file configuration is is a `conf:state:abort`.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 2c4e48aa4b Use the same Input class for both normal lexer and syntax file lexer. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 90cc00e333 Move syntax file lexer/parser to the same subdirectory as normal lexer/parser. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich a793a3f59d Stricten the precondition for eliding fallback transition.
Check that tags and YYSKIP are the same as on transition to which the
control flow falls through if the fallback transition is elided.
(Previously the code assumed that tags and YYSKIP are the same, but it
is not obvious why it should be so.)
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 0f29e41d45 Do not elide fallback transitions in rec/func mode, except if YYFILL is disabled.
Fallback transition is part of an IF/THEN/ELSE statement. In rec/func
mode both THEN and ELSE must end in a tailcall, therefore elisiion is
forbidden (except if YYFILL is disabled, then the whole IF/THEN/ELSE can
be replaced with a tailcall to to-state).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 739c509ac6 Fix test helper script to avoid erroneously filtering out valid test. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich 891b109abf Reuse tags:expression configuration for final tags in rec/func mode.
Normally final tags are user-defined local variables in the function
that wraps the generated DFA. However, in rec/func mode each DFA state
is a separate autogenerated function, so there's no place for the user
to define local variables. Therefore in rec/func mode final tags are
part of the state that is passed from one function to another.

We could theoretically autogenerate final tag declarations before
setting them in the final states, so that they are still local
variables. This would require adding YYSTAGTYPE / YYMTAGTYPE. But what's
worse, it would't work for languages like OCaml, where variables are
immutable bindings: fixed tags with generic API require a few operations
(set, then shift). If, however, final tags are part of the state struct,
they can be updated.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich ad1d82bd26 Add syntax configuration code:yyaccept.
Also, don't reset `re2c:variable:yyaccept` to default value if storable
states are not enbled, as it may be needed in other cases as well.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 8ab63d0805 Forbid the combination of --skeleton and --recursive-functions.
It is possible to add support for skeleton in rec/func mode, but it will
take some effort as skeleton programs use a lot of local variables that
must be passed as function parameters. Disable it for now.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 17a435e953 Use first block options in getstate:re2c with a list of blocks.
If `getstate:re2c` is global (it has no explicit block list, assuming
that it covers all blocks in a file) then use global options accumulated
over the whole file. Otherwise use options of the first block listed in
the directive. For block-level labels/function always use block options.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich a522ee160f Add syntax configurations for YYPEEK, YYSKIP, YYBACKUP and combinations.
The following configurations have been added:
    `code:skip`
    `code:yybackup`
    `code:yyskip_peek`
    `code:yypeek_skip`
    `code:yyskip_backup`
    `code:yybackup_skip`
    `code:yybackup_peek`
    `code:yyskip_backup_peek`
    `code:yybackup_peek_skip`
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 7a53cb2a73 Define code:recursive_functions in default syntax files. 2024-07-16 06:55:24 +01:00
Ulya Trofimovich af618f6481 Add code:fndecl syntax configuration.
It allows one to generate forward declarations of all functions in
rec/func mode, which is needed for some languages (C/C++).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 5a341e25a9 Add code:tailcall, use it instead of code:fncall in rec/func mode.
Unlike `code:fncall` which is an expression, `code:tailcall` is a
statement with `return` (if the language needs it) and indent/newline.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich bc6c23c02f In rec/func mode, generate arguments based on YYFN configuration.
Also, tweak syntax configuration `code:recursive_functions` to assume
toplevel functions rather than closures (as most languages do not allow
co-recursive closures, and some don't have closures at all).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 163d32b6e3 Rearrange functions in a file to bring other static functions in scope.
Prepare source file for the follow-up changes (minimize the diff).
2024-07-16 06:55:24 +01:00
Ulya Trofimovich fee0446b48 Emit default case after (not before) all other cases in state switch.
In some languages (e.g. OCaml) default case is not special, and if it
comes before other cases, it always matches and makes all other cases
useless.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 63c77e8528 Add helper function to generate function calls.
Use YYFN configuration to generate user-defined arguments.
2024-07-16 06:55:24 +01:00
Ulya Trofimovich 42c93b3684 Small cleanups/comments in location tracking in lexer/parser. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich fbd146465e Add configuration re2c:define:YYFN of a new configuration type (list). 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 9a3904265f Make rec/func mode work with storable states. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 15ea590914 Make rec/func mode work with conditions. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich da4a307a96 Do not generate "if" without "else" in rec/func mode.
In functional languages both branches must have the same type, and
C-style early returns are not possible.

In goto/label and loop/switch mode early returns are still preferred,
because the "else" part is often elided.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 6b16784a25 Add prepend operation on lists. Add a unit test for list operations. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 67620440d3 Simplify append operation on lists. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich af410c7065 Simplify checks for transition elision. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich e1878caf9f In rec/func mode, don't elide transitions in "if/else-if/else" branches.
This is because in functional languages like OCaml "if/else-if/else" is
an expression where all branches must have the same type (except perhaps
for a single "if" branch that may have void type.

One exception is the case of a single branch that goes to the next state
(in that case "if/else-if/else" construct is not needed).
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 01e9d8adab Avoid early return from an "if" statement in recursive functions mode.
Generate "if/else-if.../else" instead of a sequence of "if"s,
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 8013918c11 Remove unused oneline field and the wrapper struct. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich b9f9872990 Allow oneline if/else statements with condition in the "else" branch.
This is part of a general effort to unify rendering of oneline if/else
statements (either render them all on the same line without braces, or
all on a new line with braces).

Users that prefer always rendering if/else statements in braces should
be able to do so by commenting out `code:if_then_else_oneline`
configuration in the syntax file (`--syntax` option).

Note that default syntax file include/syntax/<language> (the one that is
used without `--syntax` option) is built into re2c; changing it requires
rebuilding re2c with configure option `--enable-syntax` or CMake option
`-DRE2C_REBUILD_SYNTAX=on`.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich e0ad5b1218 Allow oneline if/else statements for skeleton programs.
This is part of a general effort to unify rendering of oneline if/else
statements (either render them all on the same line without braces, or
all on a new line with braces).

Users that prefer always rendering if/else statements in braces should
be able to do so by commenting out `code:if_then_else_oneline`
configuration in the syntax file (`--syntax` option).

Note that default syntax file include/syntax/<language> (the one that is
used without `--syntax` option) is built into re2c; changing it requires
rebuilding re2c with configure option `--enable-syntax` or CMake option
`-DRE2C_REBUILD_SYNTAX=on`.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich e46f998c95 Allow oneline if/else statements for computed goto check.
(It is not used anyway, as there is always a multi-line "else" branch
that makes the whole "if-then-else" construct render as multiline.)

This is part of a general effort to unify rendering of oneline if/else
statements (either render them all on the same line without braces, or
all on a new line with braces).

Users that prefer always rendering if/else statements in braces should
be able to do so by commenting out `code:if_then_else_oneline`
configuration in the syntax file (`--syntax` option).

Note that default syntax file include/syntax/<language> (the one that is
used without `--syntax` option) is built into re2c; changing it requires
rebuilding re2c with configure option `--enable-syntax` or CMake option
`-DRE2C_REBUILD_SYNTAX=on`.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich c00ea29161 Allow oneline if/else statements for yybm check (bitmaps).
This is part of a general effort to unify rendering of oneline if/else
statements (either render them all on the same line without braces, or
all on a new line with braces).

Users that prefer always rendering if/else statements in braces should
be able to do so by commenting out `code:if_then_else_oneline`
configuration in the syntax file (`--syntax` option).

Note that default syntax file include/syntax/<language> (the one that is
used without `--syntax` option) is built into re2c; changing it requires
rebuilding re2c with configure option `--enable-syntax` or CMake option
`-DRE2C_REBUILD_SYNTAX=on`.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 271746cdbe Allow oneline if/else statements for yyaccept check.
This is part of a general effort to unify rendering of oneline if/else
statements (either render them all on the same line without braces, or
all on a new line with braces).

Users that prefer always rendering if/else statements in braces should
be able to do so by commenting out `code:if_then_else_oneline`
configuration in the syntax file (`--syntax` option).

Note that default syntax file include/syntax/<language> (the one that is
used without `--syntax` option) is built into re2c; changing it requires
rebuilding re2c with configure option `--enable-syntax` or CMake option
`-DRE2C_REBUILD_SYNTAX=on`.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 279c4e20f3 Allow oneline if/else statements for condition dispatch.
This is part of a general effort to unify rendering of oneline if/else
statements (either render them all on the same line without braces, or
all on a new line with braces).

Users that prefer always rendering if/else statements in braces should
be able to do so by commenting out `code:if_then_else_oneline`
configuration in the syntax file (`--syntax` option).

Note that default syntax file include/syntax/<language> (the one that is
used without `--syntax` option) is built into re2c; changing it requires
rebuilding re2c with configure option `--enable-syntax` or CMake option
`-DRE2C_REBUILD_SYNTAX=on`.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich e6057e22b5 Render oneline statements from else branch(es) on the same line.
Keep a few exceptions for `yyaccept` and conditional dispatch for now
(to avoid updating many tests at once).
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 4e330457e7 Allow multiple else branches in syntax configurations for if-then-else. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 82577ce06d CMakeLists.txt: remove unneeded dependency for re2c_test_argsubst. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 7e43200796 Reduce the number of parameters to helper function print_char_or_hex. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich b1a7a11d28 Rename syntax configuration char_literals to yyctype_literals. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich b2701c7f4c Implement codegen model rec/func (recursive functions).
Add syntax configuration "code:recursive_functions".
2024-07-16 06:55:23 +01:00
Ulya Trofimovich c30fe1e7b7 Rename syntax file value rec_funcs to recursive_functions. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 2aaf2b329a Correctly render oneline function call statements. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 472373796c Add syntax configurations for functions: code:fndef and code:fncall.
These are currently used only for skeleton backend (which supports only
C/C++), but later they will be used for rec/func codegen model.

Split codegen for function definitions and function calls. Make it
simpler (don't try to format differently based on the length of
arguments, just output all the arguments on the same line).

Some function calls in skeleton programs are syntactically too complex
(they are part of OR expressions, or they have multiline arguments) ---
for such function calls do not use syntax configurations and fallback to
generating text. This works because skeleton supports only one language
backend.

If there is a need for more complex syntax constructs that contain
function calls in the future, it will be possible to add them as
separate syntax configurations (for that purpose `code:fncall` is an
expression, not a statement).
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 62afc3674d Simplify handling of semicolon when generating function calls. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 2f6c71a38c Initial support for a new codegen model rec/func (recursive functions).
Add options --goto-label and --recursive-functions in addition to the
existing option --loop-switch.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 67f6680ce5 Track "is default" status for global options.
This is needed to correctly set defaults based on syntax file, which is
itself based on global option --lang.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 0d5fe165b3 Get rid of useless macro CONSTOPT1. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 0621b973ed Make YYDEBUG configurable in syntax file or using in-file configuration.
Add tests.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 762ced0a3c Simplify rendering of YYPEEK statement, update syntax configuration. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich d6e2ca3316 Simplify generation of YYDEBUG.
Pass `yych` instead of YYPEEK as the second argument to YYDEBUG.
Also, move YYDEBUG invocation in the initial state past YYPEEK so that
`yych` is properly set to the first symbol.

The motivation for this change is to decouple codegen for YYPEEK and
YYDEBUG statements and avoid having two syntax configurations for YYPEEK
(one for the expression that was previously used in YYDEBUG, and one for
the statement). Also, this helps in cases where YYPEEK modifies internal
lexer state, e.g. reads a character from file and moves file pointer.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 4f7ad682f5 Add basic support for D language (no documentation).
Use examples provided in https://github.com/skvadrik/re2c/pull/431
(suitably modified).
2024-07-16 06:55:23 +01:00
Ulya Trofimovich cf1b735fdb Correctly initialize language (based on RE2C_LANG definition).
Previously re2go/re2rust/re2d binaries erroneously used syntax config
for C/C++ by default.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich a08cdec815 Generate abort in default switch case (for some languages).
Replace syntax configuration `abort_requires_include` with
`abort_in_default_case`. Enable it for Go and Rust, but not for C/C++ as
it requires an `#include` directive that must be provided by the user.

Update Go tests. Rust tests do not need updates because they use a
different codegen model (loop/switch) that has no initial switch on
conditions.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 39cfb282e9 Add syntax configuration code:enum_elem (used to render enum members). 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 7ddb79a70a Generate parentheses around & operator to clarify precedence.
This is only needed if the expression is explicitly compared to zero.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 539c99ea2a Remove language from options. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 20ff170efb Get rid of the last language check using syntax configurtion case_ranges. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 2b7945a75e Do not abort on undefined syntax configurations.
Instead, provide default values:
  - empty string for string-valued configurations
  - false for boolean-valued ones
  - no output for `code:*` configurations

Also, fix an error in libre2c initialization: it now has to manually set
the target option, as it does not load syntax file (and so the options
are not properly initialized).
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 776397ccb0 Get rid of another language check using syntax configuration computed_goto 2024-07-16 06:55:23 +01:00
Ulya Trofimovich f013593448 Get rid of another language check using syntax configuration api. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 02bae836a2 Get rid of another language check using syntax configuration target. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 0872f12815 Replace another language check with syntax configuration semicolons. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich d535fee6ed Add syntax configuration code:loop_label.
This is the first example of a single string valued configuration.
Leave it in the "code" group for now (`code:...`) but add a special
`Stx`method that returns an error if the value is not a single string.
Make the default value empty string, as we don't want to specify such
configurations in syntax files for languages that don't need them.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 1ba6cdd6a5 Add syntax configurations "backtick_quoted_strings" and "standalone_single_quotes".
Use them instead of the language checks in the lexer.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich b51d2b67ab Add Stx reference to immutable (global) options.
This is needed to check syntax configurations from lexer/parser (global
options are the only options available at that point).
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 06f72154ef Implement syntax configuration abort_requires_include. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 8ac61bb6d9 Forward methods that evaluate syntax configurations to opt_t.
This is to simplify calling these methods from the codegen subsystem.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 215ef38d7f Move StxFile to syntax file parser (to avoid pulling it into libre2c sources). 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 320f319faa Constify Stx struct in opt_t.
Options are passed everywhere by const pointer, as they should not be
modified anywhere in the program once they have been set for a block.
Syntax configurations also should be immutable, with the exception of
mutable stacks that are used when evaluating immutable configurations.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 8428bfa82d Move struct Stx into Opt.
The idea is to merge them: configurations in syntax files are yet
another kind of options, and they are always used together with the
usual options.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 911cfa494d Don't copy second output block options into the first block.
This was necessary to fix https://github.com/skvadrik/re2c/issues/201,
where line directives suppression was configured using configuration
`re2c:flags:no-debug-info` (the problem was that it didn't affect the
first block, and the first line directive was generated contrary to the
user's intent).

Now this workaround is no longer needed as the configuration
`re2c:flags:no-debug-info` was deprecated in re2c-2.2 and later removed.

Dropping this allows us to get rid of default copy semantics for `opt_t`
which is necessary in preparation to store `Stx` reference there
(the compiler won't generate default defintions in that case).
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 91dee4a860 Specify prefix for bison-generated primitives in syntax file parser.
So that they don't collide with the main parser (potential collisions
are possible due to header includes).
2024-07-16 06:55:23 +01:00
Ulya Trofimovich d51775c857 Fix "undefined reference" build errors in libre2c library.
Some `Stx::*` methods are now called from src/options.opt.cc, but the
source file that defines them (src/options/syntax.cc) weren't added to
the list of library sources.

The fix is to make these methods inline, as they are small and the other
alternative (to include src/options/syntax.cc) would pull in even more
unrelated source files for the definition of DEFAULT_SYNTAX_{C,GO,RUST}.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 09ffa6a3ab Move syntax* source files from src/codegen to src/options. 2024-07-16 06:55:23 +01:00
Ulya Trofimovich 2c70bf5da2 Disallow conditionals in word configuration (in syntax files).
Conditionals in syntax files were based on options, which caused a
dependency cycle: options required syntax configurations to initialize
default values, and evaluating syntax configurations required options.
Now syntax configurations do not depend on options.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich f83f3903e0 Get rid of conditionals in non-code syntax options.
The only conditional was in `char_literals` (a test for EBCDIC).
It can be as well hardcoded in the re2c source code, as there is nothing
language-specific in it.

The next step will be to simplify non-code syntax configurations and
allow only single word values or word lists (no conditionals).
2024-07-16 06:55:23 +01:00
Ulya Trofimovich c3bb892add Get rid of some language checks when initializing default options.
Use syntax file instead.
2024-07-16 06:55:23 +01:00
Ulya Trofimovich 752c499714 Simplify handling of line directives.
Commit 1d9319548bc97313426499ad7b7aa6dfdfe71ac2 added a fix-up pass that
removes line directives (if they are not needed). It turns out that this
is unnecessary, as line directives cannot be enabled/disabled with a
configuration --- only with a command-line option. This option is
available early at program start, so there's no need for a clean-up pass
as we can test the option before adding line directives.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich b684f22fd0 Add a fix-up pass that removes line directives (if they are not needed).
Line directives are generated by default for C and Go, but not for Rust
(which does not support them at all). They can be turned off/on with a
command-line option or configuration. From the codegen perspective,
there are multiple ways to avoid generating line directives:

  1) do not add them in the first place
  2) remove them during fix-up phase
  3) render them as empty during rendering phase

1 is the most efficient, but it canot be used with configuration, as the
latter may be parsed later than the directive must be generated (some of
them are generated early during parsing, at which point the block
options are not known yet).

3 is the easiest to implement, but it confuses the checks for oneline
statements and results in ugly multiline formatting and lots of trivial
test updates.

Previously we used a combination of 1 and 3: for Rust directives were
not generated (language is an immutable option which is known at program
start), and for other languages directives were generated but not
rendered.

This commit changes the behaviour to 2 and makes it uniform for all
languages. C tests for which re2c is now able to properly detect oneline
statements have been updated.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 305b0d497a Implement syntax configuration implicit_bool_conversion.
Add a function specialized for boolean-valued configurations ("yes" /
"no") and rewrite code for other configurations with it.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 0ea51ba272 Implement syntax configuration semicolons. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 994d4ae525 Implement syntax configuration char_literals.
It is the first configuration of the "word" type (all the previous ones
were "code" configurations).
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 3e274664b8 Implement syntax configuration code:yypeek_expr.
Move YYDEBUG generation to the rendering phase, as it depends on
`code:yypeek_expr`.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 15a5971468 Replace configuration code:bitmap_check with implicit_conv_to_bool.
The only language-dependent syntax is the check against zero which is
emitted for Go but not for C (and Rust codegen does not support bitmaps
at all).
2024-07-16 06:55:22 +01:00
Ulya Trofimovich f85fa16c4b Rust codegen: emit semicolon after panic.
It worked without a semicolon as well because panic was the last
statement in a block. However, this was unintentional and it may change
in the future.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 3645616065 Implement syntax configuration code:abort. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich f5f559df8b Drop unnecessary syntax configuration code:label.
Rust has an unusual syntax for labels: they have to start with a single
quote. But it is inconvenient to encode the quote in a syntax config ---
it's easier to encode it in the name, since the only kind of label used
in Rust is the yyloop label (which has a string name that is configured
with `re2c:label:yyloop` that can easily encode the quote as well).
2024-07-16 06:55:22 +01:00
Ulya Trofimovich bb0bfa189f Implement code:const syntax configuration.
Reuse code item for `code:var` configuration.

Change Go codegen to assume that YYMAXFILL and YYMAXNMATCH are unsigned
and update test results accordingly. (Other codegens already assume that
YYMAXFILL and YYMAXNMATCH are unsigned).
2024-07-16 06:55:22 +01:00
Ulya Trofimovich a65d0ad67b Don't copy options string when creating code items.
Options lifetime covers codegen, and they are not moved.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 9e0cf884bb Use internal scratchbuf stream instead of creating a temporary one. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich a5531ecd7b Use a fake filename for default syntax file (rather than empty string).
This makes error reporting less confusing (in the unlikely case there is
an error in the default syntax file).
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 7f40ae1780 Implement code:line_info syntax configuration. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich bdc040e986 Parse escape sequences in string literals in syntax files. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 4812be8b9f Implement syntax configuration code:fingerprint. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich f143b2dc1c Make code:enum configuration more generic.
Namely:
  - add `have_init` conditional instead of using `jumps.loop_switch`
  - add `type` variable instead of using `storable_state` conditional
    and `code:type_cond_enum` configuration for the underlying type

These changes make `code:enum` more generic and usable not only for the
specific case of condition enum, but for any enum (although it's not
needed at the moment, as condition enum is the only use).

Remove obsolete `GenEnum` class.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich af3c3ca319 Rename OutptuCallback to RenderCallback.
All syntax file base codegen has been moved to rendering phase.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 88e2223326 Render list variable "row" in code:array configuration.
Although it generates no code, it should not cause an abort.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 8a219d3d7b Move language-dependent enum code generation to the rendering phase.
The goal is to do all language-specific codegen during rendering phase
(based on the provided language syntax file).
2024-07-16 06:55:22 +01:00
Ulya Trofimovich ce8f4a7b5b Rename syntax handlers to match code:array configuration. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 0bb7705981 Add a function for evaluating syntax configurations without variables. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 872d601c42 Implement syntax configuration code:type_yytarget. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich e027b25abd Implement syntax configuration code:type_yybm. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 0bd9783532 Rename syntax configuration code:const_array to code:array.
Don't add `static const` type qualifiers in the C syntax file. Instead,
add them as part of the type specified in the re2c source code. This
will be fixed later, as the type should not be hardcoded based on the
language (it will become a config in the syntax file).
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 5f90615f63 Implement syntax configuration code:const_array.
Update syntax files for C and Go.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich cac96326a3 Constify yytarget array in the generated code for C.
It was meant to be constant from the beginning, so the missing `const`
was probably an omission.

Also, generate explicit array size for Go.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 5f8b5a443b Move table codegen from "generate" phase to "render" phase.
Prepare for rendering tables using syntax configuration.

Update test results. There is a lot of changes, but they are trivial:
  - drop optional comma at the end of array initializer for C
  - change formatting: `void *` to `void* `
  - add explicit array size in array definitions
2024-07-16 06:55:22 +01:00
Ulya Trofimovich a9988c4e46 Implement syntax handlers for variable definitions.
Update syntax files for C/Go/Rust accordingly. Remove unnecessary
syntax configuration `code:yyctype`, as it is already configurable
via `re2c:define:YYCTYPE`.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 03d110f45d Delete uselsess syntax configuration label_indent.
This was mean to be used with `code_loop` for languages that have a
label preceding a loop, so that re2c would know whether to indent the
label or not (the default assumption being to indent everything).
However, now that we use explicit `topindent` variable everywhere,
there's no need for `label_indent`.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich e5a0fe4880 Implement syntax handlers for for-loop statements.
Update syntax files for C/Go/Rust accordingly.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich fd26a6e16b Move duplicate code that finds list bounds into a separate function. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich d3ffadb7bf Cache tests for specific syntax configurations in the Stx class. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 9b3c4e3af9 Make configurations map in the Stx class private. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 0aba0ed97c Implement syntax handlers for if-then-else statements.
And update syntax files for C/Go/Rust accordingly.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich cffdfd3e87 Split syntax configurations code:switch_cases and code:switch_cases_oneline.
This is so that syntax files for languages that don't need special
handling for oneline statements (like Go) do not have to handle
`oneline` conditional (which may be confusing and unexpected).
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 90142297ff Implement syntax handlers for switch statements.
Also, update syntax files for C/Go/Rust accordingly.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 9ccd146f79 Fix stack usage during nested calls to Stx::gen_code.
Previously stack was cleared at the beginning of a call, but this wipes
out the state for the outer call.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 94db280d2b Fix check for vars in syntax files.
Previously list vars were erroneously looked up among simple vars as
well (in case they haven't been found among list vars,)
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 88d33f439a Simplify codegen handling of lists in syntax files.
List bounds need to be evaluated at codegen time (not earlier), because
the indices specified in syntax file may be negative and must be
converted to non-negative (the size of a list varies and is not known
until codegen time). To avoid duplicating the same code for every list
handler, this commit moves it to the generic function that renders
syntax trees.

Also, add `eval_cond` method to evaluate conditionals in syntax files
and fix the generic `eval_cond` method to respect configuration-local
conditionals.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 48b05810c3 Use embedded syntax files if no --syntax option has been provided.
This allows one to run re2c/re2go/re2rust without --syntax option and
get the same behaviour as before.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich d4c186b642 Embed default syntax files for all three languages into each binary.
Previously re2c was built with syntax file for C, re2go with that for Go
and re2rust with that for Rust. However each binary needs all three
configs, as the language may be changed dynamically with --lang option.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 1bbcf89767 CMakeLists.txt: add a way to embed syntax files into re2c binary and update them.
Add CMake option RE2C_REBUILD_SYNTAX.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 6f6c0fba7b Makefile.am: add a way to embed syntax files into re2c binary and update them.
Add configure option --enable-syntax.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich be6f7e2a23 Makefile.am, CMakeLists.txt: add syntax files to distribution. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 074250e210 Update CMakeLists.txt with the recently added code for syntax files. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 97fa5ad3e9 Generate code for condition enum based on syntax configuration.
It is the first codegen function that is based on syntax configuration.
The chosen configuration is generic enough: it has lists with specific
bounds, conditionals, global and local variables.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 41c563c50b Update syntax files for C/Go/Rust. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 1ebe649de8 Update the list of allowed syntax configurations and conditionals.
Also, fix associated checks.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 2fb4f360a3 Update syntax file parser for new configuration format.
Code configuration names now start with `code:`, other configurations
can be either lists or conditional expressions.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 66e08da942 Slightly change list syntax in syntax files, improve variable checks. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 8c24b9a09f Add a list of syntax configurations, improve validation of syntax files. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich ca2e0ce183 Slightly reformat option definitions (cosmetic, no functional changes). 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 0cdd39e79c Validate conditionals and variable names in syntax configs. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 3885b0da1b Fix switch statement definitions in syntax configs for C/Go/Rust. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 4a05f11eb6 Store syntax configurations in a map instead of a list. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 1dcbfee713 Merge util/list.h into util/containers.h. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich eebdfddb57 Rename SyntaxConfig into StxFile to unify with other names. 2024-07-16 06:55:22 +01:00
Ulya Trofimovich 1b878f6682 Construct AST for syntax files.
The AST is not used yet, it is only created and discarded.

Also, move list template to a separate file to reuse the existing
definition from codegen.
2024-07-16 06:55:22 +01:00
Ulya Trofimovich 0f27e43f24 Fix syntax file grammar to parse boolean right-hand-side correctly.
Previously it was parsed as part of complex expressions, which should
not be allowed by the grammar as it makes it too lax and introduces
meaningless constructs.

Also, remove parenthesized expressions other than conditionals, as they
aere not used (they also caused LR conflicts in grammar).
2024-07-16 06:55:21 +01:00
Ulya Trofimovich b30bccb4d3 Parse numbers and strings in syntax configs correctly. Use allocator. 2024-07-16 06:55:21 +01:00
Ulya Trofimovich 80e6339242 Remove unused function. 2024-07-16 06:55:21 +01:00
Ulya Trofimovich 045752dc73 Track line/column information for error reporting in syntax configs. 2024-07-16 06:55:21 +01:00
Ulya Trofimovich 4e955f25aa Reuse message class for error reporting in syntax config parser. 2024-07-16 06:55:21 +01:00
Ulya Trofimovich 8cc3315138 Add class that encapsulates parsing details for syntax config files. 2024-07-16 06:55:21 +01:00
Ulya Trofimovich 5acb29fea4 Remove unused and unimplemented method prototype. 2024-07-16 06:55:21 +01:00
Ulya Trofimovich 30fa370ee1 Implement basic lexer/parser for syntax files.
Currently it can parse C, Go and Rust configs without errors, but it
does not build AST yet (parse results are discarded).
2024-07-16 06:55:21 +01:00
Ulya Trofimovich c9c3dc699e Read syntax file contents into a buffer. 2024-07-16 06:55:21 +01:00
Ulya Trofimovich 652f7e3a6d Add initial parser for syntax files (can't parse anything yet). 2024-07-16 06:55:21 +01:00
Ulya Trofimovich 1f5ec6cad7 Add initial lexer for syntax files (can't lex anything yet). 2024-07-16 06:55:21 +01:00
Ulya Trofimovich a760f723e7 Add option --syntax that accepts a path to a syntax file. 2024-07-16 06:55:21 +01:00
Ulya Trofimovich 4fbf0847dc Initial syntax files for C, Go and Rust. 2024-07-16 06:55:21 +01:00
D.musique 6841306953 Flag to make python optional as build dependency
Only require the python dependency when docs, tests or benchmarks are requested.
This makes packaging simpler in some cases (eg. vcpkg).
2024-06-14 18:26:58 +01:00
Peter Kokot 671fc0bc08 Use Python version in find_package()
This simplifies the find_package() call. The version in find_package()
has been initially supported in CMake 2 and 3. Version ranges
(versionMin...[<]versionMax), on the other hand, are only supported by
CMake 3.19+.

And this also helps a bit when adding re2c as a FetchContent dependency
in CMake project where finding Python is not necessary and can be
disabled with CMAKE_DISABLE_FIND_PACKAGE_Python3 variable.
2024-04-24 08:57:30 +01:00
Stephen Wassell 75fa3dbef8 Correct definition of stub CLOSE macro 2024-03-04 21:47:53 +00:00
Ulya Trofimovich 08d414b8b2 Fix undefined behaviour in Rust examples.
This addresses bug https://github.com/skvadrik/re2c/issues/471
"Examples in re2rust manual have undefined behavior".

In Rust, it is UB to call `get_unchecked` on a slice that may be empty,
and many examples had functions that did just that (when invoked on
incorrect input data, since they use some form of sentinel method to
handle the end of input, which relies on the input being sentinel-
terminated).

The introductory example has been fixed to avoid UB and use simple
indexing with bounds checks instead of `get_unchecked`. Other examples
that had UB are now annotated with `assert` that checks conditions under
which the functions are safe to invoke.

Also, eof/02_bounds_checks.re example now uses a more efficient way to
construct YYMAXFILL-padded input string.
2024-02-26 12:53:19 +00:00
Sergei Trofimovich 0fe50b3165 IDEAS.md: fix typo s/inforamtion/information/ 2024-02-26 07:11:34 +00:00
Ivan Egorov 15f503c97f [bazel] Fix _re2c_impl
Mainly `[err_file]` is an undefined variable.

Probably some tl&c would be worth it, converting to bazel module,
but that's for another day.
2024-02-22 17:20:19 +00:00
Sergei Trofimovich 9885ee7119 .github/workflows/ci-cmake.yml: avoid pwd and use ${{ github.workspace }}
It loks like at least in `windows` `actions/upload-artifact@v4` CI step
fails to collect files at `${{ steps.build-info.outputs.BUILD_DIR }}/test_[0-9]*`

My theory is that `glob` is not able to match paths like

    `D:/a/re2c/re2c/install-2`

against theit unix-like form of

    `/d/a/re2c/re2c/install-2`

I suspect that `pwd` returns us the second form while
`${{ github.workspace }}` might keep an original form.
2024-01-31 21:47:43 +00:00
Ulya Trofimovich 1655c7f9a3 GitHub Actions: update versions of dependency actions. 2024-01-31 10:43:56 +00:00
Sergei Trofimovich 1630149d14 .github/dependabot.yml: add basic plumbing to auto-update used actions 2024-01-31 10:40:18 +00:00
Ulya Trofimovich bfa77bc471 Rewrite lexer of string/char literals in code blocks.
Lex char literals properly as single characters or escape sequences
rather than lexing them as single-quoted strings. Add syntax rules from
C/C++, Go and Rust (they are similar and do not contradict).

Add a Go test for string and character literals (prior to this patch it
caused a syntax error).

Note that the same lexer method is used for indented code blocks and
code blocks in curly braces.
2023-12-16 14:52:54 +00:00
Ulya Trofimovich 0ea38276d5 Wrap lexer body in braces only if there're local variable declarations.
This is a revert of commit 77714fce94.

While it is easier to always generate braces, in some languages (Go) it
is a compilation error to jump into the wrapped block (a scenario that
happens if there is an outer state switch generated with `getstate:re2c`
directive.

This regression was found because one of the examples for Go didn't
compile (examples/state/push.go). Now it does.
2023-12-06 21:51:35 +00:00
Ulya Trofimovich 22721f0b0e release.sh: check that examples work. 2023-12-06 21:45:34 +00:00
Ulya Trofimovich 0b6d0b510e CMake: set C++17 standard for benchmarks that use re2. 2023-07-25 07:10:51 +01:00
Ulya Trofimovich 96104a6526 CMakeLists.txt: make C++11 standard required (not optional).
This fixes https://github.com/skvadrik/re2c/issues/455 "Test for C++11
compiler at configure time".
2023-07-21 22:29:45 +01:00
Ulya Trofimovich 59c56044b9 configure.ac: make C++ compiler flag -std=c++11 required (not optional).
This fixes https://github.com/skvadrik/re2c/issues/455 "Test for C++11
compiler at configure time".
2023-07-21 22:15:34 +01:00
Ulya Trofimovich 3841e83f85 Makefile.am: add missing files to distribution.
This fixes https://github.com/skvadrik/re2c/issues/454 "BUILD.md not
present in tarball".
2023-07-21 21:42:54 +01:00
Ulya Trofimovich 7d6641778c BUILD.md: document C++11 requirement.
This fixes https://github.com/skvadrik/re2c/issues/453 "Document C++11
compiler requirement in BUILD.md".
2023-07-21 21:32:51 +01:00
Ulya Trofimovich ece4bb76e3 Release 3.1. 2023-07-19 22:50:22 +01:00
Ulya Trofimovich c3f267b248 release.sh: make the script NixOS-friendly, fix quoting in echo command. 2023-07-19 22:42:25 +01:00
Ulya Trofimovich 60b40d94bd Makefile.lib.am: remove nonexistent header from the list. 2023-07-19 21:47:14 +01:00
Ulya Trofimovich 5abc35226b Update CHANGELOG. 2023-07-18 22:56:45 +01:00
Ulya Trofimovich e868cc58b9 Document configure option --enable-parsers in BUILD.md. 2023-07-13 23:22:55 +01:00
Ulya Trofimovich c633d5de3e Update documentation for capturing and non-capturing groups.
Document the following options:
    --leftomost-captures
    --invert-captures

And the following configurations:
    re2c:leftmost-captures
    re2c:invert-captures

And the new `(! ...)` syntax.
2023-07-13 22:59:47 +01:00
Ulya Trofimovich c86a8bcf5d Add tests for re2c:leftmost-captures and re2c:posix-captures. 2023-07-13 22:27:13 +01:00
Ulya Trofimovich 3a98b54363 Add configuration re2c:leftmost-captures.
It has the same meaning as the --leftmost-captures option.
2023-07-13 22:16:37 +01:00
Ulya Trofimovich 0384cffd9f Fix build scripts for Wine to run on NixOS.
Wine cannot find DLLs by their absolute paths on NixOS, so find and copy
them before running re2c.exe.
2023-07-13 08:06:00 +01:00
Ulya Trofimovich a303a8500d Add missing header include to make src/codegen/code.h self-contained. 2023-07-13 06:22:48 +01:00
Ulya Trofimovich 8c2127d420 Replace enum GorPass with uint32_t as it is used in a bitfield.
It cannot be a `enum class` because it's used in a bitfield and this
triggers compiler warnings and errors on some toolchains (see
https://github.com/skvadrik/re2c/issues/446 for details).

It cannot be a plain `enum` defaulting to `int` as well because of
-Wsigned-enum-bitfield warning (noticed when testing on OpenBSD with
clang-13).
2023-07-12 22:48:57 +01:00
Ulya Trofimovich 54ffc58440 Make function static as it is used in one file. 2023-07-12 22:19:09 +01:00
Ulya Trofimovich 00cbfe90af Drop _POSIX_SOURCE, enable -std=gnu++11 for CMake.
On Unix systems, re2c uses POSIX functions (e.g. fdopen). Certain
systems, such as Cygwin and NetBSD, enable these funtions conditionally
based on certain preprocessor definitions.

Previously https://github.com/skvadrik/re2c/pull/376 fixed the build on
Cygwin by setting _POSIX_SOURCE. However, this broke the build on
FreeBSD which was fixed by commit

This worked for Autotools build system which uses -std=c++11 due to the
use of AC_USE_SYSTEM_EXTENSIONS, but it didn't work for CMake that used
-std=c++11 and disabled extensions with `set(CMAKE_CXX_EXTENSIONS OFF)`.

This commit drops `set(CMAKE_CXX_EXTENSIONS OFF)`, which effectively
enables -std=gnu++11 instead of -std=c++11 for CMake builds. This allows
us to get rid of the problematic _POSIX_SOURCE that breaks the build on
NetBSD.

This was tested on NetBSD-9.3, FreeBSD-13.2 and Cygwin with both
Autotools and CMake.
2023-07-11 23:34:53 +01:00
Ulya Trofimovich bb143b980c libre2c: omit redundant semicolon after namespace.
This gets rid of compiler warnings on some older toolchains (e.g. GCC-10
emits pedantic diagnostic about it, which was fixed in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96068).
2023-07-08 15:02:40 +01:00
Ulya Trofimovich fce87b493f Omit redundant semicolon after namespace.
This gets rid of compiler warnings on some older toolchains (e.g. GCC-10
emits pedantic diagnostic about it, which was fixed in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96068).
2023-07-08 14:17:31 +01:00
Ulya Trofimovich d87f86ed71 Correctly parse raw UTF-8 characters in Flex mode.
With `--flex-syntax` option re2c accepts raw (unquoted) strings.
If `--input-encoding utf8` is also enabled, re2c should parse raw UTF-8
characters in such strings. Previously it failed to do so because the
characters in raw string literals were limited to alphanumeric ASCII and
underscore (those allowed in indentifiers, as in normal mode unquoted
strings would be parsed as identifiers).

This commit fixes it: now in Flex mode and with UTF-8 input, if all
previous rules failed, re2c tries to lex the input as a UTF-8 character.

This fixes bug #447 "Re2go fail when compiling expression containing
combining character".
2023-06-22 07:53:03 +01:00
Ulya Trofimovich d7c697138a Convert GorPass from enum class to plain enum to fix compiler error.
GCC-5.4 is unhappy that `GorPass` which is `enum class: uint32_t` is
stored in a bitfield of size 2 (2 bits). In practice it is safe since
the enum has only three values (0, 1, 2).

Reported in:
  - #445 "make failure for re2c"
  - #446 "make failure for re2c on centos7"
2023-06-18 07:41:04 +01:00
Ulya Trofimovich 580ab173dd run_tests.py: remove exception for overflow-1.re test on Windows.
The test no longer causes stack overflow, so it can now run on Windows
which has a smaller stack than Linux and macOS.
2023-04-27 22:15:20 +01:00
Ulya Trofimovich 6e844850bb run_tests.py: patch backslashes in depfile to fix tests on Windows.
Change file context definition to cover more scenarios that include
filenames, e.g. the case when there is a depfile generated and appended
to the output.
2023-04-27 22:15:20 +01:00
helly25 3205c867bd Provide a min viable http://bazel.build integration.
This allows other projects that use bazel to utilize re2c as a tool.

Limitations:

. Input files (docs, lexer, parser) are not being re-generated.
. No tests are executed.
. Only the main binary is being build as nothing else is needed.

A user will load the package using bazel's 'http_archive' in their
WORKSPACE file.

In their BUILD files they can then use:

```
load("@re2c//bazel:re2c.bzl", "re2c_gen")

re2c_gen(
    name = "file_re2c",
    srcs = ["file.re2c"],
    outs = [
        "file.cc",
        "file.h",
    ]
)

cc_library(
    name = "file_cc",
    srcs = ["file.cc"],
    hdrs = ["file.h"],
)
```

The approach here is to automate as much as possible. In that way, all
source and header files will be found automatically (using glob). Also,
the provided bazel integration is kept to an absolute minimum.

An alternative is to use a `rules_foreign_cc` based approach. But that
would require much more bazel work and knowledge. Plus the result would
end up being a non-hermetic build, thereby bypassing bazel's advantages.
Further, using a rules_foreign_cc approach is much slower (for me ~x10).
2023-04-27 13:22:59 +01:00
Ulya Trofimovich 2dda36aa66 Header file should be a dependency, not a target.
So move it before the colon in the dependency file generated with
--depfile option. This fixes bug #440.
2023-04-26 00:04:33 +01:00
Ulya Trofimovich f807f7636e Add header file to the dependencies generated with --depfile option.
This fixes bug #440 "Generated header file is not present in depfile".
2023-04-25 23:44:14 +01:00
Ulya Trofimovich ce75619557 Add configuration re2c:invert_captures.
Make option --invert-captures configurable. This requires postponing the
decision whether a group is capturing or not to the after-parsing stage
when the configurations for a block are known and the immutable AST is
converted to a regexp.

Add a test for the new configuration.
2023-04-24 23:55:49 +01:00
Ulya Trofimovich dedd72dd66 Add tests for --invert-captures option. 2023-04-24 23:55:49 +01:00
Ulya Trofimovich bf3ff8f3ab Merge AST nodes CAP and REF for capturing and non-capturing groups.
These nodes are similar enough so that it is easier to handle them as
one node with a boolean parameter.
2023-04-21 22:12:40 +01:00
Ulya Trofimovich 20030ff194 Add option --invert-captures.
The new option inverts the meaning on capturing and non-capturing
parentheses: `(! ...)` becomes capturing, and `( ... )` becomes
non-capturing, including the implicit whole-regexp group, which also
becomes non-capturing.

The idea of the new option is to let the user decide which gropus should
be capturing and which are purely structural, and explicitly mark only
the capturing ones for submatch extraction.
2023-04-21 22:10:14 +01:00
Ulya Trofimovich 338806b96c Change syntax for explicit non-capturing groups.
The old syntax was `(? ...)`, the new syntax is `(! ...)`. This is in
preparation to add --invert-captures option that will flip the meaning
of capturing and non-capturing parentheses.
2023-04-19 07:20:42 +01:00
Ulya Trofimovich 6b7a437ab4 GitHub actions: replace set-output command with environment files.
This fixes a warning on GitHub actions workflows: "The `set-output`
command is deprecated and will be disabled soon. Please upgrade to using
Environment Files".
2023-04-11 23:49:06 +01:00
Ulya Trofimovich 8bdc8345cd GitHub actions: update action versions from @v2 to @v3.
This fixes a warning on GitHub actions workflows: "Node.js 12 actions
are deprecated. Please update the following actions to use Node.js 16".
2023-04-11 23:23:36 +01:00
Ulya Trofimovich 0d3eab85be Delete a few tests that are very similar to other tests. 2023-04-11 23:09:27 +01:00
Ulya Trofimovich bb63ccb687 Add tests for the new option --leftmost-captures. 2023-04-11 22:14:35 +01:00
Ulya Trofimovich 1949ed2dec Move and rename tests for capturing groups.
Prepare for adding tests for the new --leftmost-captures option.
2023-04-08 09:18:44 +01:00
Ulya Trofimovich 55de79d8f4 Add option --leftmost-captures.
The new option allows one to use POSIX syntax for capturing groups
with leftmost-greedy disambiguation. This comibination has already
been supported by libre2c, so the changes needed to expose it in re2c
are minimal.
2023-03-25 12:07:17 +00:00
Ulya Trofimovich b813c9b481 Add missing structural parentheses for non-capturing groups.
In the case of POSIX disambiguation (with --posix-captures option) it is
necessary to add structural tags around non-capturing groups, otherwise
disambiguation will be incorrect.

Commit f519385213 that allowed the use of
implicit non-capturing groups didn't properly add structural parentheses
around implicit capturing groups (which are needed if the group contains
nested capturing groups).

Commit 1edd25d31d that added explicit
non-capturing groups repeated the same error, only for the newly added
syntax `(? ...)`.

This resulted in `(? "a"* | ("aa"))*` being parsed incorrectly, as if
leftmost greedy disambiguation was used instead of POSIX disambiguation,
giving priority to the shorter first alternative `"a"` rather than the
longer match `"aa"` as POSIX requires.

This commit ensures correctness for both explicit and implicit
non-capturing groups by adding proper structural tags for the case of
AST sub-node `REF`. It is expected that it will bring back some of the
overhead on POSIX disambiguation reduced by the introduction of
non-capturing groups.

Related bugs: #438, #308.
2023-03-25 10:23:05 +00:00
Ulya Trofimovich 156a947bb3 Rename a few tests.
Rename tests for implicit non-capturing groups so that they are named
similar to the tests for explicit non-capturing groups, and thus easier
to locate and compare.
2023-03-25 08:09:49 +00:00
Ulya Trofimovich 764f4e2de2 Remove unused name field in the AST sub-node REF.
This sub-ode is used for named definitions and non-capturing groups. The
latter do not have a name (previously a dummy name "<group>" was given
to such groups, but it turned out that the name is unused anyway).
2023-03-25 08:03:25 +00:00
Ulya Trofimovich 1edd25d31d Add explicit non-capturing groups.
This is useful in POSIX mode (with --posix-captures option) in order to
avoid unnecessary captures and reduce the amount of tags.

The new syntax for non-capturing groups is `(? ...)`.

Add tests for the new feature. Note that test results coincide with the
corresponding test for implicit groups (where the same group is not
parenthesized at all, but implicit grouping is achieved with the help
of a named definition).

This addresses bugs #438 "POSIX captures processing" and #308
"Overloading precedence marker (e.g. (pattern)) with 'posix' group
markers (also parenthesis) causes loss of full functionality".
2023-03-24 23:45:58 +00:00
Ulya Trofimovich f519385213 Allow implicit grouping with --posix-captures.
Allow the use of named definitions that cause implicit grouping and
circumvent the absence of syntax for non-capturing groups. This is not
allowed by the POSIX standard, but this feature is useful in practice
and many regexp engines support it.

Update the tests that should no longer result into a compilation error.

This addresses bugs #438 "POSIX captures processing" and #308
"Overloading precedence marker (e.g. (pattern)) with 'posix' group
markers (also parenthesis) causes loss of full functionality".
2023-03-24 22:43:48 +00:00
Ulya Trofimovich 8bae0b0557 Extend tests for implicit grouping with --posix-captures. 2023-03-24 22:36:38 +00:00
helly25 d28e5063d1 Fix warning for switch statement for all compilers by providing all enum values. 2023-03-23 17:17:55 +00:00
helly25 91ace6a10e Fix some build warnings. 2023-03-23 12:13:09 +00:00
helly25 d1250a2cd8 Fix documentation "@@(...}" -> "@@{...}". 2023-03-23 12:13:09 +00:00
Ulya Trofimovich 742ff817ac Revert "Introduce Dlang codegen."
This reverts commit 8df0ed6737.

Reason for revert: D backend is not ready yet: there are no examples
and tests, the work on it has stopped. In the future support for D and
other languages should be added in a generic way via language syntax
files, rather than modifying re2c codegen to support each new language.
2023-03-19 22:40:47 +00:00
Ulya Trofimovich 8a0d0a0470 Sort definitions in unicode_categories.txt 2023-03-19 22:38:31 +00:00
Alex Grant Benedict 8df0ed6737 Introduce Dlang codegen.
Dlang supports both case ranges and the pointer API so there are a few changes
related to the error messages in options/opt.cc. The Golang backend has some
test cases that are expected to fail and check for an exact error string.

The syntax of Dlang is very close to that of C. However, there are a few
differences which impact codegen. Case ranges in D are done by
`case ${1}: .. case ${2}:` and there is no implicit fallthrough, so we need a
`goto case` at the end of cases with fallthrough. Also Dlang uses `enum`s for
most compile-time constants, which is similar to C's define macro. Lastly, in
D `char` is unsigned.

Because of the similarities between C and D, we now have some fallthrough
cases to handle both C and D.

References:

https://dlang.org/spec/statement.html#switch-statement
https://dlang.org/spec/statement.html#no-implicit-fallthrough
https://dlang.org/spec/type.html#pointers
https://dlang.org/spec/expression.html#pointer_arithmetic
https://dlang.org/spec/type.html#basic-data-types
2023-01-12 20:19:30 +00:00
Ulya Trofimovich 8196567dac Merge compile.cc into main.cc, get rid of header file compile.h. 2022-11-24 08:55:42 +00:00
Ulya Trofimovich 838398c918 Allocate AST parts which have longer lifetime with the output allocator.
Previosuly they were allocated using AST allocator, which made it
necessary to keep AST memory until the main codegen pass. Now it is
possible to release AST memory after parsing.
2022-11-24 07:45:24 +00:00
Ulya Trofimovich 86cb51e35b Explicitly deallocate memory used for AST. 2022-11-22 23:51:00 +00:00
Ulya Trofimovich 78b84cffdc Check that rendering pass did not generate any unexpected warnings. 2022-11-22 07:47:58 +00:00
Ulya Trofimovich fba7da441a Clean up the way codegen passes are called.
Move loops over output blocks into files that handle each pass.
2022-11-20 17:20:45 +00:00
Ulya Trofimovich 1330e01c34 Get rid of CodegenCtxGlobal. 2022-11-19 13:13:25 +00:00
Ulya Trofimovich 95102ca491 Rename codegen passes, slightly restructure fixup and render passes. 2022-11-18 21:39:02 +00:00
Ulya Trofimovich b8ce97337b Rename codegen files and move code from one file to another. 2022-11-17 22:28:30 +00:00
Ulya Trofimovich b90bcd0a8a Release memory used for DFAs after the main codegen phase. 2022-11-16 23:10:01 +00:00
Ulya Trofimovich 0799d52bfa Get rid of unused codegen context and remove it from the "combine" pass. 2022-11-16 22:20:15 +00:00
Ulya Trofimovich 128c8bf82f Get rid of lat codegen pass that removed empty statements.
This pass is no longer needed after commit
bdbcb1f490 that stopped generating empty
stubs for line directives in Rust.
2022-11-16 22:07:25 +00:00
Ulya Trofimovich e4029874d9 Remove useless late codegen pass.
This pass is no longer needed, as all the transformations have been
moved to other passes.
2022-11-16 21:59:36 +00:00
Ulya Trofimovich bdbcb1f490 Don't generate useless line directive stubs in Rust mode.
Rust does not support line directives. Previosuly re2c generated stubs
that were replaced with empty statements and later removed by a follow
up codegen pass. Now the stubs are not generated at all in Rust mode.
2022-11-16 21:52:01 +00:00
Ulya Trofimovich 5ef4253b80 Move label generation from late codegen to rendering phase.
Labels cannot be generated during main codegen phase: codegen for state
dispatch may add more use cases for block start labels. These labels may
come from blocks either before or after state dispatch that uses them,
which makes it difficult to decide in advance (especially since state
dispatch itself cannot be expanded before the main codegen phase).
Therefore label generation has to be delayed. However, there is no need
for a separate codegen pass, as it can be done by the rendering pass.
2022-11-15 22:50:00 +00:00
Ulya Trofimovich 8f9c605bf6 Get rid of the first delayed codegen pass.
All the functionality has moved to the main codegen pass, as it no
longer needs to be delayed. Second delayed pass still remains: it
expands labels and removes line directives for rust.
2022-11-14 22:43:49 +00:00
Ulya Trofimovich 1af943dce9 Move max:re2c/maxnmatch:re2c expansion to the main codegen phase. 2022-11-14 22:19:40 +00:00
Ulya Trofimovich 9b5bb250c5 Move condition dispatch generation to the main codegen phase. 2022-11-14 22:11:58 +00:00
Ulya Trofimovich 0be4f88adc Move yych/yyaccept/yystate generation to the main codegen phase. 2022-11-14 21:55:29 +00:00
Ulya Trofimovich 2ce67726cc Move condition dispatch generation to the main codegen phase.
It no longer needs to be delayed until late codegen phase, and there is
no need for a special code kind: it can be generated during the main
codegen phase.
2022-11-14 08:02:40 +00:00
Ulya Trofimovich c09efc1635 Move condition enum generation to the main codegen phase.
It no longer needs to be delayed until late codegen phase (all blocks
are parsed before the main codegen phase, and the list of conditions is
known by that time).
2022-11-14 07:33:11 +00:00
Ulya Trofimovich 5633e79453 Move stags:re2c and mtags:re2c expansion to the main codegen phase.
It no longer needs to be delayed until late codegen phase, since all
blocks are parsed before the main codegen phase now.
2022-11-13 21:49:47 +00:00
Ulya Trofimovich 78bd2e39da Move state dispatch generation to the main codegen phase.
It no longer needs to be delayed until late codegen phase.
2022-11-13 16:53:34 +00:00
Ulya Trofimovich 5356f2e2da Always generate YYGETSTATE inside of YYLESSTHAN check.
YYGETSTATE is only needed in the YYFILL call, it doesn't matter in case
YYLESSTHAN check fails and YYFILL is not called at all. The value of
state variable cannot "leak" into semantic action, as it is reset to -1
immediateluy before executing the action.

Previosuly YYGETSTATE was generated inside of the YYLESSTHAN check if
the end-of-input rule $ was used, but outside if it wasn't used. This
commit unifies the behavior.
2022-11-13 16:53:34 +00:00
Ulya Trofimovich d676b6b3e0 Decouple storable state dispatch generation from the main codegen pass. 2022-11-13 16:53:34 +00:00
Ulya Trofimovich c180dfc33b Allocate fill labels in advance before the main codegen pass.
Previously they were allocated during codegen, which implied that
state dispatch in storable state mode had to be generated in the late
codegen phase (because fill labels are used in transitions for state
dispatch).
2022-11-13 16:53:34 +00:00
Ulya Trofimovich 89fa4604d3 Decouple logic for state goto for use blocks and normal blocks.
Use blocks should generate state goto even if it has previously been
generated. However, that should not affect normal blocks (and previosuly
it did, as the global boolean flags was reset when seeing a use block).
2022-11-13 16:53:34 +00:00
Ulya Trofimovich e4f4fac798 Split early codegen into first and second pass.
This is so that we can gather whole-program information during the
first pass and use it during the second pass (obliviating the need for
late codegen).
2022-11-13 16:53:34 +00:00
Ulya Trofimovich b605cfa3b6 Set initial state action together with other actions.
Move it from codegen to where it belongs.
2022-11-13 16:53:34 +00:00
Ulya Trofimovich 71bded8e06 Get rid of OutputFragment, rename a few methods.
The only advantage of `OutputFragment` compared to just `CodeList` was
that it additionally stored indentation level. However, it turns out
that just using top indent in all fragments produces the same output
(some of the fragments are line directives that always use zero indent).
2022-11-13 16:53:34 +00:00
Ulya Trofimovich 85ea9a0e7a Separate parsing and codegen phases.
Previously parsing and early codegen were intermixed: early codegen for
each block was done before parsing for the next block started. This is
problematic, because it creates the need for a late codegen phase that
expands whole-program constructs such as state goto or condition enum.
And then an extra pass is needed to generate labels. Used-label analysis
is spread throughout all phases: some of it is needed before early
codegen (so that we know which goto transitions can be elided and avoid
generating redundant loop/switch cases, and also to decide the need for
backup statement if there is a loop through initial state). But some of
the used-label analysis happens during the late codegen phase (expansion
of state goto may add new uses for start labels).

Separating parsing and codegen will let us simplify codegen, get rid of
the late phase and make used-label analysis and label enumeration more
clean and compact.
2022-11-13 16:53:34 +00:00
Ulya Trofimovich 1817809309 Split codegen for skeleton / dot / code targets into separate functions. 2022-11-13 16:53:34 +00:00
Ulya Trofimovich 6ba82b4c80 Set correct default value for top indent with skeleton.
Default value should be 0. Previously defult value was 2 (for some
reason), and value 0 was set at runtime.
2022-11-13 16:53:34 +00:00
Ulya Trofimovich 77714fce94 Always wrap the generated code in braces.
Previously this was done only if there were declarations of local
variables. However, the cases when braces can be omitted are rare, and
detecting them makes the code more complex for very little value.
2022-11-13 16:53:34 +00:00
Ulya Trofimovich 79215e3bdd Separate loop/switch and label/goto branches in codegen.
They are too dissimilar.
2022-11-13 16:53:34 +00:00
Ulya Trofimovich 22cb071cb2 Simplify generation of start label and dispatch to start conditions.
Start label is only needed for the first DFA in a block: although it was
previously attributed to a DFA, it should be attributed to the whole
block. Autogenerated start label is used by state dispatch in storable
state mode. It is generated before condition dispatch, which is also
generated once per block.

This patch moves start label and condition dispatch generation out of
the per-DFA codegen loop and makes it explicit that they are generated
once per block.
2022-11-13 16:53:34 +00:00
Doug Cook (WINDOWS) 374b5ecc84 BUILD.md - update dependencies, info about cmake presets
- In addition to a C++ compiler, Windows builds require a build system
  (CMake or bash). Clarify the dependencies to say this.
- Python 3 is required for tests, and tests should always be available,
  and both CMake and Automake give a hard error for missing Python 3,
  so just say Python 3 is required.
- Update docs rebuild dependencies to specify Python3 and Docutils,
  since that is what you need to install to make rst2man available.
- Add an explanation of how to use the CMake presets since they're pretty
  good.
- A few other minor corrections.
2022-11-07 21:13:22 +00:00
Doug Cook (WINDOWS) 3a10633b8c Remove unused .sh scripts 2022-11-07 08:10:30 +00:00
Doug Cook (WINDOWS) fcdca1f411 Autotools - use rst2txt for docs
- Prequisite check for Python3 docutils module instead of rst2man.
- Use `split_man.py` instead of `split_man.sh`.
- Use `rst2txt.py` instead of `rst2man` + `gen_help.sh`.
- Explicitly use `$(PYTHON) <scriptname>` when calling python scripts.
2022-11-07 08:10:30 +00:00
Ulya Trofimovich e3ec259703 Regenerate Unicode tests and include header to support a newer standard.
Regenerate files using haskell script test/encodings/unicode_groups.hs
that is based on Data.Charset library (charser-0.3.9 package). The
script generates tests in test/unicode directory inplace and include
file unicode_categories.re.inc that needs to be copied to
include/unicode_categories.re.

Update test results. As there are substantial changes in the standard,
updates are also nontrivial. They have been verified with
test/__run_unicode_tests.sh.

The three examples for C, Rust and Go were werified with __run_all.sh
scripts in examples/{c,go,rust) respectively.
2022-11-04 08:02:02 +00:00
Ulya Trofimovich f006e75513 Add missing header include.
This fixes issue #424 "Failed to build master branch on Cygwin/MSYS2
fails".
2022-11-01 22:01:59 +00:00
Doug Cook (WINDOWS) 34753db06e Fix repository CRLF on Windows 2022-10-25 07:41:42 +01:00
Doug Cook (WINDOWS) 130efff19c Enable CMake re2rust.1, update bootstrap docs 2022-10-25 07:41:42 +01:00
Doug Cook (WINDOWS) d4ba85be51 CMake - Windows-compatible doc bootstrapping
Pretty much every Python install includes Docutils, and Docutils is 95%
of what is needed to bootstrap docs on Windows. Fill in the rest.

- `docutils_txt.py` is a Docutils text-output Writer class with support for
  writing a C file.
- `rst2man.py` is a wrapper for Docutils converting to MAN file. (Copied
  from Docutils repo.)
- `rst2txt.py` is a wrapper for Docutils converting to TXT file. (Same
  as rst2man.py but it uses docutils_txt as the Writer.)
- `split_man.py` is a Python implementation of `split_man.sh`.
- Change CMake build to use the new scripts.

Additional changes:

- CMakeLists: give error message if docutils module not found.
- ci-cmake: Give hint about where to find Python3 so that the private
  install is preferred over the system install. Enable docs regen for
  Windows.
2022-10-25 07:41:42 +01:00
Sergei Trofimovich 7adf8372f6 src/util/check.h: always use DCHECK(x) argument to avoid warnings
Without the change on `gcc-13` build warns as:

    ./src/parse/input.h: In member function 're2c::loc_t re2c::Input::cur_loc() const':
    ./src/parse/input.h:139:20: warning: unused variable 'p' [-Wunused-variable]
      139 |     const uint8_t* p = cur;
          |                    ^

The change turns `DCHECK(x)` into a statement that uses `x`.
2022-10-22 17:28:34 +01:00
Ulya Trofimovich c40ebdb37f Output user-defined start label before the autogenerated one.
User-defined start label is generated once per block, and autogenerated
labels are generated once per each start condition.
2022-10-07 23:35:06 +01:00
Ulya Trofimovich 35913e09e8 Append condition to bitmap name, define all bitmaps at block start.
Previously if start conditions were used, bitmap definitions were
generated at the start of each condition, as they all had the same name
(`yybm` or a user-defined one). This was problematic in storable state
mode, as transitions to `YYFILL` labels bypassed bitmap declaration
(state dispatch is always at the beginning of a block).

Now we use condition-specific names for bitmaps (`yybm` plus underscore
and condition name), so they can all be defined together before state
dispatch, as it happens in blocks that do not use start conditions.
2022-10-07 07:41:07 +01:00
Ulya Trofimovich dff7d0475b Slightly simplify codegen logic that decides if outer braces are needed. 2022-10-06 22:39:44 +01:00
Ulya Trofimovich 6cf371a5b7 Don't generate redundant newline with --storable-state option. 2022-10-05 23:06:03 +01:00
Ulya Trofimovich 4a63376a2f Move code that is specific to the first iteration out of loop. 2022-10-05 22:52:54 +01:00
Ulya Trofimovich 0365d2b03c Move codegen structs into a separate header file. 2022-10-04 07:23:13 +01:00
Ulya Trofimovich a0f1f7f77a Move prolog/epilog generation to separate methods in the Output class. 2022-10-01 20:25:36 +01:00
Ulya Trofimovich f7abcf9864 Rename a few lexer-related classes and functions. 2022-10-01 13:17:22 +01:00
Ulya Trofimovich 0ac0cc5026 Fix -Wmismatched-tags warning. 2022-09-30 07:35:58 +01:00
Ulya Trofimovich 08950f9701 Fix -Wconditional-uninitialized warning. 2022-09-30 07:25:33 +01:00
Ulya Trofimovich ebf0b776e6 Provide wrappers for error reporting functions in the lexer. 2022-09-29 23:32:11 +01:00
Ulya Trofimovich f811c7c6a8 Handle potential strftime errors. 2022-09-29 22:09:13 +01:00
Ulya Trofimovich e988f0ba2b Merge scanner.{h,cc} into input.{h,cc}.
Both pairs of files contain lexer-related declarations and definitions,
the headers are usually included together, and the input.{h,cc} files
are very small.
2022-09-28 07:34:54 +01:00
Ulya Trofimovich dd13fe22af Rename a few AST-related structs, add more comments.
In particular, use term "grammar" rather than "specification".
2022-09-25 07:45:40 +01:00
Ulya Trofimovich ff0e44d9ad Give more precise error (with location) on unexpected end of input.
Also, simplify the logic that prevents parser from reporting a generic
"syntax error" after lexer has already reported a more precise one.
2022-09-24 21:06:13 +01:00
Ulya Trofimovich 51cd34470d Rework the way parameters are passed to the parser.
Do not use a struct, instead pass individual parameters. They are often
used in semantic actions, and addressing them as struct fields adds too
much noise in the source code.
2022-09-24 21:00:21 +01:00
Ulya Trofimovich 7f9e6a78d2 Merge ast.{h,cc} and parse.{h,cc} as both pairs contain AST decls/defs. 2022-09-24 13:04:48 +01:00
Ulya Trofimovich 96ab1a35a7 Renamed a couple of files. 2022-09-22 00:08:45 +01:00
Ulya Trofimovich a5a1a89128 Rename RE structure to Regexp (cosmetic). 2022-09-18 07:43:15 +01:00
Ulya Trofimovich 47f1979115 Move a few functions and remove empty header. 2022-09-18 07:43:15 +01:00
Ulya Trofimovich bb3aa1a14b Remove space before opening parenthesis (cosmetic). 2022-09-18 07:43:15 +01:00
Ulya Trofimovich 6d2611d475 Rename identifiers in camelCase to snake_case (cosmetic). 2022-09-18 07:43:15 +01:00
Ulya Trofimovich c5bc8667e9 Rename DFA to Adfa to reflect that it is "action DFA" (cosmetic). 2022-09-18 07:43:15 +01:00
Ulya Trofimovich 0b15b1eeb0 Reorder options in source file: group them by name (cosmetic). 2022-09-18 07:43:15 +01:00
Ulya Trofimovich 8b8409dd31 Rename options (no API changes, just the names in the source code). 2022-09-18 07:43:15 +01:00
Ulya Trofimovich a6d0e75d96 Rename determinization context fields (get rid of "dc_" prefix).
Prefix was used inconsistently, and other structs/classes don't do it.
2022-09-18 07:33:16 +01:00
Ulya Trofimovich 511a030c0c libre2c: remove GTOP shortest path finding algorithm.
It performs almost identical to GOR1 (sometimes slightly better or
worse), but it has no proven worst-case bound.

Apparently both the updated test and benchmark erroneously flipped GOR1
and GTOP (but the results were so close it didn't matter).
2022-09-18 07:33:13 +01:00
Ulya Trofimovich aa97b01494 libre2c: remove Kuklewicz POSIX disambiguation algorithm.
Previous studies and benchmarks have shown that it is suboptimal, and
an adaptation of Okui-Suzuki algorithm for TNFA is faster.
2022-09-18 07:31:53 +01:00
Ulya Trofimovich 27256be1ed libre2c: remove incorrect backward-matching algorithm.
It was interesting for experimental/benchmarking purposes, but now it is
no longer needed and can be removed.
2022-09-18 07:31:53 +01:00
Sergei Trofimovich 508de1570c bison parsers: mark static yylex() and yyerror()
Unused exported symbols are detected by uselex:

    yyerror: [R]: exported from: src/parse/re2go-parser.o src/parse/parser.o src/parse/re2rust-parser.o
    yylex: [R]: exported from: src/parse/re2go-parser.o src/parse/parser.o src/parse/re2rust-parser.o
2022-09-04 08:00:53 +01:00
Sergei Trofimovich 8161d996f0 bison parsers: switch to pure bison API
Before the change parsers relied on `YYSTYPE` global variable.
Not very handy for libre2c if it's expected to be used in reentrant
or multi-threaded contexts.

The change enables `%define api.pure full` and adjusts lexer calls
to explicitly pass through `YYSTYPE` around.

`%define api.pure full` is preferred to `%pure-parser` (deprecated in
2008, around Bison 2.3b). Should be safe to use.
2022-09-03 20:17:15 +01:00
Sergei Trofimovich efa2ab027b build system: disable timestamp generation for bootstrap files
Eases diff inspection on lexer changes.

While at it dropped deprecated '-r' option.
2022-09-03 19:15:02 +01:00
Sergei Trofimovich 87cf19bf58 cmake/Re2cBootstrapParser.cmake: change flag order to match Makefile.am
Autotools-based and cmake-based build systems had slightly different flag order:

    Makefile.am:    $(AM_V_GEN)$(BISON) --warnings --output=$@ --defines=$(@:cc=h) $<

Let's make them identical.
2022-09-03 18:44:54 +01:00
Sergei Trofimovich 7e7c4b97af src/parse/parser.ypp: use %empty token for empty rule
New `bison --warnings` gives the following helpful diagnostic:

      GEN      src/parse/parser.cc
    src/parse/parser.ypp:60.2: warning: empty rule without %empty [-Wempty-rule]
       60 | : /* empty */
          |  ^
          |  %empty

%empty was introduced in bison-2.7.90 around 2013.
2022-09-03 18:09:14 +01:00
Sergei Trofimovich 67a58414ce build system: enable --warnings for bison
The change allows catching fresh bison diagnostics. Current example:

      GEN      src/parse/parser.cc
    src/parse/parser.ypp:60.2: warning: empty rule without %empty [-Wempty-rule]
       60 | : /* empty */
          |  ^
          |  %empty

The warning itself will be fixed in another change.
2022-09-03 18:09:14 +01:00
Sergei Trofimovich c18aed9f21 .github/workflows/ci-autotools.yml: use latest bison from brew 2022-09-03 18:09:14 +01:00
Ulya Trofimovich 111ee5da7b GitHub Actions: limit stack for tests to 256K.
Run tests as:
    bash -c "ulimit -s 256; make check -j$(nproc)"

I also verified that the tests fail on CI without commit
460412913771e9b7b9506bc623470195f6ccf21e (the last change that was
needed to fix #219).
2022-07-25 08:35:51 +01:00
Ulya Trofimovich 5fffb18701 Rewrite recursion into iteration for rule liveness analysis.
This fixes bug #219. Tested as follows (all tests passed):

    bash -c "ulimit -s 256; time ./run_tests.py"

Original test that revealed the problematic recursive functions:

    bash -c "ulimit -s 256; echo run | gdb --args ./re2c overflow-1.re"
2022-07-25 08:35:51 +01:00
Ulya Trofimovich 02e5d79784 Rewrite recursion into iteration for AST to range conversion.
This partially addresses bug #219.
2022-07-24 16:28:25 +01:00
Ulya Trofimovich a8bf479067 Avoid repeated computation of "has captures" property for AST subtrees.
Save this information in each subtree and compute it bottom-up on AST
construction. This means a slight constant overhead on construction for
non-POSIX case (where this information is unused), but it eliminates a
worst-case quadratic algorithm for the POSIX case (where the property
was recomputed for each alternative/concatenation subexpression).

Note that tags were counted as captures by the old implementation, but
not by the new one, as POSIX regexps cannot have standalone tags.
2022-07-24 16:28:25 +01:00
Ulya Trofimovich 72a304cc28 Add outer decls for static constexpr data members (required by C++11).
In C++17 this is no longer necessary (it makes static constexpr data
members implicitly inline).
2022-07-24 16:28:25 +01:00
Ulya Trofimovich aaf6829263 Rewrite AST to RE conversion using iteration instead of recursion.
This partially addresses bug #219.
2022-07-24 16:28:25 +01:00
Ulya Trofimovich 9724f16b93 Reorder functions (to avoid declaring prototypes at the top of file). 2022-07-24 16:28:25 +01:00
Ulya Trofimovich 6bf6a5896b Rename files (related to multi-pass TDFA). 2022-07-24 16:28:25 +01:00
Ulya Trofimovich 643d387133 Rename (some) structs to follow uniform type naming rules.
Lowercase type names prefixed with `_t` are used for containers and
utility structures. Domain-specific types use camel case.

Also, rename REG_REGLESS to REG_MULTIPASS (but keep the old constant
definition for compatibility).
2022-07-24 16:28:25 +01:00
Ulya Trofimovich 4191b0a54f Slightly restructure TNFA state fields. 2022-07-24 16:28:25 +01:00
Ulya Trofimovich 46a9b4c46e Rewrite TNFA construction using iterative approach instead of recursion.
This partially addresses bug #219.
2022-07-24 16:28:25 +01:00
Ulya Trofimovich bc3a1c2770 Use unsigned character type in the lexers, enable -Wold-style-cast.
Previously we used signed characters and `re2c:yych_conversion = 1;` to
convert from char to uint8_t in the generated lexer code (the lexer
compares `yych` to various literals which may be outside of the signed
ASCII range, depending on the lexical grammar). As a consequence,
-Wold-style-cast was disabled.

Unfortunately now we have to disable -Wreserved-identifiers, as it warns
about user-defined literal suffixes like `_u8` that must start with an
underscore (the standard reserves non-underscore prefix for the future).
2022-07-07 09:03:29 +01:00
Ulya Trofimovich 89a467908c Disable -Wc++98-compat-pedantic with -Weverything (as re2c uses C++11). 2022-07-07 08:57:40 +01:00
Ulya Trofimovich 7e00ea55ae Enable -Wglobal-constructors (with -Weverything). 2022-07-06 23:24:21 +01:00
Ulya Trofimovich 6264787bb1 Add static_cast to fix warning on platforms with 32-bit long. 2022-07-06 22:08:46 +01:00
Ulya Trofimovich f199f3a915 GitHub Actions (CMake): build with -j$(nproc). 2022-07-06 07:45:29 +01:00
Ulya Trofimovich 1f01ceb32b GitHub Actions (Autotools): add nproc on macOS (from coreutils). 2022-07-06 07:27:40 +01:00
Ulya Trofimovich 8e1f7c7c8b Reduce the number of different allocators, make them safer to use.
Use four basic allocator types (defined as different structs, so not
possible to mix with each other by accident):

    - AST allocator (may be shared between blocks)
    - IR allocator (intermediate representations for a single DFA)
    - DFA allocator (codegen for all DFA in a block)
    - output allocator
2022-07-05 23:53:49 +01:00
Ulya Trofimovich a53062c159 CMake: use /W3 not /Wall for MSVC.
Even /W4 emits too much (informational warnings that we are not going to
fix), and /Wall is /W4 plus some warnings that are off by default. See
https://docs.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level

Also disable some selected warnings that add to much noise (C4068 that
complains about unused pragmas and C4996 that complains about functions
like `fopen`).
2022-07-05 23:53:49 +01:00
Ulya Trofimovich 5574e40171 CMake: exclude -Wc++98-compat from -Weverything.
re2c uses C++11, not C++98.
2022-07-05 23:53:49 +01:00
Ulya Trofimovich 2f28225b88 Ignore -Wunused-macros warning for a platform-specific macro. 2022-07-05 23:53:49 +01:00
Ulya Trofimovich 12fe914395 Ignore -Wunused-macros warnings in Bison-generated code.
Previously some of the warnings have been disabled with pragmas, but not
all warnings can be fixed this way, as some of the macros are emitted
too early (before the pragmas).

The fix is to "use" the macros in trivial `#ifndef` clauses.
2022-07-05 23:53:49 +01:00
Ulya Trofimovich 6aee0f1076 Explicitly handle enum values in switch to fix -Wswitch-enum warning. 2022-07-05 23:53:49 +01:00
Ulya Trofimovich ae8b9b179b Remove useless default clause reported by -Wcovered-switch-default. 2022-07-05 23:53:49 +01:00
Ulya Trofimovich 08797d4a89 Remove unused variables reported by -Wunused-variable. 2022-07-05 23:53:49 +01:00
Ulya Trofimovich c3995c3edb Remove unused function templates reported by -Wunused-template. 2022-07-05 23:53:49 +01:00
Ulya Trofimovich a0d8aa952c Remove useless comparison reported by -Wtautological-type-limit-compare. 2022-07-05 23:53:49 +01:00
Ulya Trofimovich fec2a6c808 Rename variables to fix -Wshadow warning. 2022-07-05 23:53:49 +01:00
Ulya Trofimovich ae67b2c98a Initialize variable to fix -Wconditional-uninitialized warning. 2022-07-05 23:53:49 +01:00
Ulya Trofimovich f7095954bd Remove unused macro. 2022-07-05 23:53:49 +01:00
Ulya Trofimovich 2b34974da4 Use printf modifiers %z and %t for size_t and ptrdiff_t.
They were added in C99, so should be available in C++11.

For int64_t / uint64_t use PRId64 / PRIu64 macros from <cinttypes>.

Also fix some formatting issues.
2022-07-05 23:53:49 +01:00
Sergei Trofimovich 243083b29b autogen.sh: drop dangerous 'git clean -dfx' command
Now it's just a one-liner autoreconf.
2022-07-05 23:44:22 +01:00
Sergei Trofimovich 19595aee4d .github/workflows: add basic autotools workflow 2022-07-05 23:30:17 +01:00
Sergei Trofimovich dc1adfaa9a configure.ac: remove redundant escapes 2022-07-05 07:04:33 +01:00
Sergei Trofimovich 0fcb43a7ae .github/workflows: rename ci.yml to ci-cmake.yml
A prerequisite for basic autotools-based build.
2022-07-05 07:04:20 +01:00
Ulya Trofimovich 51c3d5f5ac Replace standard assert with custom CHECK that ignores NDEBUG.
Assertions are used in tests and elsewhere to verify assumptions that
must be correct, or else the program should abort. Compiling them away
in release mode is dangerous. For debug-mode assertions we use `DCHECK`.
2022-07-03 09:24:37 +01:00
Ulya Trofimovich badb1524a7 Fix NDEBUG-mode compiler warning about unused function parameter.
The parameter was used only in `assert`, so there was no warning in
NDEBUG mode.
2022-07-02 19:39:20 +01:00
Ulya Trofimovich f2d85745cc GitHub Actions: run Valgrind tests on CI. 2022-07-02 19:12:30 +01:00
Ulya Trofimovich 8097795340 Fix memory leaks.
A previous fix of error handling revealed memory leaks caused by not
destructing common data structures like tags, rules and charset that
live through different intermediate representations and move from one to
another (regexp -> TNFA -> determinization context -> TDFA -> ADFA).

Previously they were stored as references, and the last IR (ADFA) took
the responsibility for destroying them. This works with normal control
flow, but if there is an error in one of the previous IRs, the program
exits without constructing and (what matters here) destructing ADFA.

The fix is to use move semantics introduced in C++11: instead of storing
references, store values and move common data structures from one IR to
another. This way they are always owned and destroyed by the same IR
that causes the error.

This patch makes all tests pass under valgrind:

  $ ./run_tests.py --valgrind

  $ LD_LIBRARY_PATH=.libs \
    G_SLICE=always-malloc \
    G_DEBUG=gc-friendly \
    GLIBCXX_FORCE_NEW=1 \
      valgrind \
        --track-origins=yes \
        --trace-children=yes \
        --num-callers=50 \
        --track-fds=yes \
        --leak-check=full \
        --show-reachable=yes \
        --malloc-fill=0xa1 \
        --free-fill=0xa1 \
        --suppressions="$HOME/misc/valgrind/all.supp" \
      .libs/test_libre2c
2022-07-02 18:13:23 +01:00
Ulya Trofimovich 3a9b98a0c7 Use std::vector instead of std::valarray for rules.
A long time ago `std::valarray` was used because it did not require copy
semantics for rules. But this depends on the libstdc++ implementation
(if I remember correctly, macOS implementation required copy semantics).
2022-07-02 16:25:39 +01:00
Ulya Trofimovich ff408ec4ce Add proper error handling.
Instead of doing `exit(1)` after printing an error message, return
error code to the calling function and propagate it all the way back to
`main`. Avoid boilerplate and bloating the code with checks by using
consistent error codes throughout the codebase and wrapping function
calls in a `CHECK_RET` macro. Use another macro `RET_FAIL` for errors.

This change has reduced the number of failing tests under valgrind from
131 to 32 (previously all the tests that report an error failed, because
`exit(1)` bypassed the destructors and didn't free memory).
2022-06-29 23:56:43 +01:00
Ulya Trofimovich 43a1a08732 CMake: ensure autogenerated headers are built before included.
In CMake this is done by adding autogenerated sources to an "object
library", which is not really a library, but just a collection of files
that can be used as a library in the sense that other targets can depend
on it. The dependency can be achieved by either adding it explicitly to
another library with something like `target_link_libraries`, or by
adding the object library to the list of source files.

For libre2c the latter was done slightly differently (and incorrectly):
instead of listing object libraries in the list of sources, normal
sources were added to another object library, and the object libraries
for autogenerated and normal sources were listed as sibling entries on
the sources list. So there was no dependency from the object library for
normal sources on the object library for autogenerated sources.

This caused build errors when a normal source file included an
autogenerated header, which was not generated yet. The fix is to not use
object library for normal sources.
2022-06-29 23:56:43 +01:00
Ulya Trofimovich 81c37adbab Optimize the way lexer and parser allocate intermediate values.
For some allocations, move them to slab allocators. For others, replace
them with temporary buffers. Avoid allocating and freeing temporary
values with `new`/`delete`, which was previously done in order not to
store "fat" value on the parser stack (also since non-POD values cannot
be stored in the `yylval` union).
2022-06-29 07:40:03 +01:00
Ulya Trofimovich 1fef8d161a Get rid of local_increment_t as it was only used in one place. 2022-06-29 07:40:03 +01:00
Ulya Trofimovich cc60dcb4f1 Update CONTRIBUTING.md: explain --enable-parsers / RE2C_REBUILD_PARSERS. 2022-06-29 07:40:03 +01:00
Ulya Trofimovich 6e91c22dfe Add CMake option RE2C_REBUILD_PARSERS (it requires Bison).
Previosuly CMake checked for Bison, and if it was present, then it
regenerated parsers and updated bootstrap files. Now it checks
RE2C_REBUILD_PARSERS, and if it is enabled, then CMake fails if it
cannot find Bison, regenerates parsers and updates bootstrap files.
2022-06-29 07:40:03 +01:00
Ulya Trofimovich 9e0dbd3c7c Add configure option --enable-parsers (regenerate parsers with Bison).
This fixes `make distcheck`, which previously failed when trying to
update bootstrap parser (it makes the source directory read-only. Now it
no longer fails because rebuilding parsers is disabled by default.

Also, cleanup Makefile.am implementation for rebuilding lexers with
RE2C_FOR_BUILD: there is no need to check that the re2c executable
exists, as it is done by configure.ac.
2022-06-23 07:53:18 +01:00
Ulya Trofimovich 4cb1a5d567 Consolidate and rename a few headers in src/util. 2022-06-22 23:40:50 +01:00
Ulya Trofimovich 8bb8100853 Rewrite SemAct to use slab allocator instead of a free list.
As this was the last remaining use of `free_list`, remove it altogether.
2022-06-22 08:12:39 +01:00
Ulya Trofimovich 731fb70b28 Use namespaces instead of classes with static functions. 2022-06-21 22:57:56 +01:00
Ulya Trofimovich 3dbc2801b9 Flatten file layout for encoding subsystem, merge small headers. 2022-06-21 22:45:39 +01:00
Ulya Trofimovich 1b1326ecf0 Rewrite RangeSuffix to use slab allocator instead of a free list. 2022-06-21 22:12:36 +01:00
Ulya Trofimovich d534094f20 Rewrite uniq_vector_t to behave more like std::vector.
Make `uniq_vector_t` inherit from `std::vector` and hide a few methods
instead of aggregating `std::vector` and wrapping some of the methods.
2022-06-21 08:26:47 +01:00
Ulya Trofimovich 265da45938 Move uniq_vector_t to util/containers.h. 2022-06-21 07:32:53 +01:00
Ulya Trofimovich f462d48347 Move lookup_t to util/containers.h. 2022-06-21 07:23:53 +01:00
Ulya Trofimovich 9535bbcaa6 Make membuf_t more like a container and move it to util/containers.h. 2022-06-21 00:09:04 +01:00
Ulya Trofimovich fdacb97620 Move to C++11: use uniform initialization syntax to reduce boilerplate. 2022-06-21 00:09:04 +01:00
Ulya Trofimovich 377fe6bf75 Rewrite AST construction, use slab allocator instead of a free list. 2022-06-21 00:09:04 +01:00
Ulya Trofimovich 90856c5f0b Move to C++11: replace typedef with using. 2022-06-19 11:13:02 +01:00
Ulya Trofimovich 2cebd41ed4 Move to C++11: use standard static_assert instead of a local one. 2022-06-19 10:48:44 +01:00
Ulya Trofimovich fbae2a09cc Move to C++11: use static constexpr instead of static const where possible. 2022-06-19 09:31:44 +01:00
Ulya Trofimovich a6f7defb42 Remove unused enum definition. 2022-06-18 19:55:18 +01:00
Ulya Trofimovich 812f80fac9 Move to C++11: convert enum lexer_state_t to enum class LexMode. 2022-06-18 18:57:04 +01:00
Ulya Trofimovich f6888dfdbd Move to C++11: convert enum AST::type_t to enum class AST::Kind. 2022-06-18 18:52:34 +01:00
Ulya Trofimovich e0e1e38db4 Move to C++11: convert enum Action::type_t to enum class Action::Kind. 2022-06-18 18:34:08 +01:00
Ulya Trofimovich a8f22e1c29 Move to C++11: convert enum nfa_state_t::type_t to enum class nfa_state_t::Kind. 2022-06-18 18:25:56 +01:00
Ulya Trofimovich b066007ca3 Move to C++11: convert enum RE::type_t to enum class RE::Kind. 2022-06-18 18:14:59 +01:00
Ulya Trofimovich 9040ace1a9 Move to C++11: convert enums in codegen to enum classes. 2022-06-18 17:52:14 +01:00
Ulya Trofimovich b83d4a5427 Move to C++11: use constexpr for UTF-8 constants. 2022-06-18 17:36:24 +01:00
Ulya Trofimovich f84e41959a Move to C++11: convert enum Enc::policy_t to enum class Enc::Policy. 2022-06-18 17:27:08 +01:00
Ulya Trofimovich d4845e2ec2 Move to C++11: convert enum Enc::type_t to enum class Enc::Type. 2022-06-18 17:17:28 +01:00
Ulya Trofimovich 57c79c13ca Autoformat re2c source code (with some manual tweaks).
This is the `astyle` command used for autoformatting:

    $ # run in source directory
    $ astyle --style=google \
             --max-code-length=100 \
             --align-pointer=type \
             --align-reference=type \
             --keep-one-line-statements \
             --suffix=none \
             --recursive '*'
2022-06-18 15:55:46 +01:00
Ulya Trofimovich dc8f264aa7 Remove TDFA(0) algorithm.
Benchmarks show that TDFA(1) is generally faster than TDFA(0); see the
official re2c website: https://re2c.org/benchmarks/benchmarks.html, or
the paper https://arxiv.org/abs/2206.01398 for details.

The benchmarks for TDFA(0) now use re2c-3.0 to build.
2022-06-13 23:15:50 +01:00
Ulya Trofimovich ac5c06ccb5 Remove staDFA algorithm.
Although it is an interesting algorithm, re2c benchmarks show that it
performs worse than TDFA(1): on complex regular expressions staDFA are
often much larger and slower than TDFA(1). See the benchmarks on the
official re2c website: https://re2c.org/benchmarks/benchmarks.html, or
the paper https://arxiv.org/abs/2206.01398 for details.

StaDFA implementation adds complexity to the most complex part of re2c
code -- determinization, and it takes some effort to maintain.

The algorithm is not fully documented and formalized: the original paper
by Chowdhury is incomplete, and the implementation is re2c had to use a
few fixes and modifications to make it work.

The benchmarks for staDFA now use re2c-3.0 to build.
2022-06-13 21:44:17 +01:00
Ulya Trofimovich ad7451a7f1 Move to C++11: define move ctor/assgnment in addition to copy ones. 2022-06-12 07:34:26 +01:00
Ulya Trofimovich a939a6eb9e Move to C++11: use 'default' keyword for copy ctor/assignment. 2022-06-11 23:21:56 +01:00
Ulya Trofimovich 753c09148f Move to C++11: use 'delete' keyword to forbid copying. 2022-06-11 23:09:02 +01:00
Ulya Trofimovich 98aa445546 Move to C++11: use range-for where possible. 2022-06-11 22:59:31 +01:00
Ulya Trofimovich 0aff7b9eae Move to C++11: fix a couple of -Wshadow warnings and use range-for. 2022-06-10 22:46:26 +01:00
Ulya Trofimovich b8f465ab29 Disable -Wzero-as-null-pointer-constant on re2c-generated code.
The generated code contains NULL in registed operations on TDFA
transitions (NULL is the default value for negative tags).
2022-06-10 22:30:19 +01:00
Ulya Trofimovich 0a5b271919 Move to C++11: convert enum gor_status_t to enum class GorPass. 2022-06-10 22:02:14 +01:00
Ulya Trofimovich 9e99220894 Move to C++11: specify underlying type for enum DirConf. 2022-06-10 21:50:09 +01:00
Ulya Trofimovich 2c0f9534b7 Move to C++11: convert enum VarType to enum class. 2022-06-10 21:45:31 +01:00
Ulya Trofimovich c191626dc7 Move to C++11: convert enum CodeKind to enum class. 2022-06-10 21:40:53 +01:00
Ulya Trofimovich 1d8d605c1c Move to C++11: convert enum posix_prectable_alg_t to enum class PosixPrecedenceTable. 2022-06-10 21:25:32 +01:00
Ulya Trofimovich 07dd1ce127 Move to C++11: convert enum posix_closure_t to enum class PosixClosure. 2022-06-10 21:15:15 +01:00
Ulya Trofimovich adab705372 Move to C++11: convert enum dfa_minimization_t to enum class Minimization. 2022-06-10 21:03:11 +01:00
Ulya Trofimovich 32c8bc40c7 Move to C++11: convert enum empty_class_policy_t to enum class EmptyClassPolicy. 2022-06-10 20:57:08 +01:00
Ulya Trofimovich 43efb026d2 Move to C++11: convert enum InputBlockKind to enum class InputBlock. 2022-06-10 08:16:26 +01:00
Ulya Trofimovich 2bac195bf8 Move to C++11: convert enum parse_opts_t to enum class ParseOpts. 2022-06-10 08:11:27 +01:00
Ulya Trofimovich 29711e6274 Move to C++11: convert enum fixed_tags_t to enum class FixedTags. 2022-06-10 08:05:39 +01:00
Ulya Trofimovich 8fb9f969ea Move to C++11: convert enum api_style_t to enum class ApiStyle. 2022-06-10 08:02:13 +01:00
Ulya Trofimovich fe39a5f1e7 Move to C++11: convert enum input_api_t to enum class Api. 2022-06-10 07:58:19 +01:00
Ulya Trofimovich 48352fbf23 Move to C++11: convert enum lang_t to enum class Lang. 2022-06-10 07:50:43 +01:00
Ulya Trofimovich 502aa69d13 Move to C++11: convert enum target_t to enum class Target. 2022-06-10 07:50:31 +01:00
Ulya Trofimovich 12808cb1d1 Move to C++11: use std::unique_ptr instead of a custom smart pointer. 2022-06-10 07:25:59 +01:00
Ulya Trofimovich 04b049f8c2 Move to C++11: replace NULL with nullptr.
One exception is the files generated by re2c (it uses NULL for tags).
2022-06-09 23:43:58 +01:00
Ulya Trofimovich 9c007557e1 Fix comment: fopen 'x' specifier (exclusive) is C11, but C++17. 2022-06-09 23:04:40 +01:00
Ulya Trofimovich b1b246b4a3 Move to C++11: replace custom <stdint.h> with a standard one. 2022-06-09 22:55:32 +01:00
Ulya Trofimovich d2a833a899 Autoconf, CMake: switch to C++11. 2022-06-09 22:27:17 +01:00
Ulya Trofimovich ce8501e27b Autoconf, CMake: check for python version >= 3.7.
This fixes bug #405 reported by Daniel Macks
"Insufficient version-check for python (run_tests.py failures)".

For CMake, prefer manual check to avoid raising required CMake version
to 3.19, in which find_package() learned to do version check.
2022-06-09 21:57:15 +01:00
Ulya Trofimovich 56df6e6146 Benchmarks: json2pgfplot.py: use correct font to render captions. 2022-06-09 08:19:40 +01:00
Ulya Trofimovich fa94d9c777 TDFA paper (co-authored with Angelo Borsotti). 2022-06-08 07:54:45 +01:00
Ulya Trofimovich c6bf3fc356 Benchmarks (Java): add results. 2022-05-30 22:42:12 +01:00
Ulya Trofimovich 0899f16e63 Benchmarks (DFA-JIT): update results. 2022-05-30 22:42:12 +01:00
Ulya Trofimovich a5be4db2b3 Benchmarks (DFA-AOT): update results, add helper script. 2022-05-30 22:42:12 +01:00
Ulya Trofimovich f4b4abbe7a Benchmarks: specialize json2pgfplot.py for each type of benchmark.
Changes in json2pgfplot.py:

- add mandatory argument --variant <dfa_aot | dfa_jit | nfa>
- for DFA-AOT benchmark show time and size results on the same page
- for DFA-AOT/DFA-JIT add header, drop labels on all but the 1st column
- make bars colorful
- for rows that don't fit replace three dots with a thick arrow
- automatically make DFA-JIT and NFA benchmarks relative

Also, remove some unnecessary cases from DFA JIT benchmark (they are
very similar to other cases and add little extra value).
2022-05-30 22:42:12 +01:00
Ulya Trofimovich e9ed0c8d25 Makefile.am: drop check for re2c executable in a bison rule.
The check makes no sense (parser is regenerated if there is bison, and
it is not related to re2c bootstrapping itself). The bootstrapping
process was changed in commit 967540566b,
and the check was likely left by mistake.
2022-05-30 22:42:12 +01:00
Ulya Trofimovich 0687500e8a Benchmarks: use '/usr/bin/env' instead of '/bin/env' in a script. 2022-05-30 22:42:12 +01:00
Ulya Trofimovich ea3c3ba9bc Benchmarks: update scripts that get Ragel and Kleenex.
Ragel:
  - Patch `/bin/bash` to `/usr/bin/env bash` to build Colm on NixOS.
  - Configure Colm with `--disable-manual` to avoid Asciidoc dependency.

Kleenex:
  - Use `cabal build` instead of the removed `cabal v1-sandbox`.
2022-05-30 22:42:12 +01:00
Ulya Trofimovich 058e266ece Benchmarks: regenerated re2c benchmarks with the latest re2c version. 2022-05-30 22:42:12 +01:00
Ulya Trofimovich 5cd639f341 Add MAINTAINERS.md with a list of things that should be removed first. 2022-05-30 22:41:50 +01:00
Ulya Trofimovich 34cb2e1a5a Add IDEAS.md with (as the name suggests) some ideas for the future. 2022-05-30 18:31:21 +01:00
Sergei Trofimovich 2a078d56e9 .github/workflows/benchmarks.yml: update apt indices for benchmarks as well
ci.yml already updates indices to pull in most recent packges.
Let's update benchmarks as well.
2022-03-30 13:01:28 +01:00
Sergei Trofimovich 2103838454 .github/workflows/ci.yml: always use latest apt state, not the outdated OS default 2022-03-30 10:07:43 +01:00
Sergei Trofimovich 55673eda5c .github/workflows/ci.yml: set up trivial apt cache
CI runs occasionally fail to fetch apt packages due to unavailable
remote. Let's try to cache heavyweight .deb packages and see if it
helps.

.deb files should not normally change frequently.
2022-03-30 10:07:43 +01:00
Ulya Trofimovich 814d38f7eb CMake presets: update Visual Studio version to 2022.
This fixes CI builds on windows (following the recent Github Actions
environment update).
2022-02-20 16:51:20 +00:00
Ulya Trofimovich d7d8e9d691 libre2c: multi-pass TDFA: compress identical backlinks into one.
Configurations with the same origin TNFA state also have identical
transition tags (by TDFA(1) construction those are the lookahead tags in
the origin configuration), therefore backlinks for such configurations
are identical and can be collapsed into one (provided that indices in
other backlink arrays that point into this one are suitably adjusted).
2022-02-20 16:51:20 +00:00
Ulya Trofimovich 38864aa327 libre2c: multi-pass TDFA: reduce lifetime of determinization context.
Determinization context was needed at `regexec` time previously, when
tag sequences on TDFA transitions were fetched from the tag tree. Now
that they are stored as arrays, tag tree is no longer needed and there
is no reason to keep determinization context alive after TDFA is
constructed.
2022-02-20 16:51:20 +00:00
Ulya Trofimovich 183d49137e libre2c: multi-pass TDFA: remove unused field in backlink structure. 2022-02-20 16:51:20 +00:00
Sergei Trofimovich 31c914f982 run_tests.py.in: add --verbose flag, disable successful printing by default
re2c test are so fast that text output in terminal takes comparable time
on slower terminals. Let's disable it by default. Can still be brought
back with --verbose option.
2022-02-20 12:14:03 +00:00
Ulya Trofimovich 9a143f45be C backend: do not emit comma after the last condition in enumeration.
Otherwise there is a warning when compiling in C90 mode:

    warning: commas at the end of enumerator lists are a C99-specific
             feature [-Wc99-extensions]

This fixes bug #395 "commas at the end of enumerator lists".
2022-02-04 07:28:29 +00:00
4861 changed files with 1294889 additions and 1556585 deletions
+3
View File
@@ -0,0 +1,3 @@
* text=auto
test/newlines/** -text
test/codegen/python/indentation_sensitive_crlf.re -text
+12
View File
@@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: "github-actions"
commit-message:
include: "scope"
prefix: "Actions"
directory: "/"
labels:
- "enhancement"
schedule:
interval: "weekly"
+24 -12
View File
@@ -33,18 +33,20 @@ jobs:
steps:
- name: Checkout Code
uses: actions/checkout@v2
uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/setup-python@v7
with:
python-version: '3.8'
- name: Setup Java
uses: actions/setup-java@v2
uses: actions/setup-java@v6
with:
distribution: 'adopt'
java-version: '11'
# One of the distributions that packages OpenJDK, see
# https://github.com/marketplace/actions/setup-java-jdk#supported-distributions
distribution: 'oracle-openjdk'
java-version: '26'
- name: Setup Common Prerequisites
run: |
@@ -52,6 +54,7 @@ jobs:
Linux*)
echo "CC=gcc" >> $GITHUB_ENV
echo "CXX=g++" >> $GITHUB_ENV
sudo apt update
sudo apt install libre2-dev libbenchmark-dev
;;
macOS*)
@@ -70,8 +73,17 @@ jobs:
cmake -S . -B .build \
-G "Unix Makefiles" \
-DRE2C_BUILD_LIBS=ON \
-DRE2C_BUILD_RE2D=OFF \
-DRE2C_BUILD_RE2GO=OFF \
-DRE2C_BUILD_RE2HS=OFF \
-DRE2C_BUILD_RE2JAVA=OFF \
-DRE2C_BUILD_RE2JS=OFF \
-DRE2C_BUILD_RE2OCAML=OFF \
-DRE2C_BUILD_RE2PY=OFF \
-DRE2C_BUILD_RE2RUST=OFF \
-DRE2C_BUILD_RE2SWIFT=OFF \
-DRE2C_BUILD_RE2V=OFF \
-DRE2C_BUILD_RE2ZIG=OFF \
-DRE2C_BUILD_BENCHMARKS=ON \
-DCMAKE_CXX_FLAGS="-O3"
@@ -79,20 +91,20 @@ jobs:
run: cmake --build .build
- name: Run submatch DFA AOT benchmark
working-directory: .build/benchmarks/submatch_dfa_aot
working-directory: .build/benchmarks/c
run: |
./run.py --quickverify \
&& ./run.py --repetitions 5 --output results.json \
./run.py --verify \
&& ./run.py --output results.json \
&& cat results.json
- name: Run submatch DFA JIT benchmark
working-directory: .build/benchmarks/submatch_dfa_jit
run: ./bench_submatch_dfa_jit
working-directory: .build/benchmarks/c/libre2c/jit
run: ./bench_submatch_jit
- name: Run submatch Java benchmark (ReTdfa)
working-directory: .build/benchmarks/submatch_java
working-directory: .build/benchmarks/c/libre2c/java
run: ./run.py
- name: Run submatch NFA benchmark
working-directory: .build/benchmarks/submatch_nfa
working-directory: .build/benchmarks/c/libre2c/nfa
run: ./bench_submatch_nfa
+167
View File
@@ -0,0 +1,167 @@
name: CI autotools
on:
push:
pull_request:
defaults:
run:
shell: bash
jobs:
build-and-test:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
# When set to true, GitHub cancels
# all in-progress jobs if any matrix job fails.
fail-fast: false
matrix:
include:
- name: linux-gcc-intree
os: ubuntu-latest
- name: linux-gcc-ootree
os: ubuntu-latest
# macOS
- name: macos-clang-intree
os: macos-latest
- name: macos-clang-ootree
os: macos-latest
steps:
- name: Checkout Code
uses: actions/checkout@v7
- name: Setup apt cache (Linux)
if: startsWith(runner.os, 'Linux')
uses: actions/cache@v6
with:
path: /var/cache/apt
key: ${{ runner.os }}-apt-cache-${{ matrix.os }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-apt-cache-${{ matrix.os }}-
${{ runner.os }}-apt-cache-
- name: Setup Common Prerequisites
run: |
case ${{ runner.os }} in
Linux*)
sudo apt update
sudo apt install autoconf automake libtool bison
;;
macOS*)
sudo xcode-select -switch /Applications/Xcode.app
echo "SDKROOT=$(xcodebuild -version -sdk macosx Path)" >> $GITHUB_ENV
echo "$(xcodebuild -version -sdk macosx Path)" >> $GITHUB_PATH
brew install autoconf automake libtool bison coreutils
# bison is not activated by default to avoid clobbering
# already present outdated system bison. Let's prepend
# brew's path.
echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH
;;
esac
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: 3.x
architecture: x64
- name: Install Python Dependencies
run: |
python -m pip install --upgrade pip
python -m pip install docutils pygments
- name: Generate ./configure
run: ./autogen.sh
- name: Fast Configure
run: |
./configure \
--disable-dlang \
--disable-golang \
--disable-haskell \
--disable-java \
--disable-js \
--disable-ocaml \
--disable-python \
--disable-rust \
--disable-swift \
--disable-vlang \
--disable-zig \
--prefix=$PWD/install
- name: Fast Build
run: make -j$(nproc)
- name: Fast Install
run: make -j$(nproc) install
- name: Fast Clean
run: make -j$(nproc) distclean
- name: Minimal Install Test
working-directory: ./install/bin
run: ./re2c --version
- name: Get build dir
id: build-info
run: |
if echo "${{ matrix.name }}" | grep -q "ootree"; then
BUILD_DIR="$(pwd)/.build/${{ matrix.name }}-full"
mkdir -p "$BUILD_DIR"
else
BUILD_DIR="$(pwd)"
fi
echo "BUILD_DIR=$BUILD_DIR" >> $GITHUB_OUTPUT
- name: Full Configure
working-directory: ${{ steps.build-info.outputs.BUILD_DIR }}
run: |
$GITHUB_WORKSPACE/configure \
--prefix=$PWD/full-install \
--enable-libs \
--enable-parsers \
--enable-lexers \
--enable-docs \
--enable-debug \
RE2C_FOR_BUILD=$GITHUB_WORKSPACE/install/bin/re2c
- name: Full Build
working-directory: ${{ steps.build-info.outputs.BUILD_DIR }}
run: |
find $GITHUB_WORKSPACE/src -name '*.re' | xargs touch
make -j$(nproc)
- name: Run Main Test Suite
working-directory: ${{ steps.build-info.outputs.BUILD_DIR }}
run: bash -c "ulimit -s 256; make check -j$(nproc)"
- name: Run Skeleton Tests
working-directory: ${{ steps.build-info.outputs.BUILD_DIR }}
run: python run_tests.py --skeleton
- name: Full Install
working-directory: ${{ steps.build-info.outputs.BUILD_DIR }}
run: make -j$(nproc) install
- name: Archive test artifacts
# Run this step only if tests failed (otherwise there is nothing to upload).
if: failure()
uses: actions/upload-artifact@v7
with:
# To ensure that jobs don't overwrite existing artifacts,
# use a different name per job.
name: test-${{ matrix.name }}
# Tests run in a temporary directory that has a name test_<timestamp>.
path: ${{ steps.build-info.outputs.BUILD_DIR }}/test_[0-9]*
# Artifacts are retained for 90 days by default.
# In fact, we don't need such long period.
retention-days: 30
+181
View File
@@ -0,0 +1,181 @@
name: CI CMake
on:
push:
pull_request:
defaults:
run:
shell: bash
jobs:
build-and-test:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
# When set to true, GitHub cancels
# all in-progress jobs if any matrix job fails.
fail-fast: false
matrix:
include:
# Linux
- name: linux-gcc-ubsan-ootree
os: ubuntu-latest
- name: linux-gcc-asan-ootree
os: ubuntu-latest
- name: linux-gcc-valgrind-ootree
os: ubuntu-latest
- name: linux-gcc-debug-ootree-skeleton
os: ubuntu-latest
- name: linux-gcc-debug-intree-m32-skeleton
os: ubuntu-latest
- name: linux-gcc-release-ootree-skeleton
os: ubuntu-latest
# macOS
- name: macos-clang-debug-ootree-skeleton
os: macos-latest
- name: macos-clang-debug-intree-skeleton
os: macos-latest
- name: macos-clang-release-ootree-skeleton
os: macos-latest
# Windows
- name: windows-msvc-debug-ootree
os: windows-latest
- name: windows-msvc-debug-intree
os: windows-latest
- name: windows-msvc-release-ootree
os: windows-latest
steps:
- name: Checkout Code
uses: actions/checkout@v7
- name: Setup chocolatey Cache (Windows)
if: startsWith(runner.os, 'Windows')
uses: actions/cache@v6
with:
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
key: ${{ runner.os }}-chocolatey-${{ matrix.os }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-chocolatey-${{ matrix.os }}-
${{ runner.os }}-chocolatey-
- name: Setup apt cache (Linux)
if: startsWith(runner.os, 'Linux')
uses: actions/cache@v6
with:
path: /var/cache/apt
key: ${{ runner.os }}-apt-cache-${{ matrix.os }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-apt-cache-${{ matrix.os }}-
${{ runner.os }}-apt-cache-
- name: Setup Common Prerequisites
run: |
case ${{ runner.os }} in
Linux*)
sudo apt update
sudo apt install gcc-multilib g++-multilib # for -m32
sudo apt install valgrind
;;
macOS*)
sudo xcode-select -switch /Applications/Xcode.app
echo "SDKROOT=$(xcodebuild -version -sdk macosx Path)" >> $GITHUB_ENV
echo "$(xcodebuild -version -sdk macosx Path)" >> $GITHUB_PATH
brew install coreutils # for `nproc`
;;
Windows*)
choco install --no-progress -y winflexbison3
choco install gnuwin32-coreutils.install # for `nproc`
;;
esac
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: 3.x
architecture: x64
- name: Install Python Dependencies
run: |
python -m pip install --upgrade pip
python -m pip install docutils pygments
- name: Check Available Configure Presets
run: cmake --list-presets
- name: Fast Configure
run: cmake --preset=${{ matrix.name }}-fast -DPython3_ROOT_DIR="${{ env.pythonLocation }}"
- name: Fast Build
run: cmake --build --preset=${{ matrix.name }}-fast -j$(nproc)
- name: Install
run: cmake --build --preset=${{ matrix.name }}-fast --target install
- name: Minimal Install Test
working-directory: ./install/bin
run: ./re2c --version
- name: Get build dir
id: build-info
run: |
if echo "${{ matrix.name }}" | grep -q "ootree"; then
BUILD_DIR="${{ github.workspace }}/.build/${{ matrix.name }}-full"
else
BUILD_DIR="${{ github.workspace }}"
fi
echo "BUILD_DIR=$BUILD_DIR" >> $GITHUB_OUTPUT
- name: Full Configure
run: cmake --preset=${{ matrix.name }}-full -DPython3_ROOT_DIR="${{ env.pythonLocation }}"
- name: Full Build
run: |
find src -name '*.re' | xargs touch
cmake --build --preset=${{ matrix.name }}-full -j$(nproc)
- name: Run Main Test Suite
run: bash -c "ulimit -s 256; cmake --build --preset=${{ matrix.name }}-full --target tests -j$(nproc)"
- name: Run Skeleton Tests
if: "contains(matrix.name, 'skeleton')"
working-directory: ${{ steps.build-info.outputs.BUILD_DIR }}
run: python run_tests.py --skeleton
- name: Run Valgrind Tests
if: "contains(matrix.name, 'valgrind')"
working-directory: ${{ steps.build-info.outputs.BUILD_DIR }}
run: python run_tests.py --valgrind
- name: Archive test artifacts
# Run this step only if tests failed (otherwise there is nothing to upload).
if: failure()
uses: actions/upload-artifact@v7
with:
# To ensure that jobs don't overwrite existing artifacts,
# use a different name per job.
name: test-${{ matrix.name }}
# Tests run in a temporary directory that has a name test_<timestamp>.
# Provide both relative and absolute paths. Absolute path should work for all builds,
# but it doesn't work on Windows. Relative path works for in-tree Windows builds.
path: |
test_[0-9]*
${{ steps.build-info.outputs.BUILD_DIR }}/test_[0-9]*
# Artifacts are retained for 90 days by default.
# In fact, we don't need such long period.
retention-days: 30
-159
View File
@@ -1,159 +0,0 @@
name: CI
on:
push:
pull_request:
defaults:
run:
shell: bash
jobs:
build-and-test:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
# When set to true, GitHub cancels
# all in-progress jobs if any matrix job fails.
fail-fast: false
matrix:
include:
# Linux
- name: linux-gcc-ubsan-ootree
os: ubuntu-latest
- name: linux-gcc-asan-ootree
os: ubuntu-latest
- name: linux-gcc-debug-ootree-skeleton
os: ubuntu-latest
- name: linux-gcc-debug-intree-m32-skeleton
os: ubuntu-latest
- name: linux-gcc-release-ootree-skeleton
os: ubuntu-latest
# macOS
- name: macos-clang-debug-ootree-skeleton
os: macos-latest
- name: macos-clang-debug-intree-skeleton
os: macos-latest
- name: macos-clang-release-ootree-skeleton
os: macos-latest
# Windows
- name: windows-msvc-debug-ootree
os: windows-latest
- name: windows-msvc-debug-intree
os: windows-latest
- name: windows-msvc-release-ootree
os: windows-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Setup chocolatey Cache (Windows)
if: startsWith(runner.os, 'Windows')
uses: actions/cache@v2
with:
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
key: ${{ runner.os }}-chocolatey-${{ matrix.os }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-chocolatey-${{ matrix.os }}-
${{ runner.os }}-chocolatey-
- name: Setup Common Prerequisites
run: |
case ${{ runner.os }} in
Linux*)
sudo apt install gcc-multilib g++-multilib # for -m32
;;
macOS*)
sudo xcode-select -switch /Applications/Xcode.app
echo "SDKROOT=$(xcodebuild -version -sdk macosx Path)" >> $GITHUB_ENV
echo "$(xcodebuild -version -sdk macosx Path)" >> $GITHUB_PATH
;;
Windows*)
choco install --no-progress -y winflexbison3
;;
esac
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
architecture: x64
- name: Install Python Dependencies
# Disabled until this https://github.com/skvadrik/re2c/issues/327
# will be implemented
if: startsWith(runner.os, 'Windows') == false
run: |
python -m pip install --upgrade pip
python -m pip install docutils pygments
- name: Check Available Configure Presets
run: cmake --list-presets
- name: Fast Configure
run: cmake --preset=${{ matrix.name }}-fast
- name: Fast Build
run: cmake --build --preset=${{ matrix.name }}-fast
- name: Install
run: cmake --build --preset=${{ matrix.name }}-fast --target install
- name: Minimal Install Test
working-directory: ./install/bin
run: ./re2c --version
- name: Full Configure
run: cmake --preset=${{ matrix.name }}-full
- name: Get build dir
id: build-info
run: |
if echo "${{ matrix.name }}" | grep -q "ootree"; then
BUILD_DIR="$(pwd)/.build/${{ matrix.name }}-full"
else
BUILD_DIR="$(pwd)"
fi
echo "::set-output name=BUILD_DIR::$BUILD_DIR"
- name: Full Build
run: |
find src -name '*.re' | xargs touch
cmake --build --preset=${{ matrix.name }}-full
- name: Run Main Test Suite
run: cmake --build --preset=${{ matrix.name }}-full --target tests
- name: Run Skeleton Tests
if: "contains(matrix.name, 'skeleton')"
# Remove the following line after fix Windows tests
working-directory: ${{ steps.build-info.outputs.BUILD_DIR }}
run: python run_tests.py --skeleton
- name: Archive test artifacts
# Run this step only if tests failed (otherwise there is nothing to upload).
if: failure()
uses: actions/upload-artifact@v2
with:
# To ensure that jobs don't overwrite existing artifacts,
# use a different name per job.
name: test-${{ matrix.name }}
# Tests run in a temporary directory that has a name test_<timestamp>.
path: ${{ steps.build-info.outputs.BUILD_DIR }}/test_[0-9]*
# Artifacts are retained for 90 days by default.
# In fact, we don't need such long period.
retention-days: 30
+1
View File
@@ -11,6 +11,7 @@
/m4
/test_*
/.build*
/bazel-*
# Ignore user defined CMake presets
CMakeUserPresets.json
+2 -2
View File
@@ -1,3 +1,3 @@
[submodule "benchmarks/submatch_java/REgen"]
path = benchmarks/submatch_java/REgen
[submodule "benchmarks/c/libre2c/java/REgen"]
path = benchmarks/c/libre2c/java/REgen
url = https://github.com/skvadrik/REgen.git
+46
View File
@@ -0,0 +1,46 @@
package(default_visibility = ["//visibility:private"])
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
genrule(
name = "re2c_config",
srcs = [
"CMakeLists.txt",
"//bazel:re2c_config.h",
],
outs = ["config.h"],
cmd = """
cat $(location //:CMakeLists.txt) |\\
sed -rne 's/project\\(re2c VERSION ([^ ]+).*/#define PACKAGE_VERSION "\\1-bootstrap"/p' >> "$@"
cat $(location //bazel:re2c_config.h) >> "$@"
""",
)
cc_library(
name = "re2c_config_cc",
hdrs = ["config.h"],
defines = ["""RE2C_STDLIB_DIR='"$(BINDIR)/re2c.runfiles/re2c/include"'"""],
data = ["include/unicode_categories.re"],
)
cc_library(
name = "re2c_bootstrap_cc",
includes = ["bootstrap"],
hdrs = glob([
"bootstrap/src/**/*.h",
"src/**/*.h",
]),
srcs = glob([
"bootstrap/src/**/*.cc",
"src/**/*.cc",
], exclude = ["src/test/**/*.cc"]),
deps = [
"re2c_config_cc", # Needed for 're2c_config_cc' data files
],
)
cc_binary(
name = "re2c",
srcs = ["src/main.cc"],
deps = [":re2c_bootstrap_cc"],
visibility = ["//visibility:public"],
)
+129 -20
View File
@@ -1,18 +1,24 @@
How to build
============
Build & install
===============
If you want to install re2c from a prebuilt package, skip to the bottom of the
page for a list of all packages available on different systems. Below is a guide
how to build re2c from source code.
Dependencies
------------
To build re2c from a release tarball one needs only a C++ compiler and
optionally Python 3 to run the tests.
To build re2c from a release tarball one needs only a C++ compiler (supporting
at least C++11) and Python 3 for build-time scripts and for testing. Building on
Windows additionally requires either CMake or a Mingw build environment.
To develop re2c one also needs CMake or Autotools (both build systems are
maintained). Other dependencies include Bison (to rebuild parsers), rst2man (to
rebuild documentation) and Sphinx (to rebuild the website). Benchmarks also use
google-benchmark, re2 and Java. A few helper scripts are written in Haskell, but
they are not essential for re2c development.
maintained). Other dependencies include Bison (to rebuild parsers), Python 3
Docutils (to rebuild documentation) and Sphinx (to rebuild the website).
Benchmarks also use Google-benchmark, re2 and Java. A few helper scripts are
written in Haskell, but they are not essential for re2c development.
re2c is a self-hosting lexer generator, meaning that parts of its source code
are written in re2c (namely, all the source files that have a *.re* extension).
@@ -33,7 +39,8 @@ An in-tree build (objects are generated side by side with sources):
```
$ ./configure && make && make install
```
An out-of-tree build (objects are generated in a separate directory):
An out-of-tree build (objects are generated in a separate directory
named `.build`):
```
$ mkdir .build && cd .build && ../configure && make && make install
```
@@ -44,22 +51,57 @@ The configure script has many options (to see them all, run
* `--enable-debug`
Enable debug checks in the re2c source code. Also enables debug options.
* `--enable-dlang`
Build re2d (identical to `re2c --lang d`). This is on by default.
* `--enable-golang`
Build re2go (identical to `re2c --lang go`). This is on by default.
* `--enable-haskell`
Build re2hs (identical to `re2c --lang haskell`). This is on by default.
* `--enable-java`
Build re2java (identical to `re2c --lang java`). This is on by default.
* `--enable-js`
Build re2js (identical to `re2c --lang js`). This is on by default.
* `--enable-ocaml`
Build re2ocaml (identical to `re2c --lang ocaml`). This is on by default.
* `--enable-python`
Build re2py (identical to `re2c --lang python`). This is on by default.
* `--enable-rust`
Build re2rust (identical to `re2c --lang rust`). This is on by default.
* `--enable-swift`
Build re2swift (identical to `re2c --lang swift`). This is on by default.
* `--enable-vlang`
Build re2v (identical to `re2c --lang v`). This is on by default.
* `--enable-zig`
Build re2zig (identical to `re2c --lang zig`). This is on by default.
* `--enable-lexers`
Enable regeneration of *.re* files (as opposed to using bootstrap files).
This requires setting `RE2C_FOR_BUILD` to an existing re2c executable
path.
Enable regeneration of lexers from *.re* files (as opposed to using
pre-generated bootstrap files). This requires setting `RE2C_FOR_BUILD` to
an existing re2c executable path.
* `--enable-parsers`
Enable regeneration of parsers from *.ypp* files with bison (as opposed to
using pre-generated bootstrap files).
* `--enable-syntax`
Enable regeneration of default syntax files from the ones provided in
include/ directory (as opposed to using pre-generated bootstrap files).
* `--enable-docs`
Enable regeneration of documentation (requires rst2man).
Enable regeneration of documentation (requires Python 3 Docutils).
* `--enable-benchmarks`
Build benchmarks (requires google benchmarks library).
Build benchmarks (requires Google benchmarks library).
* `--enable-benchmarks-regenerate`
Regenerate C code for Ragel and Kleenex benchmarks (this will download and
@@ -84,6 +126,24 @@ GLIBCXX_DEBUG, etc. in the ``build`` subdirectory.
Build (CMake)
-------------
re2c includes CMake presets for Linux, MacOS, and Windows. Use `cmake
--list-presets` to see them.
* The `-fast` presets have minimal dependencies and build re2c using
pre-generated manpages, lexers, and parsers.
* The `-full` presets have additional prerequisites (Docutils, Bison, and a
pre-existing re2c binary) and re-generate the manpages, lexers, and parsers.
If you just want to build re2c, use the `-release-ootree-fast` preset. The
other presets are primarily of interest to developers.
For example, to build the `windows-msvc-release-ootree-fast` preset:
* CD to the root of the re2c folder (the folder containing this README).
* Configure: `cmake --preset=windows-msvc-release-ootree-fast`
* Build: `cmake --build --preset=windows-msvc-release-ootree-fast`
* The binary will be in the `.build/<preset-name>` folder.
CMake supports different build modes, which can be further customized with
individual options. By default re2c builds with `-O2 -g` and does not set any
particular mode to allow the user complete freedom in overriding the build
@@ -117,7 +177,8 @@ The following modes are supported:
the code with Undefined Behavior Sanitizer to check for undefined behavior
errors.
A simple build (objects are generated in a separate build directory):
A simple build (objects are generated in a separate build directory named
`.build`):
```
$ mkdir .build && cd .build && cmake .. && cmake --build .
```
@@ -125,23 +186,63 @@ A simple build (objects are generated in a separate build directory):
CMake supports a lot of configuration options. Here is the list of options
specific to re2c:
* `-DRE2C_BUILD_RE2D=yes`
Build re2d executable (an alias to `re2c --lang d`). Enabled by default.
* `-DRE2C_BUILD_RE2GO=yes`
Build re2go executable (an alias to `re2c --lang go`). Enabled by default.
* `-DRE2C_BUILD_RE2HS=yes`
Build re2hs executable (an alias to `re2c --lang haskell`). Enabled by
default.
* `-DRE2C_BUILD_RE2JAVA=yes`
Build re2java executable (an alias to `re2c --lang java`). Enabled by
default.
* `-DRE2C_BUILD_RE2JS=yes`
Build re2js executable (an alias to `re2c --lang js`). Enabled by default.
* `-DRE2C_BUILD_RE2OCAML=yes`
Build re2ocaml executable (an alias to `re2c --lang ocaml`). Enabled by
default.
* `-DRE2C_BUILD_RE2PY=yes`
Build re2py executable (an alias to `re2c --lang python`). Enabled by
default.
* `-DRE2C_BUILD_RE2RUST=yes`
Build re2rust executable (an alias to `re2c --lang rust`). Enabled by
default.
* `-DRE2C_BUILD_RE2SWIFT=yes`
Build re2swift executable (an alias to `re2c --lang swift`). Enabled by
default.
* `-DRE2C_BUILD_RE2V=yes`
Build re2v executable (an alias to `re2c --lang v`). Enabled by default.
* `-DRE2C_BUILD_RE2ZIG=yes`
Build re2zig executable (an alias to `re2c --lang zig`). Enabled by default.
* `-DRE2C_REBUILD_LEXERS=yes`
Enable regeneration of *.re* files (as opposed to using bootstrap files).
This requires setting `-DRE2C_FOR_BUILD` to an existing re2c executable
path.
Enable regeneration of lexers from *.re* files (as opposed to using
pre-generated bootstrap files). This requires setting `-DRE2C_FOR_BUILD` to
an existing re2c executable path.
* `-DRE2C_REBUILD_PARSERS=yes`
Enable regeneration of parsers from *.ypp* files with bison (as opposed to
using pre-generated bootstrap files).
* `-DRE2C_REBUILD_SYNTAX=yes`
Enable regeneration of default syntax files from the ones provided in
include/ directory (as opposed to using pre-generated bootstrap files).
* `-DRE2C_REBUILD_DOCS=yes`
Enable regeneration of documentation (requires rst2man).
Enable regeneration of documentation (requires Python 3 Docutils).
* `-DRE2C_BUILD_BENCHMARKS=yes`
Build benchmarks (requires google benchmarks library).
Build benchmarks (requires Google benchmarks library).
* `-DRE2C_REGEN_BENCHMARKS=yes`
Regenerate C code for Ragel and Kleenex benchmarks (this will download and
@@ -197,3 +298,11 @@ fuzz-testing Haskell scripts in the *fuzz* subdirectory; they are based on the
QuickCheck library and can be easily modified to fuzz-test various aspects of
re2c by comparing current re2c version against older versions or against other
regular expression libraries.
Packages
--------
[Repology](https://repology.org/project/re2c/versions)
has a list of re2c packages for different systems:
![re2c](https://repology.org/badge/vertical-allrepos/re2c.svg)
+507 -59
View File
@@ -2,9 +2,512 @@ Changelog
=========
----
3.0x
----
4.6 (2026-08-29)
~~~~~~~~~~~~~~~~
- Added support for Zig labeled continue optimization.
(`#580 <https://github.com/skvadrik/re2c/pull/580>`_).
- Updated C/C++ examples to use re2c features available in version 4.0 or higher.
4.5.1 (2026-03-27)
~~~~~~~~~~~~~~~~~~
- Added missing include files to the distribution
(`#573 <https://github.com/skvadrik/re2c/issues/573>`_).
- Updated the documentation to mention the new include files.
4.5 (2026-03-23)
~~~~~~~~~~~~~~~~
- Migrated include files to Unicode 17.0.0 standard.
- Added Unicode include files:
+ `include/unicode_blocks.re <https://github.com/skvadrik/re2c/blob/master/include/unicode_blocks.re>`_
+ `include/unicode_properties.re <https://github.com/skvadrik/re2c/blob/master/include/unicode_properties.re>`_
- Implemented Unicode case mapping for case-insensitive string literals
(`#235 <https://github.com/skvadrik/re2c/issues/235>`_).
- Fixed `#571 <https://github.com/skvadrik/re2c/issues/571>`_
(segmentation fault on erroneous input during determinization).
- Updated paper `A closer look at TDFA <https://arxiv.org/abs/2206.01398>`_
(applied corrections by Lisa Felidae).
4.4 (2025-12-20)
~~~~~~~~~~~~~~~~
- Added generalized end-of-input symbol ``$``
(`#525 <https://github.com/skvadrik/re2c/issues/525>`_).
This change may break old code with conflicitng end-of-input rules,
as they now have position-based precedence. The broken cases were
reported with ``-Wdeprecated-eof-rule`` since version 4.3.
4.3.1 (2025-12-01)
~~~~~~~~~~~~~~~~~~
- Fixed bugs:
+ `#560 <https://github.com/skvadrik/re2c/issues/560>`_
(allow conditions that have no rules except for default rule)
+ `#561 <https://github.com/skvadrik/re2c/issues/561>`_
(use unsigned character type in C/C++ examples)
+ `#564 <https://github.com/skvadrik/re2c/issues/564>`_
(fix broken end of input rule $ with captures)
4.3 (2025-06-30)
~~~~~~~~~~~~~~~~
- Added warning ``-Wdeprecated-eof-rule``, this will be turned to error in the
future (`#525 <https://github.com/skvadrik/re2c/issues/525>`_).
- Improved re2c performance (made determinization faster,
`#544 <https://github.com/skvadrik/re2c/discussions/544>`_).
4.2 (2025-04-23)
~~~~~~~~~~~~~~~~
- Added Swift backend
(`#506 <https://github.com/skvadrik/re2c/issues/506>`_).
- Added options:
+ ``--lang swift``
+ ``--computed-gotos-relative``
- Added configurations:
+ ``re2c:cgoto:relative``, ``re2c:computed-gotos:relative``
+ ``re2c:yyfn:throw``
- Added syntax file code templates:
+ ``code:cgoto``
+ ``code:cgoto_data``
+ ``code:yytarget_filter``
+ ``code:type_yyctable``
- Added syntax file conditionals:
+ ``.cgoto.relative``
+ ``.yyfn.throw``
- Added some C++ benchmarks without submatch extraction.
4.1 (2025-02-16)
~~~~~~~~~~~~~~~~
- Added new syntax for actions
(`#521 <https://github.com/skvadrik/re2c/issues/521>`_).
- Added entry, pre-rule and post-rule actions
(`#521 <https://github.com/skvadrik/re2c/issues/521>`_):
+ ``!entry`` action binds code at the start of the current finite state machine
+ ``!pre_rule`` action prepernds code to semantic actions of all rules in the
current block or condiiton.
+ ``!post_rule`` action appernds code to semantic actions of all rules in the
current block or condiiton.
- Added syntax file option ``special_escapes`` that describes allowed escape
sequences (`#516 <https://github.com/skvadrik/re2c/issues/516>`_).
- Fixed bugs:
+ `#518 <https://github.com/skvadrik/re2c/issues/518>`_
(allow using lookahead operator with captures).
+ `#519 <https://github.com/skvadrik/re2c/issues/519>`_
(integer overflow caused a very long loop when generating tag names).
+ `#522 <https://github.com/skvadrik/re2c/issues/522>`_
(segfault on ``!use`` directive in a block with conditions).
+ `#523 <https://github.com/skvadrik/re2c/issues/523>`_
(regression with bit-vector optimization).
+ `#529 <https://github.com/skvadrik/re2c/issues/529>`_
(failure to recognize escaped double quotes in character literals).
- OCaml backend now uses ``unsafe_get`` instead of ``get`` as the default ``YYPEEK``
implementation.
- Zig backend now uses ``const`` for ``yych`` declaration in
``--recursive-functions`` mode.
- Benchmarks (C/C++):
+ Reimplemented benchmarks using google-benchmark library.
+ Added simple variants without buffer refill.
+ Removed Kleenex benchmarks.
+ Removed deprecated TDFA(0) and StaDFA algorithms.
+ Updated benchmark results.
- Build system:
+ Migrated to Bazel 8 using bzlmod.
4.0.2 (2024-12-11)
~~~~~~~~~~~~~~~~~~
- CMake build system: fixed bug
`#515 <https://github.com/skvadrik/re2c/issues/515>`_ where language-specific
binaries erroneously defaulted to generating code for C.
- Playground: address bar now reflects navigation between examples, editors use
a more high-contrast CSS theme.
4.0.1 (2024-11-25)
~~~~~~~~~~~~~~~~~~
- Added missing doc sources to the distribution tarball
(`#503 <https://github.com/skvadrik/re2c/issues/503>`_)
- Reworked C/C++ examples to avoid using new configuration aliases until the
world has updated to re2c 4.0, made them compatible with C.
- A few build system changes: increased CMake minimum required version to 3.15,
added missing dependencies on doc sources in Makefile.am.
- Fixed typos in docs.
4.0 (2024-11-19)
~~~~~~~~~~~~~~~~
- Added a generic technique for describing language backends based on the idea
of syntax files (`#450 <https://github.com/skvadrik/re2c/issues/450>`_).
- Added support for new languages: D, Haskell, Java, JavaScript, OCaml, Python,
V, Zig.
- Added new record API for all languages (enabled with ``--api record``,
``re2c:api = record``) and made it the default API for Haskell and OCaml.
- Renamed former "default API" to "simple API", implemented it for all backends
except Haskell and OCaml, and enabled by default API for C, D, Java,
JavaScript, Python, V and Zig.
- Added new code generation model - recursive functions (enabled with
``--recursive-functions``), primarily to be used for functional languages.
- Added options:
+ ``--syntax <file>``
+ ``--api simple``
+ ``--api generic``
+ ``--api record``
+ ``--goto-label``
+ ``--recursive-functions``
+ ``--lang none``
+ ``--lang d``
+ ``--lang haskell``
+ ``--lang java``
+ ``--lang js``
+ ``--lang ocaml``
+ ``--lang python``
+ ``--lang v``
+ ``--lang zig``
+ ``--leftmost-captvars``
+ ``--posix-captvars``
+ ``--captvars`` (alias for ``--leftmost-captvars``)
+ ``--captures`` (alias for ``--leftmost-captures``)
- Added configurations:
+ ``re2c:api = simple`` (alias for ``re2c:api = default``)
+ ``re2c:api = generic`` (alias for ``re2c:api = custom``)
+ ``re2c:api = record``
+ ``re2c:computed-gotos`` (alias for ``re2c:cgoto``)
+ ``re2c:cond:abort``
+ ``re2c:tags:negative``
+ ``re2c:leftmost-captvars``
+ ``re2c:posix-captvars``
+ ``re2c:captvars`` (alias for ``re2c:leftmost-captvars``)
+ ``re2c:captures`` (alias for ``re2c:leftmost-captures``)
+ ``re2c:monadic``
+ ``re2c:fn:sep``
+ ``re2c:[define:]YYFN``
+ ``re2c:[define:]YYINPUT``
+ ``re2c:[define:]YYGETACCEPT``
+ ``re2c:[define:]YYSETACCEPT``
+ ``re2c:[define:]YYCOPYSTAG``
+ ``re2c:[define:]YYCOPYMTAG``
+ ``re2c:[define:]YYGETCOND`` (alias for ``re2c:[define:]YYGETCONDITION``)
+ ``re2c:[define:]YYSETCOND`` (alias for ``re2c:[define:]YYSETCONDITION``)
+ ``re2c:[variable:]yyfill``
+ ``re2c:[variable:]yynmatch``
+ ``re2c:[variable:]yypmatch``
+ ``re2c:[variable:]yych:literals``
- All configurations that have ``define:`` or ``variable:`` part in their name
now have an alias without this part.
- Added new block types:
+ ``/*!svars:re2c ... */``
+ ``/*!mvars:re2c ... */``
- Flex-style opening/closing braces ``%{`` and ``%}`` for block start/end
markers now work for all block types.
- Added syntax file feature lists:
+ ``supported_apis`` with values from the list:
``simple``, ``generic``, ``record``
+ ``supported_api_styles`` with values from the list:
``free-form``, ``functions``
+ ``supported_code_models`` with values from the list:
``goto-label``, ``loop-switch``, ``recursive-functions``
+ ``supported_targets`` with values from the list:
``code``, ``dot``, ``skeleton``
+ ``supported_features`` with values from the list:
``nested-ifs``, ``bitmaps``, ``computed-gotos``, ``case-ranges``,
``tags``, ``captures``, ``captvars``, ``monadic``, ``unsafe``
- Added syntax file language-specific options:
+ ``semicolons``
+ ``backtick_quoted_strings``
+ ``single_quoted_strings``
+ ``indentation_sensitive``
+ ``wrap_blocks_in_braces``
- Added syntax file code templates:
+ ``code:var_local``
+ ``code:var_global``
+ ``code:const_local``
+ ``code:const_global``
+ ``code:array_local``
+ ``code:array_global``
+ ``code:array_elem``
+ ``code:enum``
+ ``code:enum_elem``
+ ``code:assign``
+ ``code:type_int``
+ ``code:type_uint``
+ ``code:type_cond_enum``
+ ``code:type_yybm``
+ ``code:type_yytarget``
+ ``code:cmp_eq``
+ ``code:cmp_ne``
+ ``code:cmp_lt``
+ ``code:cmp_gt``
+ ``code:cmp_le``
+ ``code:cmp_ge``
+ ``code:if_then_else``
+ ``code:if_then_else_oneline``
+ ``code:switch``
+ ``code:switch_cases``
+ ``code:switch_cases_oneline``
+ ``code:switch_case_range``
+ ``code:switch_case_default``
+ ``code:loop``
+ ``code:continue``
+ ``code:goto``
+ ``code:fndecl``
+ ``code:fndef``
+ ``code:fncall``
+ ``code:tailcall``
+ ``code:recursive_functions``
+ ``code:fingerprint``
+ ``code:line_info``
+ ``code:abort``
+ ``code:yydebug``
+ ``code:yypeek``
+ ``code:yyskip``
+ ``code:yybackup``
+ ``code:yybackupctx``
+ ``code:yyskip_yypeek``
+ ``code:yypeek_yyskip``
+ ``code:yyskip_yybackup``
+ ``code:yybackup_yyskip``
+ ``code:yybackup_yypeek``
+ ``code:yyskip_yybackup_yypeek``
+ ``code:yybackup_yypeek_yyskip``
+ ``code:yyrestore``
+ ``code:yyrestorectx``
+ ``code:yyrestoretag``
+ ``code:yyshift``
+ ``code:yyshiftstag``
+ ``code:yyshiftmtag``
+ ``code:yystagp``
+ ``code:yymtagp``
+ ``code:yystagn``
+ ``code:yymtagn``
+ ``code:yycopystag``
+ ``code:yycopymtag``
+ ``code:yygetaccept``
+ ``code:yysetaccept``
+ ``code:yygetcond``
+ ``code:yysetcond``
+ ``code:yygetstate``
+ ``code:yysetstate``
+ ``code:yylessthan``
+ ``code:yybm_filter``
+ ``code:yybm_match``
- Added global variables in syntax files:
+ ``nl``
+ ``indent``
+ ``dedent``
+ ``topindent``
- Added global conditionals in syntax files:
+ ``.api.simple``
+ ``.api.generic``
+ ``.api.record``
+ ``.api_style.functions``
+ ``.api_style.freeform``
+ ``.case_ranges``
+ ``.code_model.goto_label``
+ ``.code_model.loop_switch``
+ ``.code_model.recursive_functions``
+ ``.date``
+ ``.loop_label``
+ ``.monadic``
+ ``.start_conditions``
+ ``.storable_state``
+ ``.unsafe``
+ ``.version``
- Added warning ``-Wundefined-syntax-config``.
- Warnings that indicate serious issues are now turned on by default
(and can be disabled with ``-Wno-<warning>`` options.
- Added configure options:
+ ``--enable-syntax`` (Autoconf)
+ ``RE2C_REBUILD_SYNTAX`` (CMake)
- Dropped support for function-like API style for Rust.
(it was hard to use, if at all possible)
- Added online playground that allows one to run re2c in a web browser:
https://re2c.org/playground.
- Infra work on Github Actions CI.
3.1 (2023-07-19)
~~~~~~~~~~~~~~~~
- Added capturing groups with leftmost greedy semantics:
+ Enabled with ``--leftmost-captures`` option or ``re2c:leftmost_captures``
configuration
(`55de79d8 <https://github.com/skvadrik/re2c/commit/55de79d8>`_,
`3a98b543 <https://github.com/skvadrik/re2c/commit/3a98b543>`_).
- Added non-capturing groups:
+ Added new syntax ``(! ...)`` for non-capturing groups
(`1edd25d3 <https://github.com/skvadrik/re2c/commit/1edd25d3>`_,
`b813c9b4 <https://github.com/skvadrik/re2c/commit/b813c9b4>`_,
`338806b9 <https://github.com/skvadrik/re2c/commit/338806b9>`_).
+ Added the ability to flip defaults: make ``(...)`` capturing and ``(! ...)``
non-capturing with ``--invert-captures`` option or ``re2c:invert_captures``
configuration
(`20030ff1 <https://github.com/skvadrik/re2c/commit/20030ff1>`_,
`ce756195 <https://github.com/skvadrik/re2c/commit/ce756195>`_).
- Regenerated Unicode include header to support a newer standard
(`e3ec2597 <https://github.com/skvadrik/re2c/commit/e3ec2597>`_).
- Published TDFA paper: https://arxiv.org/abs/2206.01398, co-authored with
Angelo Borsotti
(`fa94d9c7 <https://github.com/skvadrik/re2c/commit/fa94d9c7>`_).
- Removed experimental algorithms that are superseded by TDFA(1) and
generally less efficient:
+ Removed staDFA algorithm and deprecated ``--stadfa`` option
(`ac5c06cc <https://github.com/skvadrik/re2c/commit/ac5c06cc>`_).
+ Removed TDFA(0) algorithm and deprecated ``--no-lookahead`` option
(`dc8f264a <https://github.com/skvadrik/re2c/commit/dc8f264a>`_).
+ (libre2c) Removed backward-matching algorithm
(`27256be1 <https://github.com/skvadrik/re2c/commit/27256be1>`_).
+ (libre2c) Removed Kuklewicz POSIX disambiguation algorithm
(`aa97b014 <https://github.com/skvadrik/re2c/commit/aa97b014>`_).
+ (libre2c) Removed GTOP shortest path finding algorithm
(`511a030c <https://github.com/skvadrik/re2c/commit/511a030c>`_).
- Bug fixes:
+ Fixed parsing of raw UTF-8 characters in Flex compatibility mode
(`d87f86ed <https://github.com/skvadrik/re2c/commit/d87f86ed>`_).
+ Added header file to the dependencies generated with ``--depfile`` option
(`f807f763 <https://github.com/skvadrik/re2c/commit/f807f763>`_
and `2dda36aa <https://github.com/skvadrik/re2c/commit/2dda36aa>`_).
+ Fixed stack overflow on large regular expressions by rewriting recursive
functions in iterative form
(`46a9b4c4 <https://github.com/skvadrik/re2c/commit/46a9b4c4>`_,
`aaf68292 <https://github.com/skvadrik/re2c/commit/aaf68292>`_,
`02e5d797 <https://github.com/skvadrik/re2c/commit/02e5d797>`_,
`5fffb187 <https://github.com/skvadrik/re2c/commit/5fffb187>`_)
and limited stack to 256K on GithubActions CI
(`111ee5da <https://github.com/skvadrik/re2c/commit/111ee5da>`_).
- Build system:
+ Added minimal http://bazel.build integration
(`3205c867 <https://github.com/skvadrik/re2c/commit/3205c867>`_).
+ Added configure option ``--enable-parsers`` that regenerates bison parsers
(`9e0dbd3c <https://github.com/skvadrik/re2c/commit/9e0dbd3c>`_).
+ Added CMake option ``RE2C_REBUILD_PARSERS``
(`6e91c22d <https://github.com/skvadrik/re2c/commit/6e91c22d>`_).
+ With CMake, fixed documentation generation on Windows.
- Codebase improvements:
+ Moved the entire codebase to C++11.
+ Added uniform error handling (return codes are now properly checked and
returned to the caller).
+ Reorganized codegen subsystem in four well-defined phases (analyze,
generate, fixup, render) and separated codegen from parsing phase.
+ Improved memory allocation by using slab allocators instead of global free
lists.
+ Moved to pure API for bison parsers.
+ Unified code style.
- Testing:
+ Added ``--verbose`` flag to run_tests.py and suppressed verbose output by
default.
+ Multiple improvements of continuous testing with GithubActions.
3.0 (2022-01-27)
~~~~~~~~~~~~~~~~
@@ -113,10 +616,6 @@ Changelog
`039c1894 <https://github.com/skvadrik/re2c/commit/039c1894>`_.
----
2.2x
----
2.2 (2021-08-01)
~~~~~~~~~~~~~~~~
@@ -152,9 +651,6 @@ Changelog
- Updated documentation.
----
2.1x
----
2.1.1 (2021-03-27)
~~~~~~~~~~~~~~~~~~
@@ -210,9 +706,6 @@ Changelog
- Updated documentation for end of input handling and submatch extraction.
----
2.0x
----
2.0.3 (2020-08-22)
~~~~~~~~~~~~~~~~~~
@@ -320,9 +813,6 @@ Changelog
- Major revision of the paper "Efficient POSIX submatch extraction on NFA".
----
1.3x
----
1.3 (2019-12-14)
~~~~~~~~~~~~~~~~
@@ -346,9 +836,6 @@ Changelog
(`#258 <https://github.com/skvadrik/re2c/pull/258>`_:
Make the build reproducible).
----
1.2x
----
1.2.1 (2019-08-11)
~~~~~~~~~~~~~~~~~~
@@ -530,9 +1017,6 @@ Changelog
- Updated documentation and website.
----
1.1x
----
1.1.1 (2018-08-30)
~~~~~~~~~~~~~~~~~~
@@ -550,9 +1034,6 @@ Changelog
Bugs with option: ``re2c:flags:no-debug-info``.
- Reworked first part of TDFA paper.
----
1.0x
----
1.0.3 (2017-11-08)
~~~~~~~~~~~~~~~~~~
@@ -718,10 +1199,6 @@ Changelog
Makefile.am: create target directory before writing into it
-----
0.16x
-----
0.16 (2016-01-21)
~~~~~~~~~~~~~~~~~
@@ -734,10 +1211,6 @@ Changelog
test failure on big endian archs with 0.15.3
-----
0.15x
-----
0.15.3 (2015-12-02)
~~~~~~~~~~~~~~~~~~~
@@ -861,10 +1334,6 @@ Changelog
keep a mirror on sourceforge.
-----
0.14x
-----
0.14.3 (2015-05-20)
~~~~~~~~~~~~~~~~~~~
@@ -898,10 +1367,6 @@ Changelog
Dot output label escaped characters
-----
0.13x
-----
0.13.7.5 (2014-08-22)
~~~~~~~~~~~~~~~~~~~~~
@@ -1012,10 +1477,6 @@ Changelog
- Fixed #1708378 segfault ``in actions.cc``.
-----
0.12x
-----
0.12.3 (2007-08-24)
~~~~~~~~~~~~~~~~~~~
@@ -1067,10 +1528,6 @@ Changelog
+ aCC: HP C/aC++ B3910B A.06.15 [Mar 28 2007] (HP-UX IA64)
-----
0.11x
-----
0.11.3 (2007-04-01)
~~~~~~~~~~~~~~~~~~~
@@ -1097,10 +1554,6 @@ Changelog
- Added ``-u`` switch to support unicode.
-----
0.10x
-----
0.10.8 (2007-04-01)
~~~~~~~~~~~~~~~~~~~
@@ -1231,10 +1684,6 @@ Changelog
- Applied #1307467 Unicode patch for 0.9.7.
----
0.9x
----
0.9.12 (2005-12-28)
~~~~~~~~~~~~~~~~~~~
@@ -1328,9 +1777,8 @@ Changelog
- Removed rcs comments in source files.
-------------------------
re2c adopted (2003-12-09)
-------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~
- Version 0.9.1 README::
+358 -250
View File
@@ -1,63 +1,84 @@
cmake_minimum_required(VERSION 3.12)
project(re2c VERSION 3.0 HOMEPAGE_URL "https://re2c.org/")
cmake_minimum_required(VERSION 3.15)
project(re2c VERSION 4.6 HOMEPAGE_URL "https://re2c.org/")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(Re2cAutotoolsHelpers)
include(Re2cBootstrapLexer)
include(Re2cBootstrapParser)
include(Re2cBootstrapSyntax)
include(Re2cBuildType)
include(Re2cGenDocs)
include(Re2cCompilerFlags)
ac_subst(PACKAGE_VERSION "${PROJECT_VERSION}")
# check whether re2c is the root project
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
set(RE2C_IS_ROOT_PROJECT TRUE)
else()
set(RE2C_IS_ROOT_PROJECT FALSE)
endif()
option(RE2C_REBUILD_LEXERS "Regenerate lexers" OFF)
if(RE2C_REBUILD_LEXERS AND NOT RE2C_FOR_BUILD)
message(FATAL_ERROR "option RE2C_FOR_BUILD is required for RE2C_REBUILD_LEXERS")
endif()
option(RE2C_REBUILD_DOCS "Regenerate manpage" OFF)
if(RE2C_REBUILD_DOCS)
find_program(RST2MAN NAMES rst2man rst2man.py)
if(NOT RST2MAN)
message(FATAL_ERROR "rst2man (or rst2man.py) program is required for RE2C_REBUILD_DOCS")
endif()
# Windows does not have a native 'man' and 'sed' commands.
# Therefore, we are looking for the Cygwin versions of 'man' and 'sed'.
if (WIN32)
find_program(MAN_EXECUTABLE man)
if(NOT MAN_EXECUTABLE)
message(FATAL_ERROR "man program is required for RE2C_REBUILD_DOCS")
endif()
find_program(SED_EXECUTABLE sed)
if(NOT SED_EXECUTABLE)
message(FATAL_ERROR "sed program is required for RE2C_REBUILD_DOCS")
endif()
endif()
option(RE2C_REBUILD_PARSERS "Regenerate parsers with Bison" OFF)
if(RE2C_REBUILD_PARSERS AND NOT RE2C_FOR_BUILD)
find_package(BISON REQUIRED)
endif()
option(RE2C_REBUILD_SYNTAX "Regenerate default syntax files" OFF)
option(RE2C_REBUILD_DOCS "Regenerate manpage" OFF)
option(RE2C_BUILD_LIBS "Build libraries" OFF)
option(RE2C_BUILD_RE2D "Build re2d executable (an alias for `re2c --lang d`)" ON)
option(RE2C_BUILD_RE2GO "Build re2go executable (an alias for `re2c --lang go`)" ON)
option(RE2C_BUILD_RE2HS "Build re2hs executable (an alias for `re2c --lang haskell`)" ON)
option(RE2C_BUILD_RE2JAVA "Build re2java executable (an alias for `re2c --lang java`)" ON)
option(RE2C_BUILD_RE2JS "Build re2js executable (an alias for `re2c --lang js`)" ON)
option(RE2C_BUILD_RE2OCAML "Build re2ocaml executable (an alias for `re2c --lang ocaml`)" ON)
option(RE2C_BUILD_RE2PY "Build re2py executable (an alias for `re2c --lang python`)" ON)
option(RE2C_BUILD_RE2RUST "Build re2rust executable (an alias for `re2c --lang rust`)" ON)
option(RE2C_BUILD_RE2SWIFT "Build re2swift executable (an alias for `re2c --lang swift`)" ON)
option(RE2C_BUILD_RE2V "Build re2v executable (an alias for `re2c --lang v`)" ON)
option(RE2C_BUILD_RE2ZIG "Build re2zig executable (an alias for `re2c --lang zig`)" ON)
option(RE2C_BUILD_BENCHMARKS "Build benchmarks" OFF)
option(RE2C_REGEN_BENCHMARKS "Regenerate C code for benchmarks" OFF)
# test targets are enabled by default only if re2c is the root project
option(RE2C_BUILD_TESTS "Build tests" "${RE2C_IS_ROOT_PROJECT}")
# checks for programs
find_package(BISON)
find_package(Python3 COMPONENTS Interpreter)
if(RE2C_REBUILD_DOCS OR RE2C_BUILD_TESTS OR RE2C_BUILD_BENCHMARKS)
find_package(Python3 3.7 REQUIRED COMPONENTS Interpreter)
endif()
# checks for C++ compiler flags
set(CMAKE_CXX_STANDARD 98)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON) # make sure object libraries work with shared libraries
if(RE2C_REBUILD_DOCS)
execute_process(
COMMAND "${Python3_EXECUTABLE}" -c "import docutils"
RESULT_VARIABLE EXIT_CODE
OUTPUT_QUIET
)
if (NOT ${EXIT_CODE} EQUAL 0)
message(FATAL_ERROR "python package docutils (needed for docs) not found")
endif()
endif()
# Use C++11 standard. Note that without `set(CMAKE_CXX_EXTENSIONS OFF)` this enables
# -std=gnu++11, not -std=c++11. Extensions are needed to enable POSIX functions on
# Cygwin and NetBSD.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON) # fail if the C++ compiler does not support this standard
# make sure object libraries work with shared libraries
include(CheckPIESupported)
check_pie_supported()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# use system stdint.h if present, otherwise fallback to src/c99_stdint.h
ac_check_headers("stdint.h")
# needed for POSIX file API
ac_check_headers("sys/types.h")
ac_check_headers("sys/stat.h")
@@ -66,36 +87,54 @@ ac_check_headers("unistd.h")
# windows POSIX-like API
ac_check_headers("io.h")
# list of possible types to use in typedefs
ac_check_sizeof("char")
ac_check_sizeof("short")
ac_check_sizeof("int")
ac_check_sizeof("long")
ac_check_sizeof("long long")
ac_check_sizeof("__int64")
ac_check_sizeof("void *")
# 64-bit integer constant suffix
ac_check_sizeof("0l")
ac_check_sizeof("0ll")
ac_check_sizeof("0i8")
# docs (manpages and help)
set(re2c_manpage_source "${CMAKE_CURRENT_BINARY_DIR}/doc/manpage.rst")
set(re2c_help_source "${CMAKE_CURRENT_BINARY_DIR}/doc/help.rst")
set(re2c_manpage_bootstrap_c "${CMAKE_CURRENT_SOURCE_DIR}/bootstrap/doc/re2c.1")
set(re2c_manpage_bootstrap_go "${CMAKE_CURRENT_SOURCE_DIR}/bootstrap/doc/re2go.1")
set(re2c_help_bootstrap "${CMAKE_CURRENT_SOURCE_DIR}/bootstrap/src/msg/help.cc")
set(re2c_manpage_c "${CMAKE_CURRENT_BINARY_DIR}/doc/re2c.1")
set(re2c_manpage_go "${CMAKE_CURRENT_BINARY_DIR}/doc/re2go.1")
set(re2c_help "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help.cc")
set(re2c_genhelp "${CMAKE_CURRENT_SOURCE_DIR}/build/gen_help.sh")
set(re2c_splitman "${CMAKE_CURRENT_SOURCE_DIR}/build/split_man.sh")
set(re2c_manpage_source "${CMAKE_CURRENT_BINARY_DIR}/doc/manpage.rst")
set(re2c_help_source "${CMAKE_CURRENT_BINARY_DIR}/doc/help.rst")
set(re2c_manpage_c "${CMAKE_CURRENT_BINARY_DIR}/doc/re2c.1")
set(re2c_manpage_d "${CMAKE_CURRENT_BINARY_DIR}/doc/re2d.1")
set(re2c_manpage_go "${CMAKE_CURRENT_BINARY_DIR}/doc/re2go.1")
set(re2c_manpage_haskell "${CMAKE_CURRENT_BINARY_DIR}/doc/re2hs.1")
set(re2c_manpage_java "${CMAKE_CURRENT_BINARY_DIR}/doc/re2java.1")
set(re2c_manpage_js "${CMAKE_CURRENT_BINARY_DIR}/doc/re2js.1")
set(re2c_manpage_ocaml "${CMAKE_CURRENT_BINARY_DIR}/doc/re2ocaml.1")
set(re2c_manpage_python "${CMAKE_CURRENT_BINARY_DIR}/doc/re2py.1")
set(re2c_manpage_rust "${CMAKE_CURRENT_BINARY_DIR}/doc/re2rust.1")
set(re2c_manpage_swift "${CMAKE_CURRENT_BINARY_DIR}/doc/re2swift.1")
set(re2c_manpage_v "${CMAKE_CURRENT_BINARY_DIR}/doc/re2v.1")
set(re2c_manpage_zig "${CMAKE_CURRENT_BINARY_DIR}/doc/re2zig.1")
set(re2c_help_c "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2c.cc")
set(re2c_help_d "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2d.cc")
set(re2c_help_go "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2go.cc")
set(re2c_help_haskell "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2hs.cc")
set(re2c_help_java "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2java.cc")
set(re2c_help_js "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2js.cc")
set(re2c_help_ocaml "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2ocaml.cc")
set(re2c_help_python "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2py.cc")
set(re2c_help_rust "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2rust.cc")
set(re2c_help_swift "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2swift.cc")
set(re2c_help_v "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2v.cc")
set(re2c_help_zig "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help_re2zig.cc")
set(re2c_rst2man "${CMAKE_CURRENT_SOURCE_DIR}/build/rst2man.py")
set(re2c_rst2txt "${CMAKE_CURRENT_SOURCE_DIR}/build/rst2txt.py")
set(re2c_splitman "${CMAKE_CURRENT_SOURCE_DIR}/build/split_man.py")
set(re2c_docs
"${re2c_help}"
"${re2c_manpage_c}"
"$<$<BOOL:${RE2C_BUILD_RE2D}>:${re2c_manpage_d}>"
"$<$<BOOL:${RE2C_BUILD_RE2GO}>:${re2c_manpage_go}>"
"$<$<BOOL:${RE2C_BUILD_RE2HS}>:${re2c_manpage_haskell}>"
"$<$<BOOL:${RE2C_BUILD_RE2JAVA}>:${re2c_manpage_java}>"
"$<$<BOOL:${RE2C_BUILD_RE2JS}>:${re2c_manpage_js}>"
"$<$<BOOL:${RE2C_BUILD_RE2OCAML}>:${re2c_manpage_ocaml}>"
"$<$<BOOL:${RE2C_BUILD_RE2PY}>:${re2c_manpage_python}>"
"$<$<BOOL:${RE2C_BUILD_RE2RUST}>:${re2c_manpage_rust}>"
"$<$<BOOL:${RE2C_BUILD_RE2SWIFT}>:${re2c_manpage_swift}>"
"$<$<BOOL:${RE2C_BUILD_RE2V}>:${re2c_manpage_v}>"
"$<$<BOOL:${RE2C_BUILD_RE2ZIG}>:${re2c_manpage_zig}>"
)
# syntax files
set(re2c_stx2cpp "${CMAKE_CURRENT_SOURCE_DIR}/build/stx2cpp.py")
set(top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
set(top_builddir "${CMAKE_CURRENT_BINARY_DIR}")
set(PYTHON "${Python3_EXECUTABLE}")
@@ -103,10 +142,12 @@ set(PYTHON "${Python3_EXECUTABLE}")
configure_file(doc/manpage.rst.in doc/manpage.rst @ONLY)
configure_file(doc/help.rst.in doc/help.rst @ONLY)
configure_file(run_tests.py.in run_tests.py @ONLY)
set(RE2C_RUN_TESTS "${CMAKE_CURRENT_BINARY_DIR}/run_tests.py")
if(CMAKE_HOST_UNIX)
execute_process(COMMAND chmod +x "${RE2C_RUN_TESTS}")
if(RE2C_BUILD_TESTS)
configure_file(run_tests.py.in run_tests.py @ONLY)
set(RE2C_RUN_TESTS "${CMAKE_CURRENT_BINARY_DIR}/run_tests.py")
if(CMAKE_HOST_UNIX)
execute_process(COMMAND chmod +x "${RE2C_RUN_TESTS}")
endif()
endif()
ac_config_headers("config.h")
@@ -124,12 +165,26 @@ include_directories(. "${CMAKE_CURRENT_BINARY_DIR}")
# WARNING: custom target that depends on autogenerated sources won't do here
# as its dependencies get built multiple times, which ruins parallel builds.
add_library(re2c_objects_autogen OBJECT
"${CMAKE_CURRENT_BINARY_DIR}/src/options/parse_opts.cc"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/lexer.cc"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/lexer.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/parser.cc"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/parser.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/lex.cc"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/lex.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/lex_conf.cc"
"${CMAKE_CURRENT_BINARY_DIR}/src/options/parse_opts.cc"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/conf_lexer.cc"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/conf_parser.cc"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/conf_parser.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_c.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_d.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_go.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_haskell.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_java.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_js.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_ocaml.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_python.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_rust.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_swift.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_v.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/default_syntax_zig.h"
"${re2c_docs}"
)
add_library(re2c_objects_autogen_ver_to_vernum OBJECT
@@ -137,20 +192,14 @@ add_library(re2c_objects_autogen_ver_to_vernum OBJECT
)
set(re2c_sources
src/codegen/code_goto.cc
src/codegen/combine.cc
src/codegen/gen_bitmaps.cc
src/codegen/gen_delayed.cc
src/codegen/gen_dfa.cc
src/codegen/gen_goto.cc
src/codegen/gen_program.cc
src/codegen/gen_state.cc
src/codegen/helpers.cc
src/codegen/remove_empty.cc
src/codegen/render.cc
src/codegen/output.cc
src/codegen/pass1_analyze.cc
src/codegen/pass2_generate.cc
src/codegen/pass3_fixup.cc
src/codegen/pass4_render.cc
src/options/opt.cc
src/options/symtab.cc
src/nfa/estimate_size.cc
src/nfa/re_to_nfa.cc
src/adfa/adfa.cc
src/debug/dump_adfa.cc
@@ -176,27 +225,22 @@ set(re2c_sources
src/dfa/fillpoints.cc
src/dfa/find_state.cc
src/dfa/minimization.cc
src/dfa/stacmd.cc
src/dfa/tagver_table.cc
src/dfa/tcmd.cc
src/encoding/ebcdic/ebcdic_regexp.cc
src/encoding/ebcdic.cc
src/encoding/enc.cc
src/encoding/range_suffix.cc
src/encoding/utf8/utf8_regexp.cc
src/encoding/utf8/utf8.cc
src/encoding/utf16/utf16_regexp.cc
src/encoding/utf16/utf16.cc
src/encoding/unicode_casemap.cc
src/encoding/utf8.cc
src/encoding/utf16.cc
src/msg/msg.cc
src/msg/warn.cc
src/regexp/ast_to_re.cc
src/regexp/default_tags.cc
src/regexp/fixed_tags.cc
src/regexp/nullable.cc
src/regexp/re.cc
src/regexp/rule.cc
src/regexp/regexp.cc
src/regexp/split_charset.cc
src/regexp/tag.cc
src/compile.cc
src/skeleton/control_flow.cc
src/skeleton/generate_code.cc
src/skeleton/generate_data.cc
@@ -204,167 +248,233 @@ set(re2c_sources
src/skeleton/skeleton.cc
src/parse/ast.cc
src/parse/input.cc
src/parse/parse.cc
src/parse/scanner.cc
src/parse/unescape.cc
src/util/file_utils.cc
src/util/s_to_n32_unsafe.cc
src/util/temp_file.cc
src/util/string_utils.cc
src/util/range.cc
src/main.cc
$<TARGET_OBJECTS:re2c_objects_autogen>
$<TARGET_OBJECTS:re2c_objects_autogen_ver_to_vernum>
)
re2c_bootstrap_lexer("src/msg/ver_to_vernum.re" "src/msg/ver_to_vernum.cc")
re2c_bootstrap_lexer("src/options/parse_opts.re" "src/options/parse_opts.cc")
re2c_bootstrap_lexer("src/parse/lexer.re" "src/parse/lexer.cc" "src/parse/lexer.h")
re2c_bootstrap_parser("src/parse/parser.ypp" "src/parse/parser.cc" "src/parse/parser.h")
re2c_bootstrap_lexer("src/parse/conf_lexer.re" "src/parse/conf_lexer.cc")
re2c_bootstrap_parser("src/parse/conf_parser.ypp" "src/parse/conf_parser.cc" "src/parse/conf_parser.h")
re2c_bootstrap_syntax("include/syntax/c" "src/default_syntax_c.h")
re2c_bootstrap_syntax("include/syntax/d" "src/default_syntax_d.h")
re2c_bootstrap_syntax("include/syntax/go" "src/default_syntax_go.h")
re2c_bootstrap_syntax("include/syntax/haskell" "src/default_syntax_haskell.h")
re2c_bootstrap_syntax("include/syntax/java" "src/default_syntax_java.h")
re2c_bootstrap_syntax("include/syntax/js" "src/default_syntax_js.h")
re2c_bootstrap_syntax("include/syntax/ocaml" "src/default_syntax_ocaml.h")
re2c_bootstrap_syntax("include/syntax/python" "src/default_syntax_python.h")
re2c_bootstrap_syntax("include/syntax/rust" "src/default_syntax_rust.h")
re2c_bootstrap_syntax("include/syntax/swift" "src/default_syntax_swift.h")
re2c_bootstrap_syntax("include/syntax/v" "src/default_syntax_v.h")
re2c_bootstrap_syntax("include/syntax/zig" "src/default_syntax_zig.h")
# docs
file(GLOB_RECURSE re2c_docs_sources CONFIGURE_DEPENDS
"examples/*"
"doc/manual/*"
"${re2c_manpage_source}"
)
re2c_gen_help("${re2c_help_source}" "${re2c_help_c}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_c}")
add_custom_target(docs DEPENDS "${re2c_docs}")
# re2c
add_executable(re2c ${re2c_sources})
add_executable(re2c ${re2c_sources} "${re2c_help_c}")
# re2d
if (RE2C_BUILD_RE2D)
re2c_gen_help("${re2c_help_source}" "${re2c_help_d}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_d}")
add_executable(re2d ${re2c_sources} "${re2c_help_d}")
target_compile_definitions(re2d PUBLIC
"RE2C_LANG=Lang::D"
"RE2C_PROG=\"re2d\""
)
endif()
# re2go
if (RE2C_BUILD_RE2GO)
add_executable(re2go ${re2c_sources})
target_compile_definitions(re2go PUBLIC "RE2C_LANG=LANG_GO")
re2c_gen_help("${re2c_help_source}" "${re2c_help_go}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_go}")
add_executable(re2go ${re2c_sources} "${re2c_help_go}")
target_compile_definitions(re2go PUBLIC
"RE2C_LANG=Lang::GO"
"RE2C_PROG=\"re2go\""
)
endif()
# re2hs
if (RE2C_BUILD_RE2HS)
re2c_gen_help("${re2c_help_source}" "${re2c_help_haskell}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_haskell}")
add_executable(re2hs ${re2c_sources} "${re2c_help_haskell}")
target_compile_definitions(re2hs PUBLIC
"RE2C_LANG=Lang::HASKELL"
"RE2C_PROG=\"re2hs\""
)
endif()
# re2java
if (RE2C_BUILD_RE2JAVA)
re2c_gen_help("${re2c_help_source}" "${re2c_help_java}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_java}")
add_executable(re2java ${re2c_sources} "${re2c_help_java}")
target_compile_definitions(re2java PUBLIC
"RE2C_LANG=Lang::JAVA"
"RE2C_PROG=\"re2java\""
)
endif()
# re2js
if (RE2C_BUILD_RE2JS)
re2c_gen_help("${re2c_help_source}" "${re2c_help_js}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_js}")
add_executable(re2js ${re2c_sources} "${re2c_help_js}")
target_compile_definitions(re2js PUBLIC
"RE2C_LANG=Lang::JS"
"RE2C_PROG=\"re2js\""
)
endif()
# re2ocaml
if (RE2C_BUILD_RE2OCAML)
re2c_gen_help("${re2c_help_source}" "${re2c_help_ocaml}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_ocaml}")
add_executable(re2ocaml ${re2c_sources} "${re2c_help_ocaml}")
target_compile_definitions(re2ocaml PUBLIC
"RE2C_LANG=Lang::OCAML"
"RE2C_PROG=\"re2ocaml\""
)
endif()
# re2py
if (RE2C_BUILD_RE2PY)
re2c_gen_help("${re2c_help_source}" "${re2c_help_python}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_python}")
add_executable(re2py ${re2c_sources} "${re2c_help_python}")
target_compile_definitions(re2py PUBLIC
"RE2C_LANG=Lang::PYTHON"
"RE2C_PROG=\"re2py\""
)
endif()
# re2rust
if (RE2C_BUILD_RE2RUST)
add_executable(re2rust ${re2c_sources})
target_compile_definitions(re2rust PUBLIC "RE2C_LANG=LANG_RUST")
re2c_gen_help("${re2c_help_source}" "${re2c_help_rust}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_rust}")
add_executable(re2rust ${re2c_sources} "${re2c_help_rust}")
target_compile_definitions(re2rust PUBLIC
"RE2C_LANG=Lang::RUST"
"RE2C_PROG=\"re2rust\""
)
endif()
re2c_bootstrap_lexer("src/parse/lex.re" "src/parse/lex.cc" "src/parse/lex.h")
re2c_bootstrap_lexer("src/parse/lex_conf.re" "src/parse/lex_conf.cc")
re2c_bootstrap_lexer("src/options/parse_opts.re" "src/options/parse_opts.cc")
re2c_bootstrap_lexer("src/msg/ver_to_vernum.re" "src/msg/ver_to_vernum.cc")
re2c_bootstrap_parser("src/parse/parser.ypp" "src/parse/parser.cc" "src/parse/parser.h")
if (RE2C_BUILD_RE2SWIFT)
re2c_gen_help("${re2c_help_source}" "${re2c_help_swift}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_swift}")
add_executable(re2swift ${re2c_sources} "${re2c_help_swift}")
target_compile_definitions(re2swift PUBLIC
"RE2C_LANG=Lang::SWIFT"
"RE2C_PROG=\"re2swift\""
)
endif()
# docs
set(re2c_docs_sources
"${re2c_manpage_source}"
"doc/manual/api/interface.rst_"
"doc/manual/conditions/blocks.rst_"
"doc/manual/conditions/conditions.rst_"
"doc/manual/configurations/configurations.rst_"
"doc/manual/directives/directives.rst_"
"doc/manual/dot/dot.rst_"
"doc/manual/encodings/encodings.rst_"
"doc/manual/eof/01_sentinel.rst_"
"doc/manual/eof/02_bounds_checking.rst_"
"doc/manual/eof/03_eof_rule.rst_"
"doc/manual/eof/04_generic_api.rst_"
"doc/manual/eof/eof.rst_"
"doc/manual/fill/01_fill.rst_"
"doc/manual/fill/02_fill.rst_"
"doc/manual/fill/fill.rst_"
"doc/manual/headers/headers.rst_"
"doc/manual/includes/includes.rst_"
"doc/manual/options/debug.rst_"
"doc/manual/options/internal.rst_"
"doc/manual/options/options.rst_"
"doc/manual/regexps/regular_expressions.rst_"
"doc/manual/reuse/reuse.rst_"
"doc/manual/skeleton/skeleton.rst_"
"doc/manual/state/state.rst_"
"doc/manual/submatch/submatch_example_mtags.rst_"
"doc/manual/submatch/submatch_example_posix.rst_"
"doc/manual/submatch/submatch_example_stags_fill.rst_"
"doc/manual/submatch/submatch_example_stags.rst_"
"doc/manual/submatch/submatch.rst_"
"doc/manual/synopsis.rst_"
"doc/manual/syntax/api1.rst_"
"doc/manual/syntax/api2_c.rst_"
"doc/manual/syntax/api2_go.rst_"
"doc/manual/syntax/api2_rust.rst_"
"doc/manual/syntax/api3.rst_"
"doc/manual/syntax/intro.rst_"
"doc/manual/syntax/syntax.rst_"
"doc/manual/warnings/warnings_general.rst_"
"doc/manual/warnings/warnings_list.rst_"
"examples/c/01_basic.re"
"examples/c/01_basic.c"
"examples/c/conditions/parse_u32_blocks.re"
"examples/c/conditions/parse_u32_conditions.re"
"examples/c/encodings/unicode_identifier.re"
"examples/c/eof/01_sentinel.re"
"examples/c/eof/02_bounds_checking.re"
"examples/c/eof/03_eof_rule.re"
"examples/c/eof/05_generic_api_eof_rule.re"
"examples/c/fill/01_fill.re"
"examples/c/fill/02_fill.re"
"examples/c/headers/header.re"
"examples/c/headers/lexer/state.h"
"examples/c/includes/include.re"
"examples/c/includes/definitions.h"
"examples/c/reuse/reuse.re"
"examples/c/reuse/usedir.re"
"examples/c/state/push.re"
"examples/c/submatch/01_stags_fill.re"
"examples/c/submatch/01_stags.re"
"examples/c/submatch/02_mtags.re"
"examples/c/submatch/03_posix.re"
"examples/go/01_basic.re"
"examples/go/01_basic.go"
"examples/go/conditions/parse_u32_blocks.re"
"examples/go/conditions/parse_u32_conditions.re"
"examples/go/encodings/unicode_identifier.re"
"examples/go/eof/01_sentinel.re"
"examples/go/eof/02_bounds_checking.re"
"examples/go/eof/03_eof_rule.re"
"examples/go/eof/05_generic_api_eof_rule.re"
"examples/go/fill/01_fill.re"
"examples/go/fill/02_fill.re"
"examples/go/headers/header.re"
"examples/go/headers/lexer/state.go"
"examples/go/includes/include.re"
"examples/go/includes/definitions.go"
"examples/go/reuse/reuse.re"
"examples/go/reuse/usedir.re"
"examples/go/state/push.re"
"examples/go/submatch/01_stags_fill.re"
"examples/go/submatch/01_stags.re"
"examples/go/submatch/02_mtags.re"
"examples/go/submatch/03_posix.re"
"examples/rust/01_basic.re"
"examples/rust/01_basic.rs"
"examples/rust/conditions/parse_u32_blocks.re"
"examples/rust/conditions/parse_u32_conditions.re"
"examples/rust/encodings/unicode_identifier.re"
"examples/rust/eof/01_sentinel.re"
"examples/rust/eof/02_bounds_checking.re"
"examples/rust/eof/03_eof_rule.re"
"examples/rust/eof/05_generic_api_eof_rule.re"
"examples/rust/fill/01_fill.re"
"examples/rust/fill/02_fill.re"
"examples/rust/headers/header.re"
"examples/rust/headers/lexer/state.rs"
"examples/rust/includes/include.re"
"examples/rust/includes/definitions.rs"
"examples/rust/reuse/reuse.re"
"examples/rust/reuse/usedir.re"
"examples/rust/state/push.re"
"examples/rust/submatch/01_stags_fill.re"
"examples/rust/submatch/01_stags.re"
"examples/rust/submatch/02_mtags.re"
"examples/rust/submatch/03_posix.re"
)
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_c}" "${re2c_manpage_bootstrap_c}" "c")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_go}" "${re2c_manpage_bootstrap_go}" "go")
re2c_gen_help("${re2c_help_source}" "${re2c_help}" "${re2c_help_bootstrap}")
add_custom_target(docs DEPENDS "${re2c_docs}")
# re2v
if (RE2C_BUILD_RE2V)
re2c_gen_help("${re2c_help_source}" "${re2c_help_v}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_v}")
add_executable(re2v ${re2c_sources} "${re2c_help_v}")
target_compile_definitions(re2v PUBLIC
"RE2C_LANG=Lang::V"
"RE2C_PROG=\"re2v\""
)
endif()
# install and test targets are enabled only if re2c is the root project
if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
# re2zig
if (RE2C_BUILD_RE2ZIG)
re2c_gen_help("${re2c_help_source}" "${re2c_help_zig}")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_zig}")
add_executable(re2zig ${re2c_sources} "${re2c_help_zig}")
target_compile_definitions(re2zig PUBLIC
"RE2C_LANG=Lang::ZIG"
"RE2C_PROG=\"re2zig\""
)
endif()
# install targets are enabled only if re2c is the root project
if(RE2C_IS_ROOT_PROJECT)
# install
install(TARGETS re2c RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_c}" DESTINATION "share/man/man1")
if(RE2C_BUILD_RE2D)
install(TARGETS re2d RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_d}" DESTINATION "share/man/man1")
endif()
if(RE2C_BUILD_RE2GO)
install(TARGETS re2go RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_go}" DESTINATION "share/man/man1")
endif()
if(RE2C_BUILD_RE2HS)
install(TARGETS re2hs RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_haskell}" DESTINATION "share/man/man1")
endif()
if(RE2C_BUILD_RE2JAVA)
install(TARGETS re2java RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_java}" DESTINATION "share/man/man1")
endif()
if(RE2C_BUILD_RE2JS)
install(TARGETS re2js RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_js}" DESTINATION "share/man/man1")
endif()
if(RE2C_BUILD_RE2OCAML)
install(TARGETS re2ocaml RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_ocaml}" DESTINATION "share/man/man1")
endif()
if(RE2C_BUILD_RE2PY)
install(TARGETS re2py RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_python}" DESTINATION "share/man/man1")
endif()
if(RE2C_BUILD_RE2RUST)
install(TARGETS re2rust RUNTIME DESTINATION bin)
# TODO: add docs for Rust.
install(FILES "${re2c_manpage_rust}" DESTINATION "share/man/man1")
endif()
install(FILES include/unicode_categories.re DESTINATION "${RE2C_STDLIB_DIR}")
if(RE2C_BUILD_RE2SWIFT)
install(TARGETS re2swift RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_swift}" DESTINATION "share/man/man1")
endif()
if(RE2C_BUILD_RE2V)
install(TARGETS re2v RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_v}" DESTINATION "share/man/man1")
endif()
if(RE2C_BUILD_RE2ZIG)
install(TARGETS re2zig RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_zig}" DESTINATION "share/man/man1")
endif()
install(FILES
include/syntax/c
include/syntax/d
include/syntax/go
include/syntax/haskell
include/syntax/java
include/syntax/js
include/syntax/ocaml
include/syntax/python
include/syntax/rust
include/syntax/swift
include/syntax/v
include/syntax/zig
include/unicode_blocks.re
include/unicode_categories.re
include/unicode_properties.re
DESTINATION "${RE2C_STDLIB_DIR}")
# rebuild all re2c sources using newly built re2c
add_custom_target(bootstrap
@@ -372,7 +482,9 @@ if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
COMMAND "${CMAKE_COMMAND}" -E remove_directory "doc"
COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}"
)
endif()
if(RE2C_BUILD_TESTS)
# tests
add_custom_target(tests
DEPENDS "${RE2C_RUN_TESTS}"
@@ -392,17 +504,19 @@ if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
COMMAND "${Python3_EXECUTABLE}" "${RE2C_RUN_TESTS}" --wine -j1
)
add_dependencies(wtests re2c)
add_executable(re2c_test_list
src/test/list/test.cc
)
add_executable(re2c_test_range
src/test/range/test-impl.h
src/test/range/test.cc
src/test/range/test.h
src/util/range.cc
src/util/range.h
src/util/static_assert.h
)
add_executable(re2c_test_s_to_n32_unsafe
src/test/s_to_n32_unsafe/test.cc
src/util/s_to_n32_unsafe.cc
src/util/string_utils.cc
)
add_executable(re2c_test_ver_to_vernum
src/test/ver_to_vernum/test.cc
@@ -410,9 +524,9 @@ if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
)
add_executable(re2c_test_argsubst
src/test/argsubst/test.cc
src/codegen/helpers.cc
)
add_custom_target(check_re2c
COMMAND ./re2c_test_list
COMMAND ./re2c_test_range
COMMAND ./re2c_test_s_to_n32_unsafe
COMMAND ./re2c_test_ver_to_vernum
@@ -444,21 +558,19 @@ if (RE2C_BUILD_LIBS)
)
re2c_bootstrap_lexer("lib/test_helper.re" "lib/test_helper.cc")
add_library(libre2c_objects OBJECT
set(libre2c_sources
lib/regcomp.cc
lib/regexec.cc
lib/regexec_dfa.cc
lib/regexec_dfa_regless.cc
lib/regexec_dfa_multipass.cc
lib/regexec_nfa_leftmost.cc
lib/regexec_nfa_leftmost_trie.cc
lib/regexec_nfa_posix.cc
lib/regexec_nfa_posix_trie.cc
lib/regexec_nfa_posix_backward.cc
lib/regexec_nfa_posix_kuklewicz.cc
lib/regfree.cc
lib/stubs.cc
src/parse/ast.cc
src/parse/unescape.cc
src/parse/input.cc
src/options/opt.cc
src/options/symtab.cc
src/cfg/cfg.cc
@@ -484,36 +596,29 @@ if (RE2C_BUILD_LIBS)
src/dfa/fillpoints.cc
src/dfa/find_state.cc
src/dfa/minimization.cc
src/dfa/stacmd.cc
src/dfa/tagver_table.cc
src/dfa/tcmd.cc
src/nfa/estimate_size.cc
src/nfa/re_to_nfa.cc
src/encoding/enc.cc
src/encoding/range_suffix.cc
src/encoding/ebcdic/ebcdic_regexp.cc
src/encoding/utf16/utf16.cc
src/encoding/utf16/utf16_regexp.cc
src/encoding/utf8/utf8.cc
src/encoding/utf8/utf8_regexp.cc
src/encoding/unicode_casemap.cc
src/encoding/ebcdic.cc
src/encoding/utf16.cc
src/encoding/utf8.cc
src/msg/msg.cc
src/msg/warn.cc
src/regexp/ast_to_re.cc
src/regexp/default_tags.cc
src/regexp/fixed_tags.cc
src/regexp/nullable.cc
src/regexp/re.cc
src/regexp/rule.cc
src/regexp/regexp.cc
src/regexp/split_charset.cc
src/regexp/tag.cc
src/skeleton/control_flow.cc
src/skeleton/maxpath.cc
src/skeleton/skeleton.cc
src/util/range.cc
src/util/s_to_n32_unsafe.cc
)
set(libre2c_sources
$<TARGET_OBJECTS:libre2c_objects>
src/util/file_utils.cc
src/util/string_utils.cc
$<TARGET_OBJECTS:libre2c_objects_autogen>
$<TARGET_OBJECTS:re2c_objects_autogen_ver_to_vernum>
)
@@ -547,29 +652,32 @@ if (RE2C_BUILD_LIBS)
endif()
# libre2c test
add_executable(test_libre2c lib/test.cc)
target_link_libraries(test_libre2c libre2c)
target_link_libraries(test_libre2c test_libre2c_objects_autogen)
add_custom_target(check_libre2c
COMMAND ./test_libre2c
)
if(RE2C_BUILD_TESTS)
add_executable(test_libre2c lib/test.cc)
target_link_libraries(test_libre2c libre2c)
target_link_libraries(test_libre2c test_libre2c_objects_autogen)
add_custom_target(check_libre2c
COMMAND ./test_libre2c
)
endif()
if(RE2C_BUILD_BENCHMARKS)
add_subdirectory(benchmarks/submatch_nfa)
add_subdirectory(benchmarks/submatch_dfa_jit)
add_subdirectory(benchmarks/submatch_java)
add_subdirectory(benchmarks/c/libre2c/nfa)
add_subdirectory(benchmarks/c/libre2c/jit)
add_subdirectory(benchmarks/c/libre2c/java)
endif()
else()
# empty check target
add_custom_target(check_libre2c)
if(RE2C_BUILD_TESTS)
add_custom_target(check_libre2c)
endif()
endif()
if(RE2C_BUILD_BENCHMARKS)
add_subdirectory(benchmarks/submatch_dfa_aot)
add_subdirectory(benchmarks/c)
endif()
# only add check target if toplevel project
if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
if(RE2C_BUILD_TESTS)
add_custom_target(check)
add_dependencies(check check_re2c check_libre2c)
endif()
+147 -24
View File
@@ -11,8 +11,17 @@
"hidden": true,
"installDir": "${sourceDir}/install-2",
"cacheVariables": {
"RE2C_BUILD_RE2D": true,
"RE2C_BUILD_RE2GO": true,
"RE2C_BUILD_RE2HS": true,
"RE2C_BUILD_RE2JAVA": true,
"RE2C_BUILD_RE2JS": true,
"RE2C_BUILD_RE2OCAML": true,
"RE2C_BUILD_RE2PY": true,
"RE2C_BUILD_RE2RUST": true,
"RE2C_BUILD_RE2SWIFT": true,
"RE2C_BUILD_RE2V": true,
"RE2C_BUILD_RE2ZIG": true,
"RE2C_BUILD_LIBS": true,
"RE2C_REBUILD_LEXERS": true,
"RE2C_REBUILD_DOCS": true,
@@ -48,8 +57,17 @@
"CMAKE_BUILD_TYPE": "Ubsan",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2D": false,
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
"RE2C_BUILD_RE2HS": false,
"RE2C_BUILD_RE2JAVA": false,
"RE2C_BUILD_RE2JS": false,
"RE2C_BUILD_RE2OCAML": false,
"RE2C_BUILD_RE2PY": false,
"RE2C_BUILD_RE2RUST": false,
"RE2C_BUILD_RE2SWIFT": false,
"RE2C_BUILD_RE2V": false,
"RE2C_BUILD_RE2ZIG": false
}
},
{
@@ -67,8 +85,17 @@
"CMAKE_BUILD_TYPE": "Asan",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2D": false,
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
"RE2C_BUILD_RE2HS": false,
"RE2C_BUILD_RE2JAVA": false,
"RE2C_BUILD_RE2JS": false,
"RE2C_BUILD_RE2OCAML": false,
"RE2C_BUILD_RE2PY": false,
"RE2C_BUILD_RE2RUST": false,
"RE2C_BUILD_RE2SWIFT": false,
"RE2C_BUILD_RE2V": false,
"RE2C_BUILD_RE2ZIG": false
}
},
{
@@ -86,8 +113,17 @@
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2D": false,
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
"RE2C_BUILD_RE2HS": false,
"RE2C_BUILD_RE2JAVA": false,
"RE2C_BUILD_RE2JS": false,
"RE2C_BUILD_RE2OCAML": false,
"RE2C_BUILD_RE2PY": false,
"RE2C_BUILD_RE2RUST": false,
"RE2C_BUILD_RE2SWIFT": false,
"RE2C_BUILD_RE2V": false,
"RE2C_BUILD_RE2ZIG": false
}
},
{
@@ -111,8 +147,17 @@
"CMAKE_CXX_FLAGS": "-O2 -m32",
"CMAKE_EXE_LINKER_FLAGS": "-m32",
"CMAKE_SHARED_LINKER_FLAGS": "-m32",
"RE2C_BUILD_RE2D": false,
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
"RE2C_BUILD_RE2HS": false,
"RE2C_BUILD_RE2JAVA": false,
"RE2C_BUILD_RE2JS": false,
"RE2C_BUILD_RE2OCAML": false,
"RE2C_BUILD_RE2PY": false,
"RE2C_BUILD_RE2RUST": false,
"RE2C_BUILD_RE2SWIFT": false,
"RE2C_BUILD_RE2V": false,
"RE2C_BUILD_RE2ZIG": false
}
},
{
@@ -128,8 +173,17 @@
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"RE2C_BUILD_RE2D": false,
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
"RE2C_BUILD_RE2HS": false,
"RE2C_BUILD_RE2JAVA": false,
"RE2C_BUILD_RE2JS": false,
"RE2C_BUILD_RE2OCAML": false,
"RE2C_BUILD_RE2PY": false,
"RE2C_BUILD_RE2RUST": false,
"RE2C_BUILD_RE2SWIFT": false,
"RE2C_BUILD_RE2V": false,
"RE2C_BUILD_RE2ZIG": false
}
},
{
@@ -137,6 +191,16 @@
"displayName": "Linux x86_64: GCC / Release / Skeleton / Out of tree (full)",
"inherits": ["default-full-configuration", "linux-gcc-release-ootree-skeleton-fast"]
},
{
"name": "linux-gcc-valgrind-ootree-fast",
"displayName": "Linux x86_64: GCC / Valgrind / Out of tree (fast)",
"inherits": ["linux-gcc-release-ootree-skeleton-fast"]
},
{
"name": "linux-gcc-valgrind-ootree-full",
"displayName": "Linux x86_64: GCC / Valgrind / Out of tree (full)",
"inherits": ["linux-gcc-release-ootree-skeleton-full"]
},
{
@@ -167,8 +231,17 @@
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2D": false,
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
"RE2C_BUILD_RE2HS": false,
"RE2C_BUILD_RE2JAVA": false,
"RE2C_BUILD_RE2JS": false,
"RE2C_BUILD_RE2OCAML": false,
"RE2C_BUILD_RE2PY": false,
"RE2C_BUILD_RE2RUST": false,
"RE2C_BUILD_RE2SWIFT": false,
"RE2C_BUILD_RE2V": false,
"RE2C_BUILD_RE2ZIG": false
}
},
{
@@ -186,8 +259,17 @@
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2D": false,
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
"RE2C_BUILD_RE2HS": false,
"RE2C_BUILD_RE2JAVA": false,
"RE2C_BUILD_RE2JS": false,
"RE2C_BUILD_RE2OCAML": false,
"RE2C_BUILD_RE2PY": false,
"RE2C_BUILD_RE2RUST": false,
"RE2C_BUILD_RE2SWIFT": false,
"RE2C_BUILD_RE2V": false,
"RE2C_BUILD_RE2ZIG": false
}
},
{
@@ -203,8 +285,17 @@
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"RE2C_BUILD_RE2D": false,
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
"RE2C_BUILD_RE2HS": false,
"RE2C_BUILD_RE2JAVA": false,
"RE2C_BUILD_RE2JS": false,
"RE2C_BUILD_RE2OCAML": false,
"RE2C_BUILD_RE2PY": false,
"RE2C_BUILD_RE2RUST": false,
"RE2C_BUILD_RE2SWIFT": false,
"RE2C_BUILD_RE2V": false,
"RE2C_BUILD_RE2ZIG": false
}
},
{
@@ -217,7 +308,7 @@
{
"name": "windows-config-base",
"hidden": true,
"generator": "Visual Studio 16 2019",
"generator": "Visual Studio 18 2026",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
@@ -240,17 +331,23 @@
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"RE2C_BUILD_RE2D": false,
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
"RE2C_BUILD_RE2HS": false,
"RE2C_BUILD_RE2JAVA": false,
"RE2C_BUILD_RE2JS": false,
"RE2C_BUILD_RE2OCAML": false,
"RE2C_BUILD_RE2PY": false,
"RE2C_BUILD_RE2RUST": false,
"RE2C_BUILD_RE2SWIFT": false,
"RE2C_BUILD_RE2V": false,
"RE2C_BUILD_RE2ZIG": false
}
},
{
"name": "windows-msvc-debug-ootree-full",
"displayName": "Windows x86_64: MSVC / Debug / Out of tree (full)",
"inherits": ["default-full-configuration", "windows-msvc-debug-ootree-fast"],
"cacheVariables": {
"RE2C_REBUILD_DOCS": false
}
"inherits": ["default-full-configuration", "windows-msvc-debug-ootree-fast"]
},
{
"name": "windows-msvc-debug-intree-fast",
@@ -260,17 +357,23 @@
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"RE2C_BUILD_RE2D": false,
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
"RE2C_BUILD_RE2HS": false,
"RE2C_BUILD_RE2JAVA": false,
"RE2C_BUILD_RE2JS": false,
"RE2C_BUILD_RE2OCAML": false,
"RE2C_BUILD_RE2PY": false,
"RE2C_BUILD_RE2RUST": false,
"RE2C_BUILD_RE2SWIFT": false,
"RE2C_BUILD_RE2V": false,
"RE2C_BUILD_RE2ZIG": false
}
},
{
"name": "windows-msvc-debug-intree-full",
"displayName": "Windows x86_64: MSVC / Debug / In tree (full)",
"inherits": ["default-full-configuration", "windows-msvc-debug-intree-fast"],
"cacheVariables": {
"RE2C_REBUILD_DOCS": false
}
"inherits": ["default-full-configuration", "windows-msvc-debug-intree-fast"]
},
{
"name": "windows-msvc-release-ootree-fast",
@@ -280,17 +383,23 @@
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"RE2C_BUILD_RE2D": false,
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
"RE2C_BUILD_RE2HS": false,
"RE2C_BUILD_RE2JAVA": false,
"RE2C_BUILD_RE2JS": false,
"RE2C_BUILD_RE2OCAML": false,
"RE2C_BUILD_RE2PY": false,
"RE2C_BUILD_RE2RUST": false,
"RE2C_BUILD_RE2SWIFT": false,
"RE2C_BUILD_RE2V": false,
"RE2C_BUILD_RE2ZIG": false
}
},
{
"name": "windows-msvc-release-ootree-full",
"displayName": "Windows x86_64: MSVC / Release / Out of tree (full)",
"inherits": ["default-full-configuration", "windows-msvc-release-ootree-fast"],
"cacheVariables": {
"RE2C_REBUILD_DOCS": false
}
"inherits": ["default-full-configuration", "windows-msvc-release-ootree-fast"]
}
],
"buildPresets": [
@@ -373,6 +482,20 @@
"inherits": "linux-build-base",
"configuration": "Release"
},
{
"name": "linux-gcc-valgrind-ootree-fast",
"displayName": "Linux x86_64: GCC / Valgrind / Out of tree (fast)",
"configurePreset": "linux-gcc-valgrind-ootree-fast",
"inherits": "linux-build-base",
"configuration": "Release"
},
{
"name": "linux-gcc-valgrind-ootree-full",
"displayName": "Linux x86_64: GCC / Valgrind / Out of tree (full)",
"configurePreset": "linux-gcc-valgrind-ootree-full",
"inherits": "linux-build-base",
"configuration": "Release"
},
{
+38 -19
View File
@@ -11,30 +11,49 @@ convenient).
## Language guidelines
re2c is written in C++. The project uses a conservative language subset (for
portability reasons the currently used standard is C++98). The code should stay
simple and avoid complex object hierarchies and excessive use of template
metaprogramming. It should allow the reader to concentrate on the underlying
algorithms, without the language getting in the way.
re2c is written in C++ (the current standard is C++11). The algorithms and
mathematical concepts used in the code are quite complex, so the code itself
should stay simple and let the developer focus on the underlying logic, without
the language getting in the way. For example, try to avoid complex object
hierarchies and excessive use of template metaprogramming.
The line length limit is 90 characters, indentation is 4 spaces, and the
indentation style is more or less K&R (egyptian braces).
The line length limit is 100 characters, indentation is 4 spaces, and the
indentation style is egyptian (the opening brace is on the same line). This is
the approximate `astyle` command to auto-format re2c source code (it requires
manual tweaking for argument/initializer lists and multiline comments):
## Updating bootstrap files
$ # run in source directory
$ astyle --style=google \
--max-code-length=100 \
--align-pointer=type \
--align-reference=type \
--keep-one-line-statements \
--suffix=none \
--recursive '*'
For changes that affect lexers (`.re` files), it is necessary to regenerate the
corresponding bootstrap files. This can be done by reconfiguring and
rebuilding re2c with options `--enable-lexers` (Autotools) or
`-DRE2C_REBUILD_LEXERS=ON` (CMake). `RE2C_FOR_BUILD` should be defined as a
path to an already existing re2c executable that will be used to regenerate
the lexers.
## Regenerating bootstrap files
For changes that affect parser (`.ypp` files), it is necessary to regenerate
bootstrap parser files. This happens automatically if bison is installed.
By default re2c uses bootstrap files for autogenerated sources (lexers, parsers,
docs) and does not attempt to regenerate them. Developers may need to enable
"regeneration mode" if they modify the corresponding source files.
For changes that update documentation, it is necessary to rebuild the
bootstrap manpages by reconfiguring and rebuilding re2c with options
`--enable-docs` (Autotools) or `-DRE2C_REBUILD_DOCS=ON` (CMake).
For changes that affect lexers (`.re` files), regeneration mode is configured
with options `--enable-lexers` (Autotools) or `-DRE2C_REBUILD_LEXERS=ON`
(CMake). `RE2C_FOR_BUILD` should be defined as a path to an existing re2c
executable that will be used to regenerate the lexers.
For changes that affect parsers (`.ypp` files), regeneration mode is configured
with options `--enable-parsers` (Autotools) or `-DRE2C_REBUILD_PARSERS=ON`
(CMake). In this case `bison` must be installed on the system. Otherwise
Autoconf or CMake will fail at configuration stage.
For changes that affect syntax files, regeneration mode is configured
with options `--enable-syntax` (Autotools) or `-DRE2C_REBUILD_SYNTAX=ON`
(CMake).
For changes that update documentation, it is necessary to rebuild the bootstrap
manpages by reconfiguring and rebuilding re2c with options `--enable-docs`
(Autotools) or `-DRE2C_REBUILD_DOCS=ON` (CMake).
Please do not commit trivial updates to the bootstrap files, such as changes of
the generator version or generation date.
+46
View File
@@ -0,0 +1,46 @@
If you run out of ideas of how to make re2c better...
## Multibyte switch
Reading multiple characters at a time is problematic due to the absence of
alignment guarantees: even if unaligned reads are supported by the CPU, they are
still likely to be slow.
But it should be possible to read a few characters, combine them into one using
shifts and bitwise operations, and then switch on the combined character. It can
be done with existing API; no new primitives are needed.
Of course it will only help in cases when the underlying DFA has long "chains"
of transitions without branches that can be collapsed into one transition. But
the optimization can be local (applied to some parts of the DFA).
## User-defined language support
The idea originated in a linux.org.ru thread (in Russian):
https://www.linux.org.ru/news/development/16759268?cid=16762746
The original idea was to provide an API to render the generated AST into code
and let the user implement it in the form of a plugin/library. This is
problematic because 1) there is no stable AST, and 2) there are some language-
agnostic optimizations and decisions that re2c takes way before the final
rendering phase (so it is not as simple as providing a bunch or functions to
generate code for different AST nodes).
There may be another way to provide any-language support: let the user define a
set of primitives/configurations that re2c will use for language-agnostic
decisions and for code generation (some of them exist already, but not enough to
fully redefine the target language). This is akin to the idea of Midnight
Commander's skins or syntax files. re2c can provide default syntax files for
some languages (it already provides "standard" Unicode categories).
## Negation and complement
It would be good to support these operations on regular expressions, but it
requires some research. Does TDFA present any special difficulties?
## Location support
It would be good to have something like Bison locations (automatic tracking of
line/column/filename information). This is primarily useful for tokenizers and
large lexers.
+41
View File
@@ -0,0 +1,41 @@
If re2c is unmaintained for a long time and starts to bitrot, or if you have a
fork and need to make it as simple as possible, here is a list of things that
can be cut off rather safely vs. things that are essential.
## Things to remove
These are mostly experimental research projects that have never been used
outside of lab (to the best of author's knowledge, that is):
- Benchmarks: drop optional dependencies on re2, google-benchmark, Java (libre2c
has JNI bindings); simplify the build system(s).
- libre2c: drop static/dynamic libraries support in the build system(s), e.g.
Libtool; remove a few internal options and a bunch of explicit template
instantiations in TDFA construction code that exist only for libre2c.
- One of the build systems: Autotools or CMake, whichever you like less. Someone
will get unhappy in both cases (Windows is supported only by CMake, but distro
maintainers may have decades old recipes based on Autotools).
## Things to remove only as a last resort
- Skeleton: it is really useful for testing and codegen validation, but re2c can
live without it (and a few large tests can be dropped).
- Fuzzers: same here, they are really useful to find bugs and test hypotheses,
but re2c can function without them.
## Things to keep
- Existing configurations / options / syntax: re2c must stay backwards
compatible or it will become unusable. One exception is internal/debug options
which may be removed with caution. For the rest, keep them as deprecated even
if they do nothing.
- Language backends: they add little code complexity for a lot of value (and
discipline in the codegen subsystem).
- Documentation (both on `master` branch and the website on `gh-pages` and
`gh-pages-gen` branches). Without docs no one will know how to use re2c.
+9
View File
@@ -0,0 +1,9 @@
module(
name = "re2c",
version = "4.0.2",
compatibility_level = 4,
bazel_compatibility = [">=7.0.0"]
)
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "rules_cc", version = "0.0.17")
+589 -221
View File
File diff suppressed because it is too large Load Diff
+25 -46
View File
@@ -7,7 +7,7 @@ libre2c_la_LDFLAGS = -module -no-undefined
libre2c_la_HDR = \
lib/lex.h \
lib/regcomp_dfa_regless.h \
lib/regcomp_dfa_multipass.h \
lib/regex.h \
lib/regex_impl.h \
lib/regoff_trie.h \
@@ -22,70 +22,53 @@ libre2c_la_HDR = \
src/dfa/determinization.h \
src/dfa/dfa.h \
src/dfa/posix_precedence.h \
src/dfa/stacmd.h \
src/dfa/tag_history.h \
src/dfa/tagver_table.h \
src/dfa/tcmd.h \
src/nfa/nfa.h \
src/encoding/case.h \
src/encoding/ebcdic/ebcdic.h \
src/encoding/ebcdic/ebcdic_regexp.h \
src/encoding/ebcdic.h \
src/encoding/enc.h \
src/encoding/range_suffix.h \
src/encoding/utf8/utf8.h \
src/encoding/utf8/utf8_regexp.h \
src/encoding/utf16/utf16_regexp.h \
src/encoding/utf16/utf16.h \
src/encoding/utf8.h \
src/encoding/utf16.h \
src/msg/location.h \
src/msg/msg.h \
src/msg/ver_to_vernum.h \
src/msg/warn.h \
src/regexp/re.h \
src/regexp/regexp.h \
src/regexp/rule.h \
src/regexp/tag.h \
src/compile.h \
src/skeleton/path.h \
src/skeleton/skeleton.h \
src/parse/ast.h \
src/parse/unescape.h \
src/parse/input.h \
src/parse/parser.h \
src/parse/scanner.h \
src/parse/unescape.h \
src/debug/debug.h \
src/util/allocate.h \
src/util/allocator.h \
src/util/attribute.h \
src/util/c99_stdint.h \
src/util/check.h \
src/util/containers.h \
src/util/file_utils.h \
src/util/forbid_copy.h \
src/util/free_list.h \
src/util/hash32.h \
src/util/local_increment.h \
src/util/lookup.h \
src/util/nowarn_in_bison.h \
src/util/range.h \
src/util/s_to_n32_unsafe.h \
src/util/slab_allocator.h \
src/util/smart_ptr.h \
src/util/static_assert.h \
src/util/string_utils.h \
src/util/u32lim.h \
src/util/uniq_vector.h
src/util/u32lim.h
libre2c_la_SRC = \
lib/regcomp.cc \
lib/regexec.cc \
lib/regexec_dfa.cc \
lib/regexec_dfa_regless.cc \
lib/regexec_dfa_multipass.cc \
lib/regexec_nfa_leftmost.cc \
lib/regexec_nfa_leftmost_trie.cc \
lib/regexec_nfa_posix.cc \
lib/regexec_nfa_posix_trie.cc \
lib/regexec_nfa_posix_backward.cc \
lib/regexec_nfa_posix_kuklewicz.cc \
lib/regfree.cc \
lib/stubs.cc \
src/parse/ast.cc \
src/parse/unescape.cc \
src/parse/input.cc \
src/options/opt.cc \
src/options/symtab.cc \
src/cfg/cfg.cc \
@@ -111,33 +94,29 @@ libre2c_la_SRC = \
src/dfa/fillpoints.cc \
src/dfa/find_state.cc \
src/dfa/minimization.cc \
src/dfa/stacmd.cc \
src/dfa/tagver_table.cc \
src/dfa/tcmd.cc \
src/nfa/estimate_size.cc \
src/nfa/re_to_nfa.cc \
src/encoding/enc.cc \
src/encoding/range_suffix.cc \
src/encoding/ebcdic/ebcdic_regexp.cc \
src/encoding/utf16/utf16.cc \
src/encoding/utf16/utf16_regexp.cc \
src/encoding/utf8/utf8.cc \
src/encoding/utf8/utf8_regexp.cc \
src/encoding/unicode_casemap.cc \
src/encoding/ebcdic.cc \
src/encoding/utf16.cc \
src/encoding/utf8.cc \
src/msg/msg.cc \
src/msg/warn.cc \
src/regexp/ast_to_re.cc \
src/regexp/default_tags.cc \
src/regexp/fixed_tags.cc \
src/regexp/nullable.cc \
src/regexp/re.cc \
src/regexp/rule.cc \
src/regexp/regexp.cc \
src/regexp/split_charset.cc \
src/regexp/tag.cc \
src/skeleton/control_flow.cc \
src/skeleton/maxpath.cc \
src/skeleton/skeleton.cc \
src/util/range.cc \
src/util/s_to_n32_unsafe.cc
src/util/file_utils.cc \
src/util/string_utils.cc
libre2c_la_SOURCES = \
$(libre2c_la_HDR) \
@@ -191,12 +170,12 @@ check_PROGRAMS += test_libre2c
# benchmarks
if WITH_BENCHMARKS
SUBDIRS += benchmarks/submatch_nfa
SUBDIRS += benchmarks/submatch_dfa_jit
EXTRA_DIST += benchmarks/submatch_nfa
EXTRA_DIST += benchmarks/submatch_dfa_jit
SUBDIRS += benchmarks/c/libre2c/nfa
SUBDIRS += benchmarks/c/libre2c/jit
EXTRA_DIST += benchmarks/c/libre2c/nfa
EXTRA_DIST += benchmarks/c/libre2c/jit
if WITH_JAVA
SUBDIRS += benchmarks/submatch_java
EXTRA_DIST += benchmarks/submatch_java
SUBDIRS += benchmarks/c/libre2c/java
EXTRA_DIST += benchmarks/c/libre2c/java
endif # WITH_JAVA
endif # WITH_BENCHMARKS
+16
View File
@@ -0,0 +1,16 @@
workspace(name = "re2c")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "bazel_skylib",
sha256 = "bc283cdfcd526a52c3201279cda4bc298652efa898b10b4db0837dc51652756f",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
],
)
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()
View File
-2
View File
@@ -1,5 +1,3 @@
#!/bin/sh
git clean -fX
mkdir -p m4
autoreconf -i -W all
+13
View File
@@ -0,0 +1,13 @@
package(default_visibility = ["//visibility:private"])
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
exports_files([
"re2c_config.h",
])
bzl_library(
name = "re2c_bzl",
srcs = ["re2c.bzl"],
visibility = ["//visibility:public"],
)
+70
View File
@@ -0,0 +1,70 @@
# re2c generator rules - assuming that re2c is available as '@re2c//:re2c'.
load("@bazel_skylib//lib:paths.bzl", "paths")
visibility("public")
# Define supported extensions as defined by:
# . https://bazel.build/reference/be/c-cpp#cc_library_args
# . https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/cpp/CppFileTypes.java
_C_SRC_EXT = [".c", ".cc", ".cpp", ".cxx", ".c++", ".C", ".cu", ".cl"]
_C_HDR_EXT = [".h", ".hh", ".hpp", ".ipp", ".hxx", ".h++", ".inc", ".inl", ".tlh", ".tli", ".H", ".tcc"]
_RE2C_EXT = [".re", ".re2c"]
def _re2c_impl(ctx):
srcs = ctx.files.srcs
if len(srcs) != 1:
fail("Attribute `srcs` must contain exactly 1 re2c source file ({exts}).".format(exts = ", ".join(_RE2C_EXT)))
outs = ctx.outputs.outs
if not outs or [o for o in outs if paths.split_extension(o.path)[1] not in _C_SRC_EXT + _C_HDR_EXT]:
fail("Attribute `outs` must contain at least 1 C/C++ shource or header file ({exts}).".format(exts = ", ".join(_C_SRC_EXT + _C_HDR_EXT)))
ctx.actions.run_shell(
outputs = outs,
tools = [ctx.executable._re2c_tool],
inputs = ctx.files.srcs + ctx.files.data,
command = """
"{re2c}" --no-generation-date "{src}" -o "{out}" {re2c_args} {includes}
""".format(
re2c = ctx.executable._re2c_tool.path,
src = srcs[0].path,
out = outs[0].path,
includes = " ".join(list(dict([("-I" + f.dirname, 1) for f in ctx.files.data]))),
re2c_args = " ".join(ctx.attr.re2c_args),
),
mnemonic = "RE2C",
progress_message = "Generating re2c %{label}",
)
_re2c_attr = {
"srcs": attr.label_list(
doc = "The re2c source.",
allow_files = _RE2C_EXT,
mandatory = True,
),
"data": attr.label_list(
doc = "Other input data files (e.g. include files).",
allow_files = _C_SRC_EXT + _C_HDR_EXT,
mandatory = False,
),
"outs": attr.output_list(
doc = "The generated output source.",
mandatory = True,
),
"re2c_args": attr.string_list(
doc = "Arguments to re2c invocation.",
),
"_re2c_tool": attr.label(
doc = "The target of the 're2c' executable.",
default = Label("//:re2c"),
allow_single_file = True,
executable = True,
cfg = "exec",
),
}
re2c_gen = rule(
attrs = _re2c_attr,
doc = """Use re2c tool to create an output file (e.g. '.cc') from a '.re' input.""",
output_to_genfiles = True,
implementation = _re2c_impl,
)
+4
View File
@@ -0,0 +1,4 @@
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_FCNTL_H 1
#define HAVE_UNISTD_H 1
@@ -2,8 +2,8 @@
import os
# 100 megabytes
LIMIT = 1024 * 1024 * 100
# 16 megabytes
LIMIT = 1024 * 1024 * 16
# read the small sample
with open('small', 'rb') as f:
+20
View File
@@ -0,0 +1,20 @@
1
12
123
1234
12345
123456
1234567
12345678
123456789
1234567890
12345678901
123456789012
1234567890123
12345678901234
123456789012345
1234567890123456
12345678901234567
123456789012345678
1234567890123456789
12345678901234567890
+97
View File
@@ -0,0 +1,97 @@
0b1
0b10
0b101
0b1010
0b10101
0b101010
0b1011010
0b10101010
0b101010101
0b1010101010
0b10101010101
0b101010101010
0b1010101010101
0b10101010101010
0b101010101010101
0b1010101010101010
0B1
0B10
0B111
0B1000
0B11111
0B100000
0B1111111
0B10000000
0B111111111
0B1000000000
0B11111111111
0B100000000000
0B1111111111111
0B10000000000000
0B111111111111111
0B1000000000000000
0
01
012
0123
01234
012345
0123456
01234567
012345670
1
12
123
1234
12345
123456
1234567
12345678
123456789
1234567890
0x1
0x12
0x123
0x1234
0x12345
0x123456
0x1234567
0x12345678
0x123456789
0x123456789a
0x123456789ab
0x123456789abc
0x123456789abcd
0x123456789abcde
0x123456789abcdef
0x123456789abcdef0
1.1e+1
12.12e-12
123.123e+123
1234.1234e-1234
12345.12345e+12345
123456.123456e-123456
1234567.1234567e+1234567
12345678.12345678e-12345678
123456789.123456789e+123456789
1234567890.1234567890e-1234567890
0.1
0.01
0.001
0.0001
0.00001
0.000001
0.0000001
0.00000001
0.000000001
0.0000000001
0.00000000001
0.000000000001
0.0000000000001
0.00000000000001
0.000000000000001
0.0000000000000001
0.00000000000000001
0.000000000000000001
0.0000000000000000001
0.00000000000000000001
+7
View File
@@ -0,0 +1,7 @@
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
+196
View File
@@ -0,0 +1,196 @@
Afghanistan
Albania
Algeria
Andorra
Angola
Antigua and Barbuda
Argentina
Armenia
Australia
Austria
Azerbaijan
The Bahamas
Bahrain
Bangladesh
Barbados
Belarus
Belgium
Belize
Benin
Bhutan
Bolivia
Bosnia and Herzegovina
Botswana
Brazil
Brunei
Bulgaria
Burkina Faso
Burundi
Cabo Verde
Cambodia
Cameroon
Canada
Central African Republic
Chad
Chile
China
Colombia
Comoros
Congo, Democratic Republic of the
Congo, Republic of the
Costa Rica
Cote d'Ivoire
Croatia
Cuba
Cyprus
Czech Republic
Denmark
Djibouti
Dominica
Dominican Republic
East Timor (Timor-Leste)
Ecuador
Egypt
El Salvador
Equatorial Guinea
Eritrea
Estonia
Eswatini
Ethiopia
Fiji
Finland
France
Gabon
The Gambia
Georgia
Germany
Ghana
Greece
Grenada
Guatemala
Guinea
Guinea-Bissau
Guyana
Haiti
Honduras
Hungary
Iceland
India
Indonesia
Iran
Iraq
Ireland
Israel
Italy
Jamaica
Japan
Jordan
Kazakhstan
Kenya
Kiribati
Korea, North
Korea, South
Kosovo
Kuwait
Kyrgyzstan
Laos
Latvia
Lebanon
Lesotho
Liberia
Libya
Liechtenstein
Lithuania
Luxembourg
Madagascar
Malawi
Malaysia
Maldives
Mali
Malta
Marshall Islands
Mauritania
Mauritius
Mexico
Micronesia, Federated States of
Moldova
Monaco
Mongolia
Montenegro
Morocco
Mozambique
Myanmar (Burma)
Namibia
Nauru
Nepal
Netherlands
New Zealand
Nicaragua
Niger
Nigeria
North Macedonia
Norway
Oman
Pakistan
Palau
Panama
Papua New Guinea
Paraguay
Peru
Philippines
Poland
Portugal
Qatar
Romania
Russia
Rwanda
Saint Kitts and Nevis
Saint Lucia
Saint Vincent and the Grenadines
Samoa
San Marino
Sao Tome and Principe
Saudi Arabia
Senegal
Serbia
Seychelles
Sierra Leone
Singapore
Slovakia
Slovenia
Solomon Islands
Somalia
South Africa
Spain
Sri Lanka
Sudan
Sudan, South
Suriname
Sweden
Switzerland
Syria
Taiwan
Tajikistan
Tanzania
Thailand
Togo
Tonga
Trinidad and Tobago
Tunisia
Turkey
Turkmenistan
Tuvalu
Uganda
Ukraine
United Arab Emirates
United Kingdom
United States
Uruguay
Uzbekistan
Vanuatu
Vatican City
Venezuela
Vietnam
Yemen
Zambia
Zimbabwe
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,4 @@
set -e
set -ex
if [ -e ragel7 ] ; then
echo "ragel7 is already installed, quitting"
@@ -10,7 +10,10 @@ RAGEL_DIR=ragel-7.0.4
wget http://www.colm.net/files/colm/"$COLM_DIR".tar.gz -O - | tar zx \
&& cd "$COLM_DIR" \
&& ./configure --prefix=$(pwd)/install \
&& sed -i 's|^#!/bin/bash|#!/usr/bin/env bash|' src/colm-wrap.sh \
&& ./configure \
--prefix=$(pwd)/install \
--disable-manual \
&& make -j$(nproc) \
&& make install \
&& cd ..
+390
View File
@@ -0,0 +1,390 @@
#!/usr/bin/env python3
import argparse
import json
import math
import sys
from collections import OrderedDict
plot_preamble = """
\\documentclass[tikz]{standalone}
\\usepackage[utf8]{inputenc}
\\usepackage{amsmath, amssymb, amsfonts}
\\usepackage{xcolor}
\\usepackage{tikz, pgfplots, pgfplotstable}
\\usepackage{pifont}
\\definecolor{colorX}{HTML}{A1CAF1}
\\definecolor{colorY}{HTML}{FBCEB1}
"""
# Use Comic Neue font.
plot_font_comicneue = """
\\usepackage{comicneue}
\\usepackage[T1]{fontenc}
\\renewcommand{\\familydefault}{\\sfdefault}
"""
# Use Computer Modern Bright font.
plot_font_cmbright = """
\\usepackage{cmbright}
\\usepackage[T1]{fontenc}
\\renewcommand{\\familydefault}{\\sfdefault}
"""
# Counterintuitively, 'assume math mode' tricks pgfmathprintnumber into not
# setting math mode, which is needed because Comic Neue does not support math.
#
# Use 'fixed relative' number format with very high precision (the numbers have
# been previously rounded to a few non-zero digits in the fractional part, so
# the trailing zeroes will will not be printed).
plot_begin = """
\\begin{document}
\\def\\plotwidth{%lfin}
\\def\\barwidth{%lfin}
\\pgfplotsset{styleX/.style={
font=\\scriptsize,
xbar,
axis y line*=none,
axis x line=none,
y=0.12in,
width=\\plotwidth*1.15,
bar width=\\barwidth,
xshift=\\xplotshift,
yshift=\\yplotshift,
xmax=\\xmax,
xmin=0,
ymax=0.7,
ymin=0.3 - \\nrows,
ytick=data,
ytick style={draw=none},
yticklabels=\\empty,
title=\\empty,
clip=false,
visualization depends on={x > \\xmax \\as \\xoverflow},
visualization depends on={x > \\xmax ? -x + \\xmax : 0 \\as \\xshift},
nodes near coords={
\\ifdim \\xoverflow pt=1pt \\!\\ding{220}\\! \\scriptsize \\fi
\\pgfmathprintnumber[assume math mode=true]{\\pgfplotspointmeta}
},
nodes near coords style={shift={(axis direction cs:\\xshift,0)}},
nodes near coords style={/pgf/number format/.cd,
fixed relative,
precision = 10,
1000 sep = {\\,}
},%s}}
"""
plot_labels_and_title = """
yticklabels from table={\\table}{algo},
every axis title/.style={below %s, at={(-0.08in,0)}},
title=\\title,
"""
plot_begin_picture = """
\\begin{tikzpicture}
\\begin{scope}[xshift=-0.2in, yshift=%sin * 0.75]
%s
\\end{scope}
"""
plot_middle = """
\\def\\xplotshift{%lfin}
\\def\\yplotshift{%lfin}
\\def\\nrows{%d},
\\def\\title{%s},
\\def\\xmax{%lf}
\\pgfplotstableread {%s} \\table
\\begin{axis}[styleX,%s]
\\clip(current axis.south west) rectangle(current axis.north east);
\\addplot[fill=%s] table[x=value, y expr=-\\coordindex] from \\table;
\\end{axis}
"""
plot_end_picture = """
\\end{tikzpicture}
"""
plot_end = """
\\end{document}
"""
VARIANTS = ['aot', 'jit', 'nfa']
def parse_args():
variants = ', '.join(VARIANTS)
parser = argparse.ArgumentParser()
parser.add_argument("input", help="input JSON file")
parser.add_argument("output", help="output TeX file")
parser.add_argument("--variant",
help="variant of the benchmark, one of %s" % variants)
parser.add_argument("--relative-to",
help="output CPU time relative to the specified algorithm")
parser.add_argument("--font",
help="use the specified font (supported fonts: cmbright, comicneue)")
args = parser.parse_args()
if args.variant not in VARIANTS:
sys.exit("please specify --variant (possible values: %s)" % variants)
return args
# Generate benchmark title from benchmark name.
def gen_title(oldname, remove_suffix):
if remove_suffix:
# cut off the last sub-word after the dash
oldname = oldname[:oldname.rfind("-")]
# Name begins with a letter, so it must be a plain language word.
if oldname[0].isalpha():
return oldname
# Name begins with something else than a letter, treat it as a regexp and
# render as a TeX math formula. This requires adding a few metacharacters.
newname = ""
for char in oldname:
if char in "{*+?":
# Repetition counters must be in superscript.
newname += "^"
newname += char
return "$\\boldsymbol{" + newname + "}$"
# Find index of a group which algorithm contains the given string (stem).
def index_of_algo(group, stem):
if stem == None:
return 0;
for i in range(len(group)):
(algo, _, _, _, _) = group[i]
if stem in algo:
return i
return 0
# Time format: keep integer part precise, round fractional part relative to the
# exponent (similar to PGFPLOTS's "fixed relative, precision = 2" numer format,
# but doesn't round integer part). This is to reduce visual noise on the plot.
#
# Examples: 1004, 195, 13, 3.8, 0.85, 0.017, 0.0048
#
def time_format(time):
order = math.floor(math.log(time, 10))
if order > 0:
return '%.1lf'
else:
return '%%.%dlf' % (-order + 1)
class Params:
def __init__(self, args):
self.barwidth = 0.08
if args.variant == 'aot':
self.override_params_aot()
elif args.variant == 'jit':
self.override_params_jit()
elif args.variant == 'nfa':
self.override_params_nfa()
self.font = ''
if args.font == 'comicneue':
self.font = plot_font_comicneue
elif args.font == 'cmbright':
self.font = plot_font_cmbright
elif args.font:
sys.exit('error: unsupported font: "%s"' % font)
if args.relative_to: # override only if set
self.relative_to = args.relative_to
def override_params_aot(self):
self.plotwidth = 1.5
self.xshift = 2 * self.plotwidth
self.header = """
\\node[anchor=west] (x0) at (0.15in,0) {\\small\\bf{gcc (time)}};
\\node[anchor=west] (x1) at (1.65in,0) {\\small\\bf{gcc (size)}};
\\node[anchor=west] (x2) at (3.15in,0) {\\small\\bf{clang (time)}};
\\node[anchor=west] (x3) at (4.65in,0) {\\small\\bf{clang (size)}};
"""
self.title_suffix = True
self.relative_to = None
self.title_annotate = False
self.global_styles = ""
self.local_styles = plot_labels_and_title % 'left'
def override_params_jit(self):
self.plotwidth = 2.7
self.xshift = self.plotwidth
self.header = """
\\node[anchor=west] (x0) at (0.15in,0) {\\small\\bf{regcomp (time)}};
\\node[anchor=west] (x1) at (2.85in,0) {\\small\\bf{regexec (time)}};
"""
self.title_suffix = True
self.relative_to = ''
self.title_annotate = False
self.global_styles = ""
self.local_styles = plot_labels_and_title % 'left'
def override_params_nfa(self):
self.plotwidth = 2.5
self.xshift = self.plotwidth + 1
self.header = ""
self.only_1st_col_with_labels = False
self.title_suffix = False
self.relative_to = 'LG'
self.title_annotate = True
self.global_styles = plot_labels_and_title % 'right'
self.local_styles = ""
# Split benchmarks into groups by regexp (the first component of the name).
# If the relative mode is on, normalize CPU time by the time of the first
# benchmark in each group.
#
# Expected JSON fomat:
# {
# "benchmarks": [
# {
# "name": <string>,
# ["cpu_time": <number>,]
# ["bin_size": <number>,]
# ["captures": <number>,]
# ["regsize": <number>,] ...
# }, ...
# ], ...
# }
#
def group_benchmarks(benchmarks, params):
benchcount = len(benchmarks)
groups = OrderedDict()
for bench in benchmarks:
name, algo = bench['name'].split('_')
cputime = bench['cpu_time'] if 'cpu_time' in bench else None
binsize = bench['bin_size'] if 'bin_size' in bench else None
captures = bench['captures'] if 'captures' in bench else None
regsize = bench['regsize'] if 'regsize' in bench else None
groups.setdefault(name, []).append(
(algo, cputime, binsize, captures, regsize))
maxtime = 0
avgtime = 0
maxsize = 0
avgsize = 0
maxrows = 0
nbench = 0
benchgroups = OrderedDict()
for name in groups:
group = groups[name]
relto = index_of_algo(group, params.relative_to)
(_, cputime0, binsize0, captures, regsize) = group[relto]
timetbl = None
if cputime0 != None:
table = 'algo value\n'
for (algo, time, _, _, _) in group:
time = time / (cputime0 if params.relative_to != None else 1)
maxtime = max(maxtime, time)
avgtime += time
table += ('{%s} ' + time_format(time) + '\n') % (algo, time)
timetbl = table
sizetbl = None
if binsize0 != None:
table = 'algo value\n'
for (algo, _, size, _, _) in group:
maxsize = max(maxsize, size)
avgsize += size
table += '{%s} %lf\n' % (algo, size)
sizetbl = table
title = gen_title(name, params.title_suffix)
nrows = len(group)
benchgroups[name] = (title, timetbl, sizetbl, nrows, regsize, captures)
nbench += nrows
maxrows = max(maxrows, nrows)
avgtime /= nbench
avgsize /= nbench
factor = 10 if params.relative_to != None else 5
maxtime = min(maxtime, factor * avgtime)
maxsize = min(maxsize, factor * avgsize)
params.plotheight = 0.15 + maxrows * params.barwidth * 0.75
params.maxtime = maxtime
params.maxsize = maxsize
return benchgroups
# Generate a Tikz picture with a PGF plot for each benchmark group. Crop
# very long bars, so that they do not squash other bars to the left.
def generate_plot(benchgroups, params):
plot = plot_preamble
plot += params.font
plot += plot_begin % (params.plotwidth, params.barwidth, params.global_styles)
plot += plot_begin_picture % (params.plotheight, params.header)
i = 0
for name, benchgroup in benchgroups.items():
even = i % 2 == 0
i += 1
(title, timetbl, sizetbl, nrows, regsize, captures) = benchgroup
xshift = 0 if even else params.xshift
yshift = -params.plotheight * (i if even else i - 1)
title = '\\textbf{%s}' % title
if params.title_annotate and regsize != None and captures != None:
title += ' \\, (%d symbol%s, %d capture%s)' % (
regsize, 's' if regsize > 1 else '',
captures, 's' if captures > 1 else '')
# Generate CPU time plots.
if timetbl != None:
plot += plot_middle % (xshift, yshift, nrows, title, params.maxtime,
timetbl, params.local_styles if even else '', 'colorX')
# Generate binary size plots.
if sizetbl != None:
xshift += params.plotwidth
plot += plot_middle % (xshift, yshift, nrows, title, params.maxsize,
sizetbl, '', 'colorY')
plot += plot_end_picture
plot += plot_end
return plot
def main():
args = parse_args()
with open(args.input) as f:
input = json.load(f)
params = Params(args)
groups = group_benchmarks(input['benchmarks'], params)
plot = generate_plot(groups, params)
with open(args.output, 'w') as f:
f.write(plot)
if __name__ == "__main__":
main()
+196
View File
@@ -0,0 +1,196 @@
find_package(PkgConfig REQUIRED)
pkg_check_modules(GBENCHMARK REQUIRED benchmark)
set(BENCHMARKS
"lex_00__numbers1"
"lex_01__numbers2"
"lex_02__words1"
"lex_03__words2"
"lex_04__words3"
"submatch_00__http_rfc7230"
"submatch_01__http_simple"
"submatch_02__uri_rfc3986"
"submatch_03__uri_simple"
"submatch_04__apache_log"
"submatch_05__datetime"
"submatch_06__email"
"submatch_07__ipv4"
"submatch_10__alt1_2"
"submatch_11__alt1_4"
"submatch_12__alt1_8"
"submatch_13__alt2_2"
"submatch_14__alt2_4"
"submatch_15__alt2_8"
"submatch_16__alt4_2"
"submatch_17__alt4_4"
"submatch_18__alt4_8"
"submatch_20__cat2_0"
"submatch_21__cat2_4"
"submatch_22__cat2_8"
"submatch_23__cat4_0"
"submatch_24__cat4_2"
"submatch_25__cat4_4"
"submatch_26__cat8_0"
"submatch_27__cat8_1"
"submatch_28__cat8_2"
"submatch_30__rep_cat_5_3_2"
"submatch_31__rep_cat_13_11_7"
"submatch_32__rep_cat_23_19_17"
"submatch_33__rep_alt_5_3_2"
"submatch_34__rep_alt_13_11_7"
"submatch_35__rep_alt_23_19_17"
"submatch_36__rep_5_rep_3_rep_2"
"submatch_37__rep_13_rep_11_rep_7"
"submatch_38__rep_23_rep_19_rep_17"
)
set(SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
set(ENG_DIR "${CMAKE_CURRENT_BINARY_DIR}/engines")
set(GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/gen")
set(PREGEN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/pregen")
set(GEN "")
# ragel
file(MAKE_DIRECTORY "${ENG_DIR}/ragel/")
file(MAKE_DIRECTORY "${GEN_DIR}/ragel/")
set(RAGEL "${ENG_DIR}/ragel/ragel7")
add_custom_command(
OUTPUT "${RAGEL}"
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/../_engines/ragel/getragel7.sh"
WORKING_DIRECTORY "${ENG_DIR}/ragel/"
)
foreach(bench ${BENCHMARKS})
set(src_file "${SRC_DIR}/ragel/${bench}.rl")
set(gen_file "${GEN_DIR}/ragel/${bench}.cc")
set(pregen_file "${PREGEN_DIR}/ragel/${bench}.cc")
# optionally regenerate ragel benchmarks if RE2C_REGEN_BENCHMARKS is set
if(RE2C_REGEN_BENCHMARKS)
file(RELATIVE_PATH rel_src_file "${CMAKE_CURRENT_BINARY_DIR}" "${src_file}")
file(RELATIVE_PATH rel_gen_file "${CMAKE_CURRENT_BINARY_DIR}" "${gen_file}")
add_custom_command(
OUTPUT "${gen_file}"
COMMAND "${RAGEL}" "-G2" "${rel_src_file}" -o "${rel_gen_file}"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${gen_file}" "${pregen_file}"
DEPENDS "${src_file}" "${RAGEL}"
)
else()
add_custom_command(
OUTPUT "${gen_file}"
COMMAND "${CMAKE_COMMAND}" -E copy "${pregen_file}" "${gen_file}"
DEPENDS "${pregen_file}"
)
endif()
list(APPEND GEN "${gen_file}")
endforeach()
# re2c
file(MAKE_DIRECTORY "${GEN_DIR}/re2c/")
set(RE2C "${CMAKE_BINARY_DIR}/re2c")
set(RE2C_FLAGS "--reusable" "--tags" "--no-generation-date" "--no-version" "-i")
# always regenerate re2c benchmarks
foreach(bench ${BENCHMARKS})
set(src_file "${SRC_DIR}/re2c/${bench}.re")
set(gen_file "${GEN_DIR}/re2c/${bench}.cc")
set(pregen_file "${PREGEN_DIR}/re2c/${bench}.cc")
file(RELATIVE_PATH rel_src_file "${CMAKE_CURRENT_BINARY_DIR}" "${src_file}")
file(RELATIVE_PATH rel_gen_file "${CMAKE_CURRENT_BINARY_DIR}" "${gen_file}")
add_custom_command(
OUTPUT "${gen_file}"
COMMAND "${RE2C}" ${RE2C_FLAGS} "${rel_src_file}" -o "${rel_gen_file}"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${gen_file}" "${pregen_file}"
DEPENDS "${src_file}" "${SRC_DIR}/re2c/base.re" "${RE2C}"
)
list(APPEND GEN "${gen_file}")
endforeach()
# binaries
if("${GBENCHMARK_INCLUDE_DIR}" STREQUAL "")
set(GBENCHMARK_INCLUDES "${GBENCHMARK_CFLAGS}")
else()
set(GBENCHMARK_INCLUDES "-I${GBENCHMARK_INCLUDE_DIR}")
endif()
set(RE2C_CXX_FLAGS "-O3" "-g" "-I" "${SRC_DIR}" "-Wall" "-Wno-unused-const-variable"
"${GBENCHMARK_INCLUDES}" "-std=c++11") # C++11 is needed for some google-benchmark features
list(APPEND COMPILERS "g++" "clang++")
list(APPEND COMPNAMES "gcc" "clang")
foreach(compiler IN ZIP_LISTS COMPILERS COMPNAMES)
set(objects "")
set(flags ${RE2C_CXX_FLAGS} "-DCXX=\\\"${compiler_1}\\\"")
foreach(gen_file ${GEN})
string(REGEX REPLACE
"^${GEN_DIR}(.+)\.cc$" "${GEN_DIR}\\1-${compiler_1}.o" obj_file "${gen_file}")
add_custom_command(
OUTPUT "${obj_file}"
COMMAND "${compiler_0}" ${flags} -c "${gen_file}" -o "${obj_file}"
DEPENDS "${gen_file}" "${SRC_DIR}/common.h"
)
list(APPEND objects "${obj_file}")
endforeach()
# don't use add_executable, as we need to mnually select the toolchain.
set(inputs ${objects} "${SRC_DIR}/bench.cc")
set(output "bench-${compiler_1}")
add_custom_command(
OUTPUT "${output}"
COMMAND "${compiler_0}" ${flags} ${inputs} "-o" "${output}" ${GBENCHMARK_LINK_LIBRARIES}
DEPENDS ${inputs}
)
if(compiler_1 STREQUAL "gcc") # build test only with GCC
set(test_inputs ${objects} "${SRC_DIR}/test.cc")
add_custom_command(
OUTPUT "test"
COMMAND "${compiler_0}" ${flags} ${test_inputs} "-o" "test" ${GBENCHMARK_LINK_LIBRARIES}
DEPENDS ${test_inputs}
)
endif()
endforeach()
# helper function to transform list
function(regex_replace_list regexp replace var)
set(result "")
foreach(arg ${ARGN})
string(REGEX REPLACE "${regexp}" "${replace}" x "${arg}")
list(APPEND result "${x}")
endforeach()
set(${var} "${result}" PARENT_SCOPE)
endfunction()
# input data
set(DAT)
# Some benchmarks share the same data, like submatch_03__uri_simple and submatch_02__uri_rfc3986.
regex_replace_list("^[a-z]+_[0-9]+__([^_]+).*" "\\1" INPUTS ${BENCHMARKS})
list(REMOVE_DUPLICATES INPUTS)
foreach(input ${INPUTS})
set(src_dir "${CMAKE_CURRENT_SOURCE_DIR}/../_data/${input}")
set(dst_dir "${CMAKE_CURRENT_BINARY_DIR}/data/${input}")
file(GLOB script "${CMAKE_CURRENT_SOURCE_DIR}/../_data/gen.py")
add_custom_command(
OUTPUT "${dst_dir}/small"
COMMAND "${CMAKE_COMMAND}" -E copy "${src_dir}/small" "${dst_dir}/small"
DEPENDS "${src_dir}/small"
)
add_custom_command(
OUTPUT "${dst_dir}/big"
COMMAND "${script}"
DEPENDS "${script}" "${dst_dir}/small"
WORKING_DIRECTORY "${dst_dir}"
)
list(APPEND DAT "${dst_dir}/small" "${dst_dir}/big")
endforeach()
add_custom_target(bench_submatch_aot ALL DEPENDS bench-gcc bench-clang test ${DAT})
# benchmark scripts
set(srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
set(builddir ".")
configure_file(run.py.in run.py @ONLY)
# override default clean command to keep engines
set_directory_properties(PROPERTY
CLEAN_NO_CUSTOM On
ADDITIONAL_CLEAN_FILES "${GEN};${OBJ};${BIN};${DAT}"
)
+146
View File
@@ -0,0 +1,146 @@
SRC_DIR = $(srcdir)/src
ENG_DIR = engines
GEN_DIR = gen
PREGEN_DIR = $(srcdir)/pregen
DAT_DIR = data
RAGEL = $(ENG_DIR)/ragel/ragel7
RE2C = $(top_builddir)/re2c
RE2C_FLAGS = --reusable --tags --no-generation-date --no-version -i
CXXFLAGS = $(AM_CXXFLAGS) -O3 -g -I $(SRC_DIR) -Wall -Wno-unused-const-variable
LDFLAGS = -lbenchmark -lpthread
BENCHMARKS = \
lex_00__numbers1 \
lex_01__numbers2 \
lex_02__words1 \
lex_03__words2 \
lex_04__words3 \
\
submatch_00__http_rfc7230 \
submatch_01__http_simple \
submatch_02__uri_rfc3986 \
submatch_03__uri_simple \
submatch_04__apache_log \
submatch_05__datetime \
submatch_06__email \
submatch_07__ipv4 \
\
submatch_10__alt1_2 \
submatch_11__alt1_4 \
submatch_12__alt1_8 \
submatch_13__alt2_2 \
submatch_14__alt2_4 \
submatch_15__alt2_8 \
submatch_16__alt4_2 \
submatch_17__alt4_4 \
submatch_18__alt4_8 \
\
submatch_20__cat2_0 \
submatch_21__cat2_4 \
submatch_22__cat2_8 \
submatch_23__cat4_0 \
submatch_24__cat4_2 \
submatch_25__cat4_4 \
submatch_26__cat8_0 \
submatch_27__cat8_1 \
submatch_28__cat8_2 \
\
submatch_30__rep_cat_5_3_2 \
submatch_31__rep_cat_13_11_7 \
submatch_32__rep_cat_23_19_17 \
submatch_33__rep_alt_5_3_2 \
submatch_34__rep_alt_13_11_7 \
submatch_35__rep_alt_23_19_17 \
submatch_36__rep_5_rep_3_rep_2 \
submatch_37__rep_13_rep_11_rep_7 \
submatch_38__rep_23_rep_19_rep_17
COMMON_SRC = $(SRC_DIR)/common.h
COMMON_RAGEL = \
$(COMMON_SRC) \
$(SRC_DIR)/ragel/base.h
COMMON_RE2C = \
$(COMMON_SRC) \
$(SRC_DIR)/re2c/base.re \
$(SRC_DIR)/re2c/base.h
GEN_RAGEL = $(patsubst %, $(GEN_DIR)/ragel/%.cc, $(BENCHMARKS))
GEN_RE2C = $(patsubst %, $(GEN_DIR)/re2c/%.cc, $(BENCHMARKS))
GEN = $(GEN_RAGEL) $(GEN_RE2C)
SRC = $(GEN_RAGEL) $(GEN_RE2C)
OBJ_GCC = $(patsubst %.cc, %-gcc.o, $(SRC))
OBJ_CLANG = $(patsubst %.cc, %-clang.o, $(SRC))
OBJ_TEST = $(patsubst %.cc, %-test.o, $(SRC))
OBJ = $(OBJ_GCC) $(OBJ_CLANG) $(OBJ_TEST)
# Some benchmarks share the same data, like 03__uri_simple and 02__uri_rfc3986.
DAT = $(patsubst %, $(DAT_DIR)/%/big, \
$(sort $(foreach bench, $(BENCHMARKS), \
$(word 3, $(subst _, , $(bench))))))
$(DAT): $(DAT_DIR)/%/big: $(srcdir)/../_data/%/small
$(AM_V_at)mkdir -p $(@D) && cp $< $(@D)
$(AM_V_GEN)( cd $(@D) && ../../$(srcdir)/../_data/gen.py )
all-local: bench-gcc bench-clang test $(DAT)
# compile
$(OBJ_GCC): %-gcc.o: %.cc
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)g++ $(CXXFLAGS) -c -o $@ $<
$(OBJ_CLANG): %-clang.o: %.cc
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)clang++ $(CXXFLAGS) -c -o $@ $<
$(OBJ_TEST): %-test.o: %.cc
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)g++ $(CXXFLAGS) -DRUN_IN_TEST_MODE -c -o $@ $<
bench-gcc: src/bench.cc $(OBJ_GCC)
$(AM_V_GEN)g++ -DCXX=\"gcc\" -o $@ $^ $(CXXFLAGS) $(LDFLAGS)
bench-clang: src/bench.cc $(OBJ_CLANG)
$(AM_V_GEN)clang++ -DCXX=\"clang\" -o $@ $^ $(CXXFLAGS) $(LDFLAGS)
test: src/test.cc $(OBJ_TEST)
$(AM_V_GEN)g++ -DRUN_IN_TEST_MODE -o $@ $^ $(CXXFLAGS) $(LDFLAGS)
# always regenerate re2c benchmarks (except for deprecated algorithms)
$(GEN_RE2C): $(GEN_DIR)/%.cc: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS) $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
# optionally regenerate other benchmarks
if REGEN_BENCHMARKS
$(GEN_RAGEL): $(GEN_DIR)/%.cc: $(SRC_DIR)/%.rl $(COMMON_RAGEL) $(RAGEL)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RAGEL) -G2 $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/ragel/$(@F) ; then cp -f $@ $(PREGEN_DIR)/ragel/$(@F) ; fi
else
$(GEN_RAGEL) $(GEN_DIR)/%: $(PREGEN_DIR)/%
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)cp -f $< $@
endif
# engines
$(RAGEL):
$(AM_V_at)mkdir -p $(@D) && cp $(srcdir)/../_engines/ragel/getragel7.sh $(@D)
$(AM_V_GEN)( cd $(@D) && ./getragel7.sh )
# clean
clean-local:
rm -f $(GEN) $(OBJ) $(DAT) bench-gcc bench-clang test
@@ -1,6 +1,6 @@
#include <string.h>
#include "benchmarks/common/common.h"
#include "benchmarks/c/common/common.h"
#include "lib/regex.h"
#ifdef HAVE_RE2_RE2_H
+136
View File
@@ -0,0 +1,136 @@
#ifndef _RE2C_BENCHMRKS_COMMON_COMMON_
#define _RE2C_BENCHMRKS_COMMON_COMMON_
#include <benchmark/benchmark.h>
#include <string>
#include <vector>
#include <stdint.h>
enum engine_t {
ENGINE_RE2C,
ENGINE_RE2
};
struct alg_t {
const char *name;
engine_t engine;
int flags;
};
struct bench_t {
const char *name;
const char *regexp;
const char **strings;
};
// Need to define benchmarks as functors for benchmark::RegisterBenchmark.
struct bench_regcomp_t {
void operator()(benchmark::State&, const alg_t&, const bench_t&) const;
};
struct bench_regexec_t {
void operator()(benchmark::State&, const alg_t&, const bench_t&) const;
};
// RFC URI and HTTP
#define CRLF "[\\n]"
#define OCT "([0-9]|[1-9][0-9]|[1][0-9]{2}|[2][0-4][0-9]|[2][5][0-5])"
#define IPV4 "(" OCT "[.]" OCT "[.]" OCT "[.]" OCT ")"
#define H16 "[0-9a-fA-F]{1,4}"
#define LS32 "(" H16 ":" H16 "|" IPV4 ")"
#define IPV6 "((" H16 ":){6}" LS32 \
"|" "::(" H16 ":){5}" LS32 \
"|(" H16 ")?::(" H16 ":){4}" LS32 \
"|((" H16 ":){0,1}" H16 ")?::(" H16 ":){3}" LS32 \
"|((" H16 ":){0,2}" H16 ")?::(" H16 ":){2}" LS32 \
"|((" H16 ":){0,3}" H16 ")?::" H16 ":" LS32 \
"|((" H16 ":){0,4}" H16 ")?::" LS32 \
"|((" H16 ":){0,5}" H16 ")?::" H16 \
"|((" H16 ":){0,6}" H16 ")?::)"
#define IPVFUTURE "(v[0-9a-fA-F]+[.][-0-9a-zA-Z._~!$&'()*+,;=:]+)"
#define IPLITERAL "([[](" IPV6 "|" IPVFUTURE ")[\\]])"
#define REGNAME "(([-0-9a-zA-Z._~!$&'()*+,;=]|%[0-9a-fA-F]{2})*)"
#define HOST "(" IPLITERAL "|" IPV4 "|" REGNAME ")"
#define PORT "(:[0-9]*)?"
#define USERINFO "(([-a-zA-Z0-9._~!$&'()*+,;=:]|%[0-9a-fA-F]{2})*@)?"
#define SCHEME "([a-zA-Z][a-zA-Z0-9+.-]*):"
#define QUERY "([?]([-a-zA-Z0-9._~!$&'()*+,;=:@/?]|%[0-9a-fA-F]{2})*)?"
#define FRAGMENT "([#]([-a-zA-Z0-9._~!$&'()*+,;=:@/?]|%[0-9a-fA-F]{2})*)?"
#define PCHAR "([-0-9a-zA-Z._~!$&'()*+,;=:@]|%[0-9a-fA-F]{2})"
#define PATH_ABEMPTY "(/" PCHAR "*)*"
#define PATH_ABSOLUTE "/(" PCHAR "+(/" PCHAR "*)*)?"
#define PATH_ROOTLESS PCHAR "+(/" PCHAR "*)*"
#define PATH_EMPTY "([/]?)"
#define AUTHORITY "(" USERINFO HOST PORT ")"
#define HIER_PART "(//" AUTHORITY PATH_ABEMPTY "|" PATH_ABSOLUTE "|" PATH_ROOTLESS "|" PATH_EMPTY ")"
#define URI SCHEME HIER_PART QUERY FRAGMENT
#define ABSOLUTE_URI SCHEME HIER_PART QUERY
#define ORIGIN_FROM PATH_ABEMPTY QUERY
#define REQUEST_TARGET "(" AUTHORITY "|" ABSOLUTE_URI "|" ORIGIN_FROM "|([*]))"
#define METHOD "([-!#$%&'*+.^_`|~0-9a-zA-Z]+)"
#define HTTP_VERSION "(HTTP/[0-9][.][0-9])"
#define STATUS_CODE "([0-9]{3})"
#define REASON_PHRASE "([ \\t \\x1f-\\x7e\\x80-\\xff]*)"
#define REQUEST_LINE METHOD "[ ]" REQUEST_TARGET "[ ]" HTTP_VERSION CRLF
#define STATUS_LINE HTTP_VERSION "[ ]" STATUS_CODE "[ ]" REASON_PHRASE CRLF
#define FIELD_NAME "([-!#$%&'*+.^_`|~0-9a-zA-Z]+)"
#define FIELD_VCHAR "[\\x1f-\\x7e\\x80-\\xff]"
#define FIELD_CONTENT "(" FIELD_VCHAR "([ \\t]+" FIELD_VCHAR")?)"
#define FIELD_VALUE "(" FIELD_CONTENT "|" CRLF "[ \\t]+)*"
#define HEADER_FIELD "(" FIELD_NAME ":[ \\t]*" FIELD_VALUE "[ \\t]*)"
#define MESSAGE_HEAD "(" REQUEST_LINE "|" STATUS_LINE ")" "(" HEADER_FIELD CRLF ")*"
// simplified URI and HTTP
#define CHAR2 "[-._~%!$&'()*+,;=a-zA-Z0-9]"
#define SCHEME2 "([-+.a-zA-Z0-9]+):"
#define USERINFO2 "((" CHAR2 "|[:])+@)?"
#define HOST2 "((" CHAR2 "|[:[\\]])+)"
#define PORT2 "(:[0-9]*)?"
#define AUTHORITY2 USERINFO2 HOST2 PORT2
#define PATH2 "((" CHAR2 "|[:@/])*)"
#define QUERY2 "([?](" CHAR2 "|[:@?/])*)?"
#define FRAGMENT2 "([#](" CHAR2 "|[:@?/])*)?"
#define URI2 SCHEME2 "(//" AUTHORITY2 ")?" PATH2 QUERY2 FRAGMENT2
#define ABSOLUTE_URI2 SCHEME2 "(//" AUTHORITY2 PORT2 ")?" PATH2 QUERY2
#define ORIGIN_FROM2 "/" PATH2 QUERY2
#define REQUEST_TARGET2 "(" AUTHORITY2 "|" ABSOLUTE_URI2 "|" ORIGIN_FROM2 "|[*])"
#define HTTP_VERSION2 "(HTTP/[0-9][.][0-9])"
#define METHOD2 "([-._~%!$&'*+#^`|a-zA-Z0-9]+)"
#define REQUEST_LINE2 "(" METHOD2 "[ ]" REQUEST_TARGET2 "[ ]" HTTP_VERSION2 CRLF ")"
#define STATUS_LINE2 "(" HTTP_VERSION2 "[ ]([0-9]{3})[ ]([\\t \\x1f-\\x7e\\x80-\\xff]*)" CRLF ")"
#define HEADER_FIELD2 "([-._~%!$&'*+#^`|a-zA-Z0-9]+:[\\x1f-\\x7e\\x80-\\xff \\t\\n]*)"
#define MESSAGE_HEAD2 "(" REQUEST_LINE2 "|" STATUS_LINE2 ")" "(" HEADER_FIELD2 CRLF ")*"
// simplified IPv6
#define IPV62 "(((" H16 ":){0,7}" H16 ")?(::)?((" H16 ":){0,7}" H16 ")?)"
// simplified IPv4
#define IPV42 "([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})"
// date
#define DATE "(Mon|Tue|Wed|Thu|Fri|Sat|Sun)" \
"[ ]+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)" \
"[ ]+([0-9]{2})" \
"[ ]+([0-9]{4})" \
"[ ]+([0-9]{2}):([0-5][0-9]):[0-5][0-9](-[0-5][0-9])?(:[0-5][0-9])?" \
"[ ]+(([A-Z]{3})([+-]([0-5][0-9]):([0-5][0-9]))?)"
// simplified date
#define DATE2 "([a-zA-Z]+)[ ]+([a-zA-Z]+)[ ]+([0-9]+)[ ]+([0-9]+)[ ]+([0-9:-]+)[ ]+([A-Z0-9+-]+)"
// Gentoo package atom
#define PACKAGE_STR "([a-zA-Z0-9_+-]+)"
#define PACKAGE_NUM "([0-9]+)"
#define PACKAGE_VER "(" PACKAGE_NUM "([.]" PACKAGE_NUM ")*)"
#define PACKAGE_SFX1 "([a-z])?"
#define PACKAGE_SFX2 "((alpha|beta|pre|rc|p)" PACKAGE_NUM "?)"
#define PACKAGE_REV "(-r" PACKAGE_NUM ")?"
#define PACKAGE_ATOM PACKAGE_STR "/" PACKAGE_STR "-" PACKAGE_VER PACKAGE_SFX1 "(_" PACKAGE_SFX2 ")*" PACKAGE_REV
// simplified Gentoo package atom
#define PACKAGE_STR2 "([a-zA-Z0-9_/+-]+)"
#define PACKAGE_VER2 "([0-9.a-z_]+)"
#define PACKAGE_ATOM2 PACKAGE_STR2 "-" PACKAGE_VER2 PACKAGE_REV
#endif // _RE2C_BENCHMRKS_COMMON_COMMON_
@@ -15016,10 +15016,6 @@ for (int a = 0; a < reTest.length; a++){
tex.printf("\\usepackage{amsmath, amssymb, amsfonts}\n");
tex.printf("\\usepackage{tikz, pgfplots, pgfplotstable}\n");
tex.printf("\n");
tex.printf("\\usepackage{comicneue}\n");
tex.printf("\\usepackage[T1]{fontenc}\n");
tex.printf("\\renewcommand{\\familydefault}{\\sfdefault}\n");
tex.printf("\n");
tex.printf("\\begin{document}\n");
tex.printf("\n");
tex.printf("\\pgfplotstableread {\n");
@@ -15044,12 +15040,13 @@ for (int a = 0; a < reTest.length; a++){
tex.printf(" legend cell align = left,\n");
tex.printf(" legend style = {thick, draw = none},\n");
tex.printf(" xlabel = regular expression size (characters),\n");
tex.printf(" ylabel = parse speed (characters per second)\n");
tex.printf(" ylabel = parse speed (characters per second),\n");
tex.printf(" width = 5in\n");
tex.printf("]\n");
String[] row0 = plot.get(0);
for (int i = 1; i < row0.length; i++){
String name = algolabels[i-1].split("\\|")[0];
tex.printf("\\addplot [color=%s] table [x index=0, y index=%s] from \\datatable;\n",
tex.printf("\\addplot [line width=0.7pt, color=%s] table [x index=0, y index=%s] from \\datatable;\n",
tex_colors[i - 1], i);
tex.printf("\\addlegendentry{%s}\n", name);
}
@@ -16314,41 +16311,41 @@ this.finreg = false;
};
ReTdfa[] rearrDPO = new ReTdfa[]{
new ReTdfa("DPOR", "negtags,posix,transtable,lookahead,okui,altbin,offsets,lastval"),
new ReTdfa("DPOL", "negtags,posix,transtable,lookahead,okui,altbin,offsets,lastval,tagless"),
new ReTdfa("DPOR-re2c", "re2c"),
new ReTdfa("DPOL-re2c", "re2c,re2c_regless"),
new ReTdfa("last-offset-java", "negtags,posix,transtable,lookahead,okui,altbin,offsets,lastval"),
new ReTdfa("last-offset-multipass-java", "negtags,posix,transtable,lookahead,okui,altbin,offsets,lastval,tagless"),
new ReTdfa("last-offset-re2c", "re2c"),
new ReTdfa("last-offset-multipass-re2c", "re2c,re2c_regless"),
};
ReTdfa[] rearrDPH = new ReTdfa[]{
new ReTdfa("DPHR", "negtags,posix,transtable,lookahead,okui,altbin,finreg"),
new ReTdfa("DPHL", "negtags,posix,transtable,lookahead,okui,altbin,finreg,tagless"),
new ReTdfa("DPHR-re2c", "re2c,re2c_subhist"),
new ReTdfa("DPHL-re2c", "re2c,re2c_subhist,re2c_regless"),
new ReTdfa("all-offsets-java", "negtags,posix,transtable,lookahead,okui,altbin,finreg"),
new ReTdfa("all-offsets-multipass-java", "negtags,posix,transtable,lookahead,okui,altbin,finreg,tagless"),
new ReTdfa("all-offsets-re2c", "re2c,re2c_subhist"),
new ReTdfa("all-offsets-multipass-re2c", "re2c,re2c_subhist,re2c_regless"),
};
ReTdfa[] rearrDPT = new ReTdfa[]{
new ReTdfa("DPTL", "negtags,posix,transtable,lookahead,okui,altbin,matchTstring,tagless"),
new ReTdfa("DPTL-re2c", "re2c,re2c_tstring,re2c_regless"),
new ReTdfa("tagged-string-multipass-java", "negtags,posix,transtable,lookahead,okui,altbin,matchTstring,tagless"),
new ReTdfa("tagged-string-multipass-re2c", "re2c,re2c_tstring,re2c_regless"),
};
ReTdfa[] rearrDFO = new ReTdfa[]{
new ReTdfa("DFOR", "negtags,posix,transtable,lookahead,okui,altbin,autotags,offsets,lastval"),
new ReTdfa("DFOL", "negtags,posix,transtable,lookahead,okui,altbin,autotags,offsets,lastval,tagless"),
new ReTdfa("DFOR-re2c", "re2c,re2c_autotags"),
new ReTdfa("DFOL-re2c", "re2c,re2c_autotags,re2c_regless"),
new ReTdfa("last-offset-java", "negtags,posix,transtable,lookahead,okui,altbin,autotags,offsets,lastval"),
new ReTdfa("last-offset-multipass-java", "negtags,posix,transtable,lookahead,okui,altbin,autotags,offsets,lastval,tagless"),
new ReTdfa("last-offset-re2c", "re2c,re2c_autotags"),
new ReTdfa("last-offset-multipass-re2c", "re2c,re2c_autotags,re2c_regless"),
};
ReTdfa[] rearrDFH = new ReTdfa[]{
new ReTdfa("DFHR", "negtags,posix,transtable,lookahead,okui,altbin,autotags,finreg"),
new ReTdfa("DFHL", "negtags,posix,transtable,lookahead,okui,altbin,autotags,finreg,tagless"),
new ReTdfa("DFHR-re2c", "re2c,re2c_autotags,re2c_subhist"),
new ReTdfa("DFHL-re2c", "re2c,re2c_autotags,re2c_subhist,re2c_regless"),
new ReTdfa("all-offsets-java", "negtags,posix,transtable,lookahead,okui,altbin,autotags,finreg"),
new ReTdfa("all-offsets-multipass-java", "negtags,posix,transtable,lookahead,okui,altbin,autotags,finreg,tagless"),
new ReTdfa("all-offsets-re2c", "re2c,re2c_autotags,re2c_subhist"),
new ReTdfa("all-offsets-multipass-re2c", "re2c,re2c_autotags,re2c_subhist,re2c_regless"),
};
ReTdfa[] rearrDFT = new ReTdfa[]{
new ReTdfa("DFTL", "negtags,posix,transtable,lookahead,okui,autotags,altbin,matchTstring,tagless"),
new ReTdfa("DFTL-re2c", "re2c,re2c_autotags,re2c_tstring,re2c_regless"),
new ReTdfa("tagged-string-multipass-java", "negtags,posix,transtable,lookahead,okui,autotags,altbin,matchTstring,tagless"),
new ReTdfa("tagged-string-multipass-re2c", "re2c,re2c_autotags,re2c_tstring,re2c_regless"),
};
ReTdfa[] rearrDP = concatArrays(rearrDPO, concatArrays(rearrDPH, rearrDPT));
@@ -16361,8 +16358,8 @@ this.finreg = false;
//bench(rearrDFO, "measure_DFO.ser", "chart_DFO.html");
//bench(rearrDFH, "measure_DFH.ser", "chart_DFH.html");
//bench(rearrDFT, "measure_DFT.ser", "chart_DFT.html");
bench(rearrDP, "measure_DP.ser", "chart_DP.html");
bench(rearrDF, "measure_DF.ser", "chart_DF.html");
bench(rearrDP, "measure_sparse.ser", "chart_sparse.html");
bench(rearrDF, "measure_dense.ser", "chart_dense.html");
if (testErrors > 0){
System.out.printf("end test %s tests failed\n",testErrors);
@@ -11,7 +11,7 @@ JNIEXPORT jlong JNICALL Java_re2c_RE2C_regcomp(JNIEnv *env, jclass, jstring patt
if (c_pattern == NULL) return 1;
const int flags = (nfa ? REG_NFA : 0)
| (regless ? REG_REGLESS : 0)
| (regless ? REG_MULTIPASS : 0)
| (subhist ? REG_SUBHIST : 0)
| (tstring ? REG_TSTRING : 0)
| (autotags ? REG_AUTOTAGS : 0);
@@ -0,0 +1,6 @@
The measurements have been taken on an Intel(R) Core(TM) i7-8750H CPU with
32 KiB L1 Data cache (x6 cores),
32 KiB L1 Instruction cache (x6 cores),
256 KiB L2 Unified cache (x6 cores),
9216 KiB L3 Unified cache,
32 GiB RAM.
@@ -0,0 +1,106 @@
\documentclass[tikz]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{amsmath, amssymb, amsfonts}
\usepackage{tikz, pgfplots, pgfplotstable}
\begin{document}
\pgfplotstableread {
18.00 64067.60 42946.34 182933.76 105057.40 6229.27 22180.86 26243.90 32994.76 73211.37 97660.34
19.00 62548.54 42164.01 178722.37 103400.35 5770.58 20847.07 23890.54 30599.08 73046.09 97387.81
20.00 60048.83 40443.29 171833.91 100612.70 5015.70 18897.54 21808.86 28312.46 72539.33 96542.90
22.00 57079.79 38515.24 159793.27 96907.26 4217.08 16900.47 19528.35 25703.02 72258.85 95088.91
23.00 54436.63 36775.10 147812.44 93065.74 3584.12 15030.44 17188.28 22920.65 71393.41 94080.62
24.00 52415.17 35525.41 138862.51 90118.03 3143.60 13812.73 15617.56 21128.39 70804.77 93103.91
25.00 50851.49 34423.06 131785.43 88851.06 2671.71 12209.55 13325.01 18396.98 70234.27 92666.51
26.00 49875.77 33780.79 125493.62 87792.96 2410.59 11148.35 11685.93 16473.76 69745.11 92356.24
27.00 49120.55 33395.10 120200.73 86274.06 2395.18 11243.06 11809.34 16687.19 68995.42 92307.63
28.00 48941.82 33446.25 119836.68 86694.70 2445.77 11597.05 12206.75 17403.04 68681.69 92504.90
29.00 47242.85 32428.99 112650.91 84709.63 2194.40 10686.36 11067.65 16096.81 68017.29 92522.99
30.00 46547.71 31908.05 106896.82 83234.19 2060.92 10322.06 10615.28 15596.19 67661.79 92201.19
31.00 44746.78 30761.95 96590.88 79863.36 1893.17 9583.53 9831.02 14350.11 66572.29 90726.62
32.00 43436.08 30015.85 89575.18 77760.96 1782.59 9124.68 9183.95 13631.79 65740.34 89967.07
33.00 42483.05 29415.64 87542.50 76519.29 1692.18 8776.04 8789.94 13070.47 65460.19 89770.30
34.00 41734.65 28869.28 84681.78 74992.78 1605.51 8386.69 8342.75 12501.38 64854.47 88944.96
35.00 41119.13 28632.57 81703.60 74722.48 1497.51 7894.08 7611.52 11732.78 64085.34 88243.59
36.00 40704.36 28343.84 80300.17 73822.50 1498.01 7896.33 7613.06 11860.52 63595.18 87867.33
37.00 40065.40 27844.84 76968.74 72293.78 1406.94 7636.42 7447.81 11603.40 62937.90 86801.18
38.00 39294.27 27215.83 70966.47 70686.86 1350.01 7207.91 6881.68 10919.70 62590.66 85851.13
39.00 39098.45 27083.52 69155.33 69889.97 1321.95 7020.93 6731.99 10696.01 62042.75 85317.37
40.00 38196.73 26541.44 65568.32 68152.49 1265.99 6765.98 6426.98 10195.64 61179.72 83724.00
41.00 36471.62 25422.34 58940.92 65249.09 1184.08 6302.20 5953.32 9435.59 59935.34 81613.14
42.00 36716.62 25509.28 59561.80 65702.64 1216.76 6537.99 6220.15 10002.22 59544.22 80900.90
43.00 36617.92 25273.60 58865.21 65134.54 1226.27 6529.91 6198.52 9889.73 59192.09 80493.85
44.00 36150.33 24864.28 57058.67 64057.84 1183.46 6377.57 6040.99 9666.42 58676.93 79926.59
45.00 36182.35 24996.13 56715.01 64209.18 1188.66 6421.67 6135.37 9821.71 58395.16 79381.75
46.00 36443.85 24884.45 55786.43 63845.59 1149.77 6162.49 5895.39 9357.53 58500.98 79228.39
47.00 36058.47 24419.19 51646.99 63004.55 1095.61 5929.20 5597.65 8944.25 58246.49 79276.10
48.00 34956.31 23801.95 48932.21 61693.23 1011.48 5500.96 5029.95 8140.69 58036.83 79196.46
49.00 34277.03 23629.45 48088.23 60894.19 1018.97 5582.97 5111.21 8275.08 57724.55 78635.00
50.00 33246.76 22945.42 44546.84 59595.18 905.60 5086.73 4571.06 7410.58 57668.88 78301.40
51.00 33773.89 23190.66 44321.00 60535.16 885.48 5039.04 4540.15 7393.76 58323.35 78631.12
52.00 33337.63 22958.67 43083.19 59922.10 837.92 4822.92 4253.07 6963.98 58365.64 79467.41
53.00 32602.41 22650.08 41747.10 58711.50 791.56 4606.34 4051.73 6618.74 58248.54 79207.90
54.00 32021.90 22488.91 40203.96 58074.90 754.94 4415.61 3850.97 6310.81 58131.37 78549.87
55.00 32799.74 23152.05 41538.58 59410.15 784.08 4529.31 3842.67 6473.81 58196.56 78239.61
56.00 32629.68 23110.97 41488.36 59501.76 802.40 4536.56 3809.06 6459.95 58417.71 78993.91
57.00 31385.48 22496.83 39347.65 57967.45 770.21 4412.27 3698.44 6297.75 57922.23 78275.11
58.00 30680.96 22559.73 38096.34 57409.70 737.30 4230.11 3533.81 6005.96 57943.76 76944.89
59.00 31446.28 22839.60 38096.15 58277.81 764.03 4460.26 3814.62 6475.04 58093.17 77455.98
60.00 31067.82 22715.31 36172.22 58136.03 710.39 4153.83 3474.16 5924.73 58263.23 77761.50
61.00 30689.92 22441.92 34874.99 57353.23 687.94 4077.04 3382.82 5816.85 58186.13 77640.38
62.00 29916.43 21939.89 33817.99 55758.16 670.90 3927.07 3205.77 5512.63 57187.21 76937.32
63.00 29961.36 22164.15 34131.52 56447.34 675.59 4023.28 3295.78 5712.03 56930.67 75941.26
64.00 29651.76 21915.98 32842.30 55660.78 653.84 3903.05 3130.16 5402.50 56589.14 75840.17
65.00 30096.51 22293.16 32886.52 56660.89 638.10 3854.69 3132.62 5413.33 57112.42 76597.87
66.00 29546.36 21925.33 31172.53 56137.56 598.51 3639.77 2962.22 5056.47 57237.38 77300.51
67.00 29489.32 21914.59 30122.63 56272.61 565.86 3527.39 2817.11 4902.97 57319.13 77385.28
68.00 29519.33 22149.89 29778.41 57078.95 555.96 3494.03 2781.40 4838.88 57562.13 77899.66
69.00 29268.33 21855.40 30071.74 56633.31 558.78 3599.36 2866.62 4978.05 57774.46 78687.77
70.00 28712.40 22026.22 28757.99 56817.35 531.88 3404.62 2636.81 4696.89 57994.28 78935.42
71.00 28623.79 22021.90 27828.04 56346.02 532.71 3342.18 2634.22 4652.04 57881.34 78591.40
72.00 28453.65 22009.10 27358.01 56227.07 520.55 3267.49 2594.98 4545.64 57973.20 79095.49
73.00 27926.89 21898.66 26803.92 56104.33 509.09 3215.34 2526.01 4466.13 58263.83 79606.04
74.00 27890.34 21796.17 25780.69 55701.50 485.78 3056.41 2365.57 4181.06 58783.30 80228.20
75.00 27771.84 21793.06 24647.71 56153.07 468.49 2962.53 2286.49 4052.66 58865.13 80711.66
} \datatable
\begin{tikzpicture}
\begin{axis} [
font=\scriptsize,
scaled y ticks = false,
y tick label style = {/pgf/number format/.cd,fixed,1000 sep = {\,}},
ymajorgrids,
grid style={line width=.1pt, draw=gray!20},
legend pos=outer north east,
legend cell align = left,
legend style = {thick, draw = none},
xlabel = regular expression size (characters),
ylabel = parse speed (characters per second),
width = 5in
]
\addplot [line width=0.7pt, color=violet] table [x index=0, y index=1] from \datatable;
\addlegendentry{last-offset-java}
\addplot [line width=0.7pt, color=teal] table [x index=0, y index=2] from \datatable;
\addlegendentry{last-offset-multipass-java}
\addplot [line width=0.7pt, color=blue] table [x index=0, y index=3] from \datatable;
\addlegendentry{last-offset-re2c}
\addplot [line width=0.7pt, color=cyan] table [x index=0, y index=4] from \datatable;
\addlegendentry{last-offset-multipass-re2c}
\addplot [line width=0.7pt, color=lightgray] table [x index=0, y index=5] from \datatable;
\addlegendentry{all-offsets-java}
\addplot [line width=0.7pt, color=pink] table [x index=0, y index=6] from \datatable;
\addlegendentry{all-offsets-multipass-java}
\addplot [line width=0.7pt, color=gray] table [x index=0, y index=7] from \datatable;
\addlegendentry{all-offsets-re2c}
\addplot [line width=0.7pt, color=purple] table [x index=0, y index=8] from \datatable;
\addlegendentry{all-offsets-multipass-re2c}
\addplot [line width=0.7pt, color=orange] table [x index=0, y index=9] from \datatable;
\addlegendentry{tagged-string-multipass-java}
\addplot [line width=0.7pt, color=olive] table [x index=0, y index=10] from \datatable;
\addlegendentry{tagged-string-multipass-re2c}
\end{axis}
\end{tikzpicture}
\end{document}
@@ -0,0 +1,106 @@
\documentclass[tikz]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{amsmath, amssymb, amsfonts}
\usepackage{tikz, pgfplots, pgfplotstable}
\begin{document}
\pgfplotstableread {
18.00 77594.81 51424.59 202781.71 122255.25 13391.78 32436.12 93838.33 65352.91 81385.82 100029.52
19.00 73778.38 49193.48 201226.52 119932.12 12427.55 30789.67 90207.09 62057.45 80696.01 100001.57
20.00 68598.33 45313.31 199038.73 116879.33 9779.37 27609.39 83788.03 57103.94 78705.31 99578.88
22.00 62094.95 40611.16 195320.45 112322.17 6817.72 23787.60 76318.91 51559.50 76104.81 98604.00
23.00 59685.51 38868.61 193951.49 110531.28 6054.46 22321.52 71496.68 49149.24 75141.38 98153.73
24.00 57919.84 37570.77 193959.47 108887.92 5566.88 21339.09 68563.67 47238.86 74504.28 97825.43
25.00 54729.44 35519.66 190951.64 108377.86 5081.34 19948.73 64985.29 44812.02 74510.63 98446.81
26.00 53889.17 35043.71 190534.09 108943.25 4974.79 19575.42 64173.63 44156.63 74396.88 98868.71
27.00 53972.18 34940.15 189604.95 109075.69 4991.53 19685.01 64533.47 43911.21 74026.11 98884.19
28.00 51677.15 34148.21 189807.01 107070.06 4696.17 19200.68 64421.79 42800.69 73770.16 98203.95
29.00 50981.66 33481.24 190440.69 107817.52 4562.04 18797.15 62962.60 42641.34 73677.70 98734.47
30.00 51012.97 33422.60 189987.41 107898.59 4529.17 18755.21 63182.28 42456.92 73693.00 99013.87
31.00 51447.73 33418.47 189874.71 107319.28 4591.04 18760.34 62872.03 42570.92 73412.16 98292.07
32.00 49959.28 32571.09 188258.74 106806.76 4433.92 18287.30 61437.20 41966.99 73167.12 98076.14
33.00 50491.42 32701.29 190458.88 108591.88 4477.34 18392.31 61445.25 42367.95 73623.08 98717.22
34.00 48137.78 31388.15 189331.30 106272.84 4180.48 17615.45 60073.29 40638.50 73377.88 98514.42
35.00 45720.16 29940.55 186112.45 104916.90 3912.74 16692.92 57813.18 39078.92 73049.46 97983.58
36.00 46016.79 30211.96 188227.09 104823.62 3899.43 16829.86 57644.40 38966.99 73057.45 97444.05
37.00 44640.77 29459.22 185966.34 103308.30 3716.86 16393.91 56824.13 37809.63 72736.91 96742.83
38.00 43829.60 28951.22 183638.55 101928.33 3647.35 16089.67 55640.13 37301.34 72416.42 96497.18
39.00 42651.68 28023.83 181633.84 100526.99 3555.32 15554.73 55565.79 36234.74 72133.25 95956.64
40.00 42129.18 27689.50 180641.57 100440.26 3530.57 15331.44 54898.74 35680.42 72197.65 95892.56
41.00 39529.78 26071.10 178680.81 98367.20 3226.95 14368.76 52840.98 33779.61 72026.62 95236.18
42.00 38479.04 25783.16 175481.55 97117.73 3080.63 14178.11 51951.28 33288.53 71565.33 94697.91
43.00 37676.67 25394.52 175021.87 95720.28 3011.24 13943.19 51921.41 32659.88 71336.49 94472.22
44.00 34991.38 23959.28 171886.62 92252.57 2722.21 13049.85 50259.07 30741.44 70568.38 93669.95
45.00 34165.65 23466.72 167800.34 92487.25 2649.59 12798.30 49300.31 30303.29 70227.83 93100.29
46.00 33444.64 23021.17 166785.14 92211.05 2580.73 12572.76 48848.65 29502.10 70192.46 93003.41
47.00 32778.35 22557.57 165867.30 91204.14 2492.84 12348.95 48376.54 29257.43 69917.55 93233.97
48.00 30710.59 21224.27 163747.55 89474.47 2288.47 11559.17 45756.85 27451.26 69872.49 93616.63
49.00 30324.96 21033.06 164086.33 89333.25 2226.44 11408.11 45953.43 26927.54 70033.38 93211.68
50.00 28961.94 20121.55 160111.62 89202.28 2086.82 10857.46 43798.37 25714.91 70106.27 93359.73
51.00 26563.74 18913.19 156965.70 86824.70 1806.15 10099.12 42250.25 24145.96 69544.12 92530.46
52.00 25153.97 18001.19 155564.89 85211.96 1701.37 9590.67 41862.18 23304.04 69182.62 92466.66
53.00 24519.40 17616.96 157148.12 85449.94 1626.37 9394.67 41858.09 23036.94 69662.26 93046.68
54.00 23643.88 17041.50 153919.71 84191.72 1544.42 9050.56 40971.95 22059.34 69320.06 92749.13
55.00 23756.97 17317.91 153586.07 85154.63 1594.03 9204.95 41451.99 22432.80 69675.14 92794.70
56.00 23600.84 17188.94 153292.10 84890.03 1605.10 9092.85 40942.48 22245.50 69874.46 93139.78
57.00 22912.77 16765.70 150786.18 83578.35 1546.94 8824.80 39671.36 21687.28 69677.13 93162.14
58.00 21559.32 15878.42 146909.50 82843.64 1464.39 8289.27 37967.48 20343.59 69615.87 92659.51
59.00 22147.44 16445.21 146336.19 83638.61 1508.75 8616.36 38782.21 21180.32 69974.59 92477.79
60.00 20734.23 15351.76 140006.00 82554.20 1434.14 8051.80 36922.29 20012.74 69406.74 92080.61
61.00 19910.09 14976.77 138024.46 81202.11 1364.36 7830.45 35802.78 19454.87 68954.08 92110.22
62.00 19640.55 14788.54 136548.53 80166.50 1344.14 7735.37 35390.46 19260.55 68659.56 92354.74
63.00 20450.27 15466.44 136567.18 81901.54 1413.37 8108.19 34691.18 19770.11 68869.02 92408.59
64.00 18977.32 14357.22 132431.47 81476.92 1308.58 7475.16 32965.95 18143.17 68931.05 92649.27
65.00 18483.82 13970.31 131639.73 83849.35 1266.76 7253.87 32134.77 17812.73 69666.02 93113.23
66.00 17575.93 13269.76 128523.85 82949.61 1181.90 6852.48 30312.31 16878.36 69540.52 92648.37
67.00 17025.49 13024.66 126292.89 81863.68 1138.11 6701.23 30092.51 16573.23 69375.29 92351.89
68.00 17636.20 13362.69 126077.77 83119.45 1179.52 6910.53 30240.87 16994.03 69604.33 92638.66
69.00 18595.50 14128.87 127252.00 83490.95 1246.90 7332.97 31441.90 18145.91 69592.81 92747.82
70.00 18433.97 13728.82 124454.12 82980.33 1237.80 7112.65 30400.05 17456.83 69126.98 92485.97
71.00 18147.59 13546.32 123926.12 82356.85 1191.15 7003.25 30143.97 17218.75 69088.17 92097.08
72.00 18117.52 13383.66 122834.63 82087.67 1188.82 6933.67 30185.92 17353.59 69053.54 92100.82
73.00 17435.05 12876.20 119406.59 81578.44 1153.69 6660.49 29806.57 16546.17 69154.79 91334.41
74.00 16388.19 12103.48 113225.95 79286.00 1073.92 6257.82 29029.85 15621.33 68518.77 90520.91
75.00 15717.38 11688.79 107030.45 76881.02 1028.43 6038.20 28352.02 15172.25 67457.34 89242.56
} \datatable
\begin{tikzpicture}
\begin{axis} [
font=\scriptsize,
scaled y ticks = false,
y tick label style = {/pgf/number format/.cd,fixed,1000 sep = {\,}},
ymajorgrids,
grid style={line width=.1pt, draw=gray!20},
legend pos=outer north east,
legend cell align = left,
legend style = {thick, draw = none},
xlabel = regular expression size (characters),
ylabel = parse speed (characters per second),
width = 5in
]
\addplot [line width=0.7pt, color=violet] table [x index=0, y index=1] from \datatable;
\addlegendentry{last-offset-java}
\addplot [line width=0.7pt, color=teal] table [x index=0, y index=2] from \datatable;
\addlegendentry{last-offset-multipass-java}
\addplot [line width=0.7pt, color=blue] table [x index=0, y index=3] from \datatable;
\addlegendentry{last-offset-re2c}
\addplot [line width=0.7pt, color=cyan] table [x index=0, y index=4] from \datatable;
\addlegendentry{last-offset-multipass-re2c}
\addplot [line width=0.7pt, color=lightgray] table [x index=0, y index=5] from \datatable;
\addlegendentry{all-offsets-java}
\addplot [line width=0.7pt, color=pink] table [x index=0, y index=6] from \datatable;
\addlegendentry{all-offsets-multipass-java}
\addplot [line width=0.7pt, color=gray] table [x index=0, y index=7] from \datatable;
\addlegendentry{all-offsets-re2c}
\addplot [line width=0.7pt, color=purple] table [x index=0, y index=8] from \datatable;
\addlegendentry{all-offsets-multipass-re2c}
\addplot [line width=0.7pt, color=orange] table [x index=0, y index=9] from \datatable;
\addlegendentry{tagged-string-multipass-java}
\addplot [line width=0.7pt, color=olive] table [x index=0, y index=10] from \datatable;
\addlegendentry{tagged-string-multipass-re2c}
\end{axis}
\end{tikzpicture}
\end{document}
+21
View File
@@ -0,0 +1,21 @@
add_executable(bench_submatch_jit
"bench.cc"
"${CMAKE_SOURCE_DIR}/benchmarks/c/common/common.cc"
)
target_link_libraries(bench_submatch_jit libre2c)
find_package(benchmark REQUIRED)
target_link_libraries(bench_submatch_jit benchmark::benchmark)
# if present, re2 is used for benchmarks
find_path(RE2_INCLUDE_DIRECTORY "re2/re2.h")
find_library(RE2_LIBRARY re2)
if(RE2_INCLUDE_DIRECTORY AND RE2_LIBRARY)
set_target_properties(bench_submatch_jit PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON)
target_compile_definitions(bench_submatch_jit PRIVATE "HAVE_RE2_RE2_H=1")
target_include_directories(bench_submatch_jit PRIVATE "${RE2_INCLUDE_DIRECTORY}")
target_link_libraries(bench_submatch_jit "${RE2_LIBRARY}")
endif()
+17
View File
@@ -0,0 +1,17 @@
bench_submatch_jit_CXXFLAGS = $(AM_CXXFLAGS) -O3 -I $(top_srcdir)
bench_submatch_jit_LDFLAGS = $(LDFLAGS_RE2) -lbenchmark -lpthread
bench_submatch_jit_LDADD = $(top_builddir)/libre2c.la
noinst_PROGRAMS = bench_submatch_jit
bench_submatch_jit_SOURCES = bench.cc \
$(top_srcdir)/benchmarks/c/common/common.cc \
$(top_srcdir)/benchmarks/c/common/common.h \
$(top_srcdir)/benchmarks/c/common/strings_atom.h \
$(top_srcdir)/benchmarks/c/common/strings_date.h \
$(top_srcdir)/benchmarks/c/common/strings_http.h \
$(top_srcdir)/benchmarks/c/common/strings_ipv4.h \
$(top_srcdir)/benchmarks/c/common/strings_ipv6.h \
$(top_srcdir)/benchmarks/c/common/strings_uri.h
all-local: bench_submatch_jit
+66
View File
@@ -0,0 +1,66 @@
#include <benchmark/benchmark.h>
#include <string.h>
#include "benchmarks/c/common/common.h"
#include "benchmarks/c/common/strings_atom.h"
#include "benchmarks/c/common/strings_date.h"
#include "benchmarks/c/common/strings_http.h"
#include "benchmarks/c/common/strings_ipv4.h"
#include "benchmarks/c/common/strings_ipv6.h"
#include "benchmarks/c/common/strings_uri.h"
#include "lib/regex.h"
int main(int argc, char** argv)
{
static const size_t MAX_TITLE = 1024;
char title[MAX_TITLE];
static const size_t AAA_LEN = 1 << 14;
char *aaa = new char[AAA_LEN + 1];
memset(aaa, 'a', AAA_LEN);
const char *aaa_strings[] = {aaa, NULL};
const std::vector<bench_t> benches {
{"http-rfc7230", MESSAGE_HEAD, http_strings},
{"http-simple", MESSAGE_HEAD2, http_strings},
{"uri-rfc3986", URI, uri_strings},
{"uri-simple", URI2, uri_strings},
{"ipv6", IPV6, ipv6_strings},
{"ipv4", IPV4, ipv4_strings},
{"date", DATE, date_strings},
{"package", PACKAGE_ATOM, atom_strings},
{NULL, "(a)*a{10}", aaa_strings},
{NULL, "(a)*a{100}", aaa_strings},
{NULL, "(a)*a{1000}", aaa_strings},
};
const std::vector<alg_t> algs {
{"last-offset", ENGINE_RE2C, 0},
{"multipass-last-offset", ENGINE_RE2C, REG_MULTIPASS},
{"all-offsets", ENGINE_RE2C, REG_SUBHIST},
{"multipass-all-offsets", ENGINE_RE2C, REG_SUBHIST | REG_MULTIPASS},
};
benchmark::Initialize(&argc, argv);
for (const bench_t &bench : benches) {
for (const alg_t &alg : algs) {
const char *name = bench.name ? bench.name : bench.regexp;
snprintf(title, MAX_TITLE, "%s-regcomp_%s", name, alg.name);
benchmark::RegisterBenchmark(title, bench_regcomp_t(), alg, bench)
->Unit(benchmark::kMicrosecond);
}
for (const alg_t &alg : algs) {
const char *name = bench.name ? bench.name : bench.regexp;
snprintf(title, MAX_TITLE, "%s-regexec_%s", name, alg.name);
benchmark::RegisterBenchmark(title, bench_regexec_t(), alg, bench)
->Unit(benchmark::kMicrosecond);
}
}
benchmark::RunSpecifiedBenchmarks();
delete[] aaa;
}
@@ -0,0 +1,8 @@
The measurements have been taken on an Intel(R) Core(TM) i7-8750H CPU with
32 KiB L1 Data cache (x6 cores),
32 KiB L1 Instruction cache (x6 cores),
256 KiB L2 Unified cache (x6 cores),
9216 KiB L3 Unified cache,
32 GiB RAM.
Software versions:
re2c built from Git at commit `814d38f <https://github.com/skvadrik/re2c/commit/814d38f7eb19130a926f8d06172a00088967779f>`_.
File diff suppressed because it is too large Load Diff
+21
View File
@@ -0,0 +1,21 @@
add_executable(bench_submatch_nfa
"bench.cc"
"${CMAKE_SOURCE_DIR}/benchmarks/c/common/common.cc"
)
target_link_libraries(bench_submatch_nfa libre2c)
find_package(benchmark REQUIRED)
target_link_libraries(bench_submatch_nfa benchmark::benchmark)
# if present, re2 is used for benchmarks
find_path(RE2_INCLUDE_DIRECTORY "re2/re2.h")
find_library(RE2_LIBRARY re2)
if(RE2_INCLUDE_DIRECTORY AND RE2_LIBRARY)
set_target_properties(bench_submatch_nfa PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON)
target_compile_definitions(bench_submatch_nfa PRIVATE "HAVE_RE2_RE2_H=1")
target_include_directories(bench_submatch_nfa PRIVATE "${RE2_INCLUDE_DIRECTORY}")
target_link_libraries(bench_submatch_nfa "${RE2_LIBRARY}")
endif()
+17
View File
@@ -0,0 +1,17 @@
bench_submatch_nfa_CXXFLAGS = $(AM_CXXFLAGS) -O3 -I $(top_srcdir)
bench_submatch_nfa_LDFLAGS = $(LDFLAGS_RE2) -lbenchmark -lpthread
bench_submatch_nfa_LDADD = $(top_builddir)/libre2c.la
noinst_PROGRAMS = bench_submatch_nfa
bench_submatch_nfa_SOURCES = bench.cc \
$(top_srcdir)/benchmarks/c/common/common.cc \
$(top_srcdir)/benchmarks/c/common/common.h \
$(top_srcdir)/benchmarks/c/common/strings_atom.h \
$(top_srcdir)/benchmarks/c/common/strings_date.h \
$(top_srcdir)/benchmarks/c/common/strings_http.h \
$(top_srcdir)/benchmarks/c/common/strings_ipv4.h \
$(top_srcdir)/benchmarks/c/common/strings_ipv6.h \
$(top_srcdir)/benchmarks/c/common/strings_uri.h
all-local: bench_submatch_nfa
+103
View File
@@ -0,0 +1,103 @@
#include <benchmark/benchmark.h>
#include <string.h>
#include "benchmarks/c/common/common.h"
#include "benchmarks/c/common/strings_atom.h"
#include "benchmarks/c/common/strings_date.h"
#include "benchmarks/c/common/strings_http.h"
#include "benchmarks/c/common/strings_ipv4.h"
#include "benchmarks/c/common/strings_ipv6.h"
#include "benchmarks/c/common/strings_uri.h"
#include "lib/regex.h"
int main(int argc, char** argv)
{
static const size_t MAX_TITLE = 1024;
char title[MAX_TITLE];
static const size_t AAA_LEN = 1 << 13;
char *aaa = new char[AAA_LEN + 1];
memset(aaa, 'a', AAA_LEN);
const char *aaa_strings[] = {aaa, NULL};
const std::vector<bench_t> benches = {
{"HTTP-RFC7230", MESSAGE_HEAD, http_strings},
{"HTTP-simple", MESSAGE_HEAD2, http_strings},
{"URI-RFC3986", URI, uri_strings},
{"URI-simple", URI2, uri_strings},
{"IPv6", IPV6, ipv6_strings},
{"IPv6-simple", IPV62, ipv6_strings},
{"IPv4", IPV4, ipv4_strings},
{"IPv4-simple", IPV42, ipv4_strings},
{"date", DATE, date_strings},
{"date-simple", DATE2, date_strings},
{"package", PACKAGE_ATOM, atom_strings},
{"package-simple", PACKAGE_ATOM2, atom_strings},
{NULL, "(a{2}|a{3}|a{5})*", aaa_strings},
{NULL, "(a{7}|a{13}|a{19})*", aaa_strings},
{NULL, "(a{29}|a{41}|a{53})*", aaa_strings},
{NULL, "(a{67}|a{83}|a{103})*", aaa_strings},
{NULL, "(a{127}|a{151}|a{179})*", aaa_strings},
{NULL, "(a{199}|a{239}|a{271})*", aaa_strings},
{NULL, "(((a){2})|((a){3})|((a){5}))*", aaa_strings},
{NULL, "(((a){7})|((a){13})|((a){19}))*", aaa_strings},
{NULL, "(((a){29})|((a){41})|((a){53}))*", aaa_strings},
{NULL, "(((a){67})|((a){83})|((a){103}))*", aaa_strings},
{NULL, "(((a){127})|((a){151})|((a){179}))*", aaa_strings},
{NULL, "(((a){199})|((a){239})|((a){271}))*", aaa_strings},
{NULL, "(a{0,16})*", aaa_strings},
{NULL, "((a){0,16})*", aaa_strings},
{NULL, "(a{0,64})*", aaa_strings},
{NULL, "((a){0,64})*", aaa_strings},
{NULL, "(a{0,256})*", aaa_strings},
{NULL, "((a){0,256})*", aaa_strings},
// Pathological case for constant-memory POSIX algorithms that use naive
// (worst-case cubic in the size of TNFA) algorithm for precedence matrix
// computation. Cubic behaviour is caused by quadratic-time computation
// of precedence matrix on each step (the number of core items in closure
// approaches TNFA size), multiplied by the length of compared histores
// (which also approaches TNFA size). Trie-based algorithms are not
// affected, but they consume memory proportional to the length of input,
// and so are also not practical.
{NULL, "((a?){0,16})*", aaa_strings},
{NULL, "((a*){0,16})*", aaa_strings},
{NULL, "((a?){0,64})*", aaa_strings},
{NULL, "((a*){0,64})*", aaa_strings},
{NULL, "((a?){0,256})*", aaa_strings},
{NULL, "((a*){0,256})*", aaa_strings},
};
const std::vector<alg_t> algs = {
{"LG", ENGINE_RE2C, REG_NFA | REG_LEFTMOST},
{"lazy-LG", ENGINE_RE2C, REG_NFA | REG_LEFTMOST | REG_TRIE},
{"OS", ENGINE_RE2C, REG_NFA},
{"simple-OS", ENGINE_RE2C, REG_NFA | REG_SLOWPREC},
{"lazy-OS", ENGINE_RE2C, REG_NFA | REG_TRIE},
#ifdef HAVE_RE2_RE2_H
{"re2-LG", ENGINE_RE2, 0},
#endif
};
benchmark::Initialize(&argc, argv);
for (const bench_t &bench : benches) {
for (const alg_t &alg : algs) {
const char *name = bench.name ? bench.name : bench.regexp;
snprintf(title, MAX_TITLE, "%s_%s", name, alg.name);
benchmark::RegisterBenchmark(title, bench_regexec_t(), alg, bench)
->Unit(benchmark::kMicrosecond);
}
}
benchmark::RunSpecifiedBenchmarks();
delete[] aaa;
}
@@ -0,0 +1,120 @@
#line 1 "../../../benchmarks/c/src/ragel/lex_00__numbers1.rl"
#include "ragel/base.h"
namespace ragel_lex_00__numbers1 {
const char *delim = "\n";
#line 13 "../../../benchmarks/c/src/ragel/lex_00__numbers1.rl"
#line 11 "gen/ragel/lex_00__numbers1.cc"
static const int lex_numbers_start = 2;
static const int lex_numbers_first_final = 2;
static const int lex_numbers_error = 0;
static const int lex_numbers_en_main = 2;
#line 15 "../../../benchmarks/c/src/ragel/lex_00__numbers1.rl"
static int lex(Input *in, int count) {
char *p = in->p;
char *ts = in->ts;
char *te = in->te;
char *pe = in->pe;
int act = in->act;
int cs;
#line 28 "gen/ragel/lex_00__numbers1.cc"
{
cs = (int)lex_numbers_start;
ts = 0;
te = 0;
}
#line 25 "../../../benchmarks/c/src/ragel/lex_00__numbers1.rl"
#line 35 "gen/ragel/lex_00__numbers1.cc"
{
switch ( cs ) {
case 2:
goto st_case_2;
case 0:
goto st_case_0;
case 1:
goto st_case_1;
}
_ctr2:
{
#line 12 "../../../benchmarks/c/src/ragel/lex_00__numbers1.rl"
{te = p+1;{
#line 12 "../../../benchmarks/c/src/ragel/lex_00__numbers1.rl"
OUTS(ts, te); }
}}
#line 52 "gen/ragel/lex_00__numbers1.cc"
goto _st2;
_st2:
{
#line 1 "NONE"
{ts = 0;}}
#line 59 "gen/ragel/lex_00__numbers1.cc"
p+= 1;
st_case_2:
if ( p == pe )
goto _out2;
{
#line 1 "NONE"
{ts = p;}}
#line 68 "gen/ragel/lex_00__numbers1.cc"
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st1;
}
goto _st0;
_st0:
st_case_0:
goto _out0;
_st1:
p+= 1;
st_case_1:
if ( p == pe )
goto _out1;
if ( ( (*( p))) == 10 ) {
goto _ctr2;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st1;
}
goto _st0;
_out2: cs = 2; goto _out;
_out0: cs = 0; goto _out;
_out1: cs = 1; goto _out;
_out: {}
}
#line 26 "../../../benchmarks/c/src/ragel/lex_00__numbers1.rl"
in->p = p;
in->ts = ts;
in->te = te;
in->pe = pe;
in->act = act;
return count;
}
RAGEL_BENCH_AND_TEST()
} // namespace ragel_lex_00__numbers1
@@ -0,0 +1,410 @@
#line 1 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
#include "ragel/base.h"
namespace ragel_lex_01__numbers2 {
const char *delim = "\n";
#line 24 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
#line 11 "gen/ragel/lex_01__numbers2.cc"
static const int lex_numbers_start = 14;
static const int lex_numbers_first_final = 14;
static const int lex_numbers_error = 0;
static const int lex_numbers_en_main = 14;
#line 26 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
static int lex(Input *in, int count) {
char *p = in->p;
char *ts = in->ts;
char *te = in->te;
char *pe = in->pe;
int act = in->act;
int cs;
#line 28 "gen/ragel/lex_01__numbers2.cc"
{
cs = (int)lex_numbers_start;
ts = 0;
te = 0;
}
#line 36 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
#line 35 "gen/ragel/lex_01__numbers2.cc"
{
switch ( cs ) {
case 14:
goto st_case_14;
case 0:
goto st_case_0;
case 1:
goto st_case_1;
case 2:
goto st_case_2;
case 3:
goto st_case_3;
case 4:
goto st_case_4;
case 5:
goto st_case_5;
case 6:
goto st_case_6;
case 7:
goto st_case_7;
case 8:
goto st_case_8;
case 9:
goto st_case_9;
case 10:
goto st_case_10;
case 11:
goto st_case_11;
case 12:
goto st_case_12;
case 13:
goto st_case_13;
}
_ctr3:
{
#line 22 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
{te = p+1;{
#line 22 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
OUTX(ts, te, 1); }
}}
#line 76 "gen/ragel/lex_01__numbers2.cc"
goto _st14;
_ctr8:
{
#line 19 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
{te = p+1;{
#line 19 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
OUTX(ts, te, 8); }
}}
#line 86 "gen/ragel/lex_01__numbers2.cc"
goto _st14;
_ctr14:
{
#line 18 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
{te = p+1;{
#line 18 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
OUTX(ts, te, 2); }
}}
#line 96 "gen/ragel/lex_01__numbers2.cc"
goto _st14;
_ctr16:
{
#line 21 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
{te = p+1;{
#line 21 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
OUTX(ts, te, 16); }
}}
#line 106 "gen/ragel/lex_01__numbers2.cc"
goto _st14;
_ctr18:
{
#line 20 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
{te = p+1;{
#line 20 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
OUTX(ts, te, 10); }
}}
#line 116 "gen/ragel/lex_01__numbers2.cc"
goto _st14;
_st14:
{
#line 1 "NONE"
{ts = 0;}}
#line 123 "gen/ragel/lex_01__numbers2.cc"
p+= 1;
st_case_14:
if ( p == pe )
goto _out14;
{
#line 1 "NONE"
{ts = p;}}
#line 132 "gen/ragel/lex_01__numbers2.cc"
switch( ( (*( p))) ) {
case 46: {
goto _st1;
}
case 48: {
goto _st6;
}
}
if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st13;
}
goto _st0;
_st0:
st_case_0:
goto _out0;
_st1:
p+= 1;
st_case_1:
if ( p == pe )
goto _out1;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st2;
}
goto _st0;
_st2:
p+= 1;
st_case_2:
if ( p == pe )
goto _out2;
switch( ( (*( p))) ) {
case 10: {
goto _ctr3;
}
case 69: {
goto _st3;
}
case 101: {
goto _st3;
}
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st2;
}
goto _st0;
_st3:
p+= 1;
st_case_3:
if ( p == pe )
goto _out3;
switch( ( (*( p))) ) {
case 43: {
goto _st4;
}
case 45: {
goto _st4;
}
}
if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st5;
}
goto _st0;
_st4:
p+= 1;
st_case_4:
if ( p == pe )
goto _out4;
if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st5;
}
goto _st0;
_st5:
p+= 1;
st_case_5:
if ( p == pe )
goto _out5;
if ( ( (*( p))) == 10 ) {
goto _ctr3;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st5;
}
goto _st0;
_st6:
p+= 1;
st_case_6:
if ( p == pe )
goto _out6;
switch( ( (*( p))) ) {
case 10: {
goto _ctr8;
}
case 46: {
goto _st1;
}
case 66: {
goto _st9;
}
case 88: {
goto _st11;
}
case 98: {
goto _st9;
}
case 120: {
goto _st11;
}
}
if ( ( (*( p))) > 55 ) {
if ( ( (*( p))) <= 57 ) {
goto _st8;
}
} else if ( ( (*( p))) >= 48 ) {
goto _st7;
}
goto _st0;
_st7:
p+= 1;
st_case_7:
if ( p == pe )
goto _out7;
switch( ( (*( p))) ) {
case 10: {
goto _ctr8;
}
case 46: {
goto _st1;
}
}
if ( ( (*( p))) > 55 ) {
if ( ( (*( p))) <= 57 ) {
goto _st8;
}
} else if ( ( (*( p))) >= 48 ) {
goto _st7;
}
goto _st0;
_st8:
p+= 1;
st_case_8:
if ( p == pe )
goto _out8;
if ( ( (*( p))) == 46 ) {
goto _st1;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st8;
}
goto _st0;
_st9:
p+= 1;
st_case_9:
if ( p == pe )
goto _out9;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 49 ) {
goto _st10;
}
goto _st0;
_st10:
p+= 1;
st_case_10:
if ( p == pe )
goto _out10;
if ( ( (*( p))) == 10 ) {
goto _ctr14;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 49 ) {
goto _st10;
}
goto _st0;
_st11:
p+= 1;
st_case_11:
if ( p == pe )
goto _out11;
if ( ( (*( p))) < 65 ) {
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st12;
}
} else if ( ( (*( p))) > 70 ) {
if ( 97 <= ( (*( p))) && ( (*( p))) <= 102 ) {
goto _st12;
}
} else {
goto _st12;
}
goto _st0;
_st12:
p+= 1;
st_case_12:
if ( p == pe )
goto _out12;
if ( ( (*( p))) == 10 ) {
goto _ctr16;
}
if ( ( (*( p))) < 65 ) {
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st12;
}
} else if ( ( (*( p))) > 70 ) {
if ( 97 <= ( (*( p))) && ( (*( p))) <= 102 ) {
goto _st12;
}
} else {
goto _st12;
}
goto _st0;
_st13:
p+= 1;
st_case_13:
if ( p == pe )
goto _out13;
switch( ( (*( p))) ) {
case 10: {
goto _ctr18;
}
case 46: {
goto _st1;
}
case 69: {
goto _st3;
}
case 101: {
goto _st3;
}
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st13;
}
goto _st0;
_out14: cs = 14; goto _out;
_out0: cs = 0; goto _out;
_out1: cs = 1; goto _out;
_out2: cs = 2; goto _out;
_out3: cs = 3; goto _out;
_out4: cs = 4; goto _out;
_out5: cs = 5; goto _out;
_out6: cs = 6; goto _out;
_out7: cs = 7; goto _out;
_out8: cs = 8; goto _out;
_out9: cs = 9; goto _out;
_out10: cs = 10; goto _out;
_out11: cs = 11; goto _out;
_out12: cs = 12; goto _out;
_out13: cs = 13; goto _out;
_out: {}
}
#line 37 "../../../benchmarks/c/src/ragel/lex_01__numbers2.rl"
in->p = p;
in->ts = ts;
in->te = te;
in->pe = pe;
in->act = act;
return count;
}
RAGEL_BENCH_AND_TEST()
} // namespace ragel_lex_01__numbers2
+369
View File
@@ -0,0 +1,369 @@
#line 1 "../../../benchmarks/c/src/ragel/lex_02__words1.rl"
#include "ragel/base.h"
namespace ragel_lex_02__words1 {
const char *delim = "\n";
#line 20 "../../../benchmarks/c/src/ragel/lex_02__words1.rl"
#line 11 "gen/ragel/lex_02__words1.cc"
static const int lex_words_start = 21;
static const int lex_words_first_final = 21;
static const int lex_words_error = 0;
static const int lex_words_en_main = 21;
#line 22 "../../../benchmarks/c/src/ragel/lex_02__words1.rl"
static int lex(Input *in, int count) {
char *p = in->p;
char *ts = in->ts;
char *te = in->te;
char *pe = in->pe;
int act = in->act;
int cs;
#line 28 "gen/ragel/lex_02__words1.cc"
{
cs = (int)lex_words_start;
ts = 0;
te = 0;
}
#line 32 "../../../benchmarks/c/src/ragel/lex_02__words1.rl"
#line 35 "gen/ragel/lex_02__words1.cc"
{
switch ( cs ) {
case 21:
goto st_case_21;
case 0:
goto st_case_0;
case 1:
goto st_case_1;
case 2:
goto st_case_2;
case 3:
goto st_case_3;
case 4:
goto st_case_4;
case 5:
goto st_case_5;
case 6:
goto st_case_6;
case 7:
goto st_case_7;
case 8:
goto st_case_8;
case 9:
goto st_case_9;
case 10:
goto st_case_10;
case 11:
goto st_case_11;
case 12:
goto st_case_12;
case 13:
goto st_case_13;
case 14:
goto st_case_14;
case 15:
goto st_case_15;
case 16:
goto st_case_16;
case 17:
goto st_case_17;
case 18:
goto st_case_18;
case 19:
goto st_case_19;
case 20:
goto st_case_20;
}
_ctr7:
{
#line 19 "../../../benchmarks/c/src/ragel/lex_02__words1.rl"
{te = p+1;{
#line 19 "../../../benchmarks/c/src/ragel/lex_02__words1.rl"
OUTS(ts, te); }
}}
#line 90 "gen/ragel/lex_02__words1.cc"
goto _st21;
_st21:
{
#line 1 "NONE"
{ts = 0;}}
#line 97 "gen/ragel/lex_02__words1.cc"
p+= 1;
st_case_21:
if ( p == pe )
goto _out21;
{
#line 1 "NONE"
{ts = p;}}
#line 106 "gen/ragel/lex_02__words1.cc"
switch( ( (*( p))) ) {
case 70: {
goto _st1;
}
case 77: {
goto _st7;
}
case 83: {
goto _st9;
}
case 84: {
goto _st13;
}
case 87: {
goto _st18;
}
}
goto _st0;
_st0:
st_case_0:
goto _out0;
_st1:
p+= 1;
st_case_1:
if ( p == pe )
goto _out1;
if ( ( (*( p))) == 114 ) {
goto _st2;
}
goto _st0;
_st2:
p+= 1;
st_case_2:
if ( p == pe )
goto _out2;
if ( ( (*( p))) == 105 ) {
goto _st3;
}
goto _st0;
_st3:
p+= 1;
st_case_3:
if ( p == pe )
goto _out3;
if ( ( (*( p))) == 100 ) {
goto _st4;
}
goto _st0;
_st4:
p+= 1;
st_case_4:
if ( p == pe )
goto _out4;
if ( ( (*( p))) == 97 ) {
goto _st5;
}
goto _st0;
_st5:
p+= 1;
st_case_5:
if ( p == pe )
goto _out5;
if ( ( (*( p))) == 121 ) {
goto _st6;
}
goto _st0;
_st6:
p+= 1;
st_case_6:
if ( p == pe )
goto _out6;
if ( ( (*( p))) == 10 ) {
goto _ctr7;
}
goto _st0;
_st7:
p+= 1;
st_case_7:
if ( p == pe )
goto _out7;
if ( ( (*( p))) == 111 ) {
goto _st8;
}
goto _st0;
_st8:
p+= 1;
st_case_8:
if ( p == pe )
goto _out8;
if ( ( (*( p))) == 110 ) {
goto _st3;
}
goto _st0;
_st9:
p+= 1;
st_case_9:
if ( p == pe )
goto _out9;
switch( ( (*( p))) ) {
case 97: {
goto _st10;
}
case 117: {
goto _st8;
}
}
goto _st0;
_st10:
p+= 1;
st_case_10:
if ( p == pe )
goto _out10;
if ( ( (*( p))) == 116 ) {
goto _st11;
}
goto _st0;
_st11:
p+= 1;
st_case_11:
if ( p == pe )
goto _out11;
if ( ( (*( p))) == 117 ) {
goto _st12;
}
goto _st0;
_st12:
p+= 1;
st_case_12:
if ( p == pe )
goto _out12;
if ( ( (*( p))) == 114 ) {
goto _st3;
}
goto _st0;
_st13:
p+= 1;
st_case_13:
if ( p == pe )
goto _out13;
switch( ( (*( p))) ) {
case 104: {
goto _st14;
}
case 117: {
goto _st17;
}
}
goto _st0;
_st14:
p+= 1;
st_case_14:
if ( p == pe )
goto _out14;
if ( ( (*( p))) == 117 ) {
goto _st15;
}
goto _st0;
_st15:
p+= 1;
st_case_15:
if ( p == pe )
goto _out15;
if ( ( (*( p))) == 114 ) {
goto _st16;
}
goto _st0;
_st16:
p+= 1;
st_case_16:
if ( p == pe )
goto _out16;
if ( ( (*( p))) == 115 ) {
goto _st3;
}
goto _st0;
_st17:
p+= 1;
st_case_17:
if ( p == pe )
goto _out17;
if ( ( (*( p))) == 101 ) {
goto _st16;
}
goto _st0;
_st18:
p+= 1;
st_case_18:
if ( p == pe )
goto _out18;
if ( ( (*( p))) == 101 ) {
goto _st19;
}
goto _st0;
_st19:
p+= 1;
st_case_19:
if ( p == pe )
goto _out19;
if ( ( (*( p))) == 100 ) {
goto _st20;
}
goto _st0;
_st20:
p+= 1;
st_case_20:
if ( p == pe )
goto _out20;
if ( ( (*( p))) == 110 ) {
goto _st17;
}
goto _st0;
_out21: cs = 21; goto _out;
_out0: cs = 0; goto _out;
_out1: cs = 1; goto _out;
_out2: cs = 2; goto _out;
_out3: cs = 3; goto _out;
_out4: cs = 4; goto _out;
_out5: cs = 5; goto _out;
_out6: cs = 6; goto _out;
_out7: cs = 7; goto _out;
_out8: cs = 8; goto _out;
_out9: cs = 9; goto _out;
_out10: cs = 10; goto _out;
_out11: cs = 11; goto _out;
_out12: cs = 12; goto _out;
_out13: cs = 13; goto _out;
_out14: cs = 14; goto _out;
_out15: cs = 15; goto _out;
_out16: cs = 16; goto _out;
_out17: cs = 17; goto _out;
_out18: cs = 18; goto _out;
_out19: cs = 19; goto _out;
_out20: cs = 20; goto _out;
_out: {}
}
#line 33 "../../../benchmarks/c/src/ragel/lex_02__words1.rl"
in->p = p;
in->ts = ts;
in->te = te;
in->pe = pe;
in->act = act;
return count;
}
RAGEL_BENCH_AND_TEST()
} // namespace ragel_lex_02__words1
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,709 @@
#line 1 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
#include "ragel/base.h"
namespace ragel_submatch_04__apache_log {
const char *delim = "\n";
#line 44 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
#line 11 "gen/ragel/submatch_04__apache_log.cc"
static const int apache_log_start = 25;
static const int apache_log_first_final = 25;
static const int apache_log_error = 0;
static const int apache_log_en_main = 25;
#line 46 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
static int lex(Input *in, int count) {
char *p = in->p;
char *pe = in->pe;
const char
*h1, *i1, *a1, *d1, *r1, *s1, *z1, *u1, *g1,
*h2, *i2, *a2, *d2, *r2, *s2, *z2, *u2, *g2;
int cs;
#line 28 "gen/ragel/submatch_04__apache_log.cc"
{
cs = (int)apache_log_start;
}
#line 56 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
#line 33 "gen/ragel/submatch_04__apache_log.cc"
{
switch ( cs ) {
case 25:
goto st_case_25;
case 0:
goto st_case_0;
case 1:
goto st_case_1;
case 2:
goto st_case_2;
case 3:
goto st_case_3;
case 4:
goto st_case_4;
case 5:
goto st_case_5;
case 6:
goto st_case_6;
case 7:
goto st_case_7;
case 8:
goto st_case_8;
case 9:
goto st_case_9;
case 10:
goto st_case_10;
case 11:
goto st_case_11;
case 12:
goto st_case_12;
case 13:
goto st_case_13;
case 14:
goto st_case_14;
case 15:
goto st_case_15;
case 16:
goto st_case_16;
case 17:
goto st_case_17;
case 18:
goto st_case_18;
case 19:
goto st_case_19;
case 20:
goto st_case_20;
case 21:
goto st_case_21;
case 22:
goto st_case_22;
case 23:
goto st_case_23;
case 24:
goto st_case_24;
}
_ctr41:
{
#line 29 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
g2 = p; }
#line 93 "gen/ragel/submatch_04__apache_log.cc"
{
#line 30 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
OUT("host: ", h1, h2);
OUT("userid: ", i1, i2);
OUT("authuser: ", a1, a2);
OUT("date: ", d1, d2);
OUT("request: ", r1, r2);
OUT("status: ", s1, s2);
OUT("size: ", z1, z2);
OUT("url: ", u1, u2);
OUT("agent: ", g1, g2);
OUTC('\n');
}
#line 109 "gen/ragel/submatch_04__apache_log.cc"
goto _st25;
_st25:
p+= 1;
st_case_25:
if ( p == pe )
goto _out25;
if ( ( (*( p))) == 46 ) {
goto _ctr44;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _ctr44;
}
goto _st0;
_st0:
st_case_0:
goto _out0;
_ctr44:
{
#line 21 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
h1 = p; }
#line 131 "gen/ragel/submatch_04__apache_log.cc"
goto _st1;
_st1:
p+= 1;
st_case_1:
if ( p == pe )
goto _out1;
switch( ( (*( p))) ) {
case 9: {
goto _ctr2;
}
case 32: {
goto _ctr2;
}
case 46: {
goto _st1;
}
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st1;
}
goto _st0;
_ctr2:
{
#line 21 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
h2 = p; }
#line 158 "gen/ragel/submatch_04__apache_log.cc"
goto _st2;
_st2:
p+= 1;
st_case_2:
if ( p == pe )
goto _out2;
switch( ( (*( p))) ) {
case 9: {
goto _st2;
}
case 32: {
goto _st2;
}
case 45: {
goto _ctr4;
}
}
goto _st0;
_ctr4:
{
#line 22 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
i1 = p; }
#line 182 "gen/ragel/submatch_04__apache_log.cc"
goto _st3;
_st3:
p+= 1;
st_case_3:
if ( p == pe )
goto _out3;
switch( ( (*( p))) ) {
case 9: {
goto _ctr6;
}
case 32: {
goto _ctr6;
}
}
goto _st0;
_ctr6:
{
#line 22 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
i2 = p; }
#line 203 "gen/ragel/submatch_04__apache_log.cc"
goto _st4;
_st4:
p+= 1;
st_case_4:
if ( p == pe )
goto _out4;
switch( ( (*( p))) ) {
case 9: {
goto _st4;
}
case 32: {
goto _st4;
}
case 45: {
goto _ctr8;
}
}
goto _st0;
_ctr8:
{
#line 23 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
a1 = p; }
#line 227 "gen/ragel/submatch_04__apache_log.cc"
goto _st5;
_st5:
p+= 1;
st_case_5:
if ( p == pe )
goto _out5;
switch( ( (*( p))) ) {
case 9: {
goto _ctr10;
}
case 32: {
goto _ctr10;
}
}
goto _st0;
_ctr10:
{
#line 23 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
a2 = p; }
#line 248 "gen/ragel/submatch_04__apache_log.cc"
goto _st6;
_st6:
p+= 1;
st_case_6:
if ( p == pe )
goto _out6;
switch( ( (*( p))) ) {
case 9: {
goto _st6;
}
case 32: {
goto _st6;
}
case 91: {
goto _ctr12;
}
}
goto _st0;
_ctr12:
{
#line 24 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
d1 = p; }
#line 272 "gen/ragel/submatch_04__apache_log.cc"
goto _st7;
_st7:
p+= 1;
st_case_7:
if ( p == pe )
goto _out7;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st0;
}
case 93: {
goto _st0;
}
}
goto _st8;
_st8:
p+= 1;
st_case_8:
if ( p == pe )
goto _out8;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st0;
}
case 93: {
goto _st9;
}
}
goto _st8;
_st9:
p+= 1;
st_case_9:
if ( p == pe )
goto _out9;
switch( ( (*( p))) ) {
case 9: {
goto _ctr16;
}
case 32: {
goto _ctr16;
}
}
goto _st0;
_ctr16:
{
#line 24 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
d2 = p; }
#line 327 "gen/ragel/submatch_04__apache_log.cc"
goto _st10;
_st10:
p+= 1;
st_case_10:
if ( p == pe )
goto _out10;
switch( ( (*( p))) ) {
case 9: {
goto _st10;
}
case 32: {
goto _st10;
}
case 34: {
goto _ctr18;
}
}
goto _st0;
_ctr18:
{
#line 25 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
r1 = p; }
#line 351 "gen/ragel/submatch_04__apache_log.cc"
goto _st11;
_st11:
p+= 1;
st_case_11:
if ( p == pe )
goto _out11;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st0;
}
case 34: {
goto _st0;
}
}
goto _st12;
_st12:
p+= 1;
st_case_12:
if ( p == pe )
goto _out12;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st0;
}
case 34: {
goto _st13;
}
}
goto _st12;
_st13:
p+= 1;
st_case_13:
if ( p == pe )
goto _out13;
switch( ( (*( p))) ) {
case 9: {
goto _ctr22;
}
case 32: {
goto _ctr22;
}
}
goto _st0;
_ctr22:
{
#line 25 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
r2 = p; }
#line 406 "gen/ragel/submatch_04__apache_log.cc"
goto _st14;
_st14:
p+= 1;
st_case_14:
if ( p == pe )
goto _out14;
switch( ( (*( p))) ) {
case 9: {
goto _st14;
}
case 32: {
goto _st14;
}
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _ctr24;
}
goto _st0;
_ctr24:
{
#line 26 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
s1 = p; }
#line 430 "gen/ragel/submatch_04__apache_log.cc"
goto _st15;
_st15:
p+= 1;
st_case_15:
if ( p == pe )
goto _out15;
switch( ( (*( p))) ) {
case 9: {
goto _ctr26;
}
case 32: {
goto _ctr26;
}
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st15;
}
goto _st0;
_ctr26:
{
#line 26 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
s2 = p; }
#line 454 "gen/ragel/submatch_04__apache_log.cc"
goto _st16;
_st16:
p+= 1;
st_case_16:
if ( p == pe )
goto _out16;
switch( ( (*( p))) ) {
case 9: {
goto _st16;
}
case 32: {
goto _st16;
}
case 45: {
goto _ctr28;
}
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _ctr29;
}
goto _st0;
_ctr28:
{
#line 27 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
z1 = p; }
#line 481 "gen/ragel/submatch_04__apache_log.cc"
goto _st17;
_st17:
p+= 1;
st_case_17:
if ( p == pe )
goto _out17;
switch( ( (*( p))) ) {
case 9: {
goto _ctr31;
}
case 32: {
goto _ctr31;
}
}
goto _st0;
_ctr31:
{
#line 27 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
z2 = p; }
#line 502 "gen/ragel/submatch_04__apache_log.cc"
goto _st18;
_st18:
p+= 1;
st_case_18:
if ( p == pe )
goto _out18;
switch( ( (*( p))) ) {
case 9: {
goto _st18;
}
case 32: {
goto _st18;
}
case 34: {
goto _ctr33;
}
}
goto _st0;
_ctr33:
{
#line 28 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
u1 = p; }
#line 526 "gen/ragel/submatch_04__apache_log.cc"
goto _st19;
_st19:
p+= 1;
st_case_19:
if ( p == pe )
goto _out19;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st0;
}
case 34: {
goto _st20;
}
}
goto _st19;
_st20:
p+= 1;
st_case_20:
if ( p == pe )
goto _out20;
switch( ( (*( p))) ) {
case 9: {
goto _ctr36;
}
case 32: {
goto _ctr36;
}
}
goto _st0;
_ctr36:
{
#line 28 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
u2 = p; }
#line 564 "gen/ragel/submatch_04__apache_log.cc"
goto _st21;
_st21:
p+= 1;
st_case_21:
if ( p == pe )
goto _out21;
switch( ( (*( p))) ) {
case 9: {
goto _st21;
}
case 32: {
goto _st21;
}
case 34: {
goto _ctr38;
}
}
goto _st0;
_ctr38:
{
#line 29 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
g1 = p; }
#line 588 "gen/ragel/submatch_04__apache_log.cc"
goto _st22;
_st22:
p+= 1;
st_case_22:
if ( p == pe )
goto _out22;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st0;
}
case 34: {
goto _st23;
}
}
goto _st22;
_st23:
p+= 1;
st_case_23:
if ( p == pe )
goto _out23;
if ( ( (*( p))) == 10 ) {
goto _ctr41;
}
goto _st0;
_ctr29:
{
#line 27 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
z1 = p; }
#line 621 "gen/ragel/submatch_04__apache_log.cc"
goto _st24;
_st24:
p+= 1;
st_case_24:
if ( p == pe )
goto _out24;
switch( ( (*( p))) ) {
case 9: {
goto _ctr31;
}
case 32: {
goto _ctr31;
}
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st24;
}
goto _st0;
_out25: cs = 25; goto _out;
_out0: cs = 0; goto _out;
_out1: cs = 1; goto _out;
_out2: cs = 2; goto _out;
_out3: cs = 3; goto _out;
_out4: cs = 4; goto _out;
_out5: cs = 5; goto _out;
_out6: cs = 6; goto _out;
_out7: cs = 7; goto _out;
_out8: cs = 8; goto _out;
_out9: cs = 9; goto _out;
_out10: cs = 10; goto _out;
_out11: cs = 11; goto _out;
_out12: cs = 12; goto _out;
_out13: cs = 13; goto _out;
_out14: cs = 14; goto _out;
_out15: cs = 15; goto _out;
_out16: cs = 16; goto _out;
_out17: cs = 17; goto _out;
_out18: cs = 18; goto _out;
_out19: cs = 19; goto _out;
_out20: cs = 20; goto _out;
_out21: cs = 21; goto _out;
_out22: cs = 22; goto _out;
_out23: cs = 23; goto _out;
_out24: cs = 24; goto _out;
_out: {}
}
#line 57 "../../../benchmarks/c/src/ragel/submatch_04__apache_log.rl"
in->p = p;
in->pe = pe;
return count;
}
RAGEL_BENCH_AND_TEST()
} // namespace ragel_submatch_04__apache_log
@@ -0,0 +1,697 @@
#line 1 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
#include "ragel/base.h"
namespace ragel_submatch_05__datetime {
const char *delim = "\n";
#line 37 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
#line 11 "gen/ragel/submatch_05__datetime.cc"
static const int datetime_start = 35;
static const int datetime_first_final = 35;
static const int datetime_error = 0;
static const int datetime_en_main = 35;
#line 39 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
static int lex(Input *in, int count) {
char *p = in->p;
char *pe = in->pe;
const char
*s1, *y1, *h1, *m1, *d1, *M1, *z1,
*s2, *y2, *h2, *m2, *d2, *M2, *z2;
int cs;
#line 28 "gen/ragel/submatch_05__datetime.cc"
{
cs = (int)datetime_start;
}
#line 49 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
#line 33 "gen/ragel/submatch_05__datetime.cc"
{
switch ( cs ) {
case 35:
goto st_case_35;
case 0:
goto st_case_0;
case 1:
goto st_case_1;
case 2:
goto st_case_2;
case 3:
goto st_case_3;
case 4:
goto st_case_4;
case 5:
goto st_case_5;
case 6:
goto st_case_6;
case 7:
goto st_case_7;
case 8:
goto st_case_8;
case 9:
goto st_case_9;
case 10:
goto st_case_10;
case 11:
goto st_case_11;
case 12:
goto st_case_12;
case 13:
goto st_case_13;
case 14:
goto st_case_14;
case 15:
goto st_case_15;
case 16:
goto st_case_16;
case 17:
goto st_case_17;
case 18:
goto st_case_18;
case 19:
goto st_case_19;
case 20:
goto st_case_20;
case 21:
goto st_case_21;
case 22:
goto st_case_22;
case 23:
goto st_case_23;
case 24:
goto st_case_24;
case 25:
goto st_case_25;
case 26:
goto st_case_26;
case 27:
goto st_case_27;
case 28:
goto st_case_28;
case 29:
goto st_case_29;
case 30:
goto st_case_30;
case 31:
goto st_case_31;
case 32:
goto st_case_32;
case 33:
goto st_case_33;
case 34:
goto st_case_34;
}
_ctr43:
{
#line 24 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
z2 = p; }
#line 113 "gen/ragel/submatch_05__datetime.cc"
{
#line 25 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
OUT("year: ", y1, y2);
OUT("month: ", m1, m2);
OUT("day: ", d1, d2);
OUT("hours: ", h1, h2);
OUT("minutes: ", M1, M2);
OUT("seconds: ", s1, s2);
OUT("tz: ", z1, z2);
OUTC('\n');
}
#line 127 "gen/ragel/submatch_05__datetime.cc"
goto _st35;
_st35:
p+= 1;
st_case_35:
if ( p == pe )
goto _out35;
if ( ( (*( p))) == 48 ) {
goto _ctr53;
}
if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _ctr54;
}
goto _st0;
_st0:
st_case_0:
goto _out0;
_ctr53:
{
#line 18 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
y1 = p; }
#line 149 "gen/ragel/submatch_05__datetime.cc"
goto _st1;
_st1:
p+= 1;
st_case_1:
if ( p == pe )
goto _out1;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st2;
}
goto _st0;
_st2:
p+= 1;
st_case_2:
if ( p == pe )
goto _out2;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st3;
}
goto _st0;
_st3:
p+= 1;
st_case_3:
if ( p == pe )
goto _out3;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st4;
}
goto _st0;
_st4:
p+= 1;
st_case_4:
if ( p == pe )
goto _out4;
if ( ( (*( p))) == 45 ) {
goto _ctr5;
}
goto _st0;
_ctr5:
{
#line 18 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
y2 = p; }
#line 192 "gen/ragel/submatch_05__datetime.cc"
goto _st5;
_st5:
p+= 1;
st_case_5:
if ( p == pe )
goto _out5;
switch( ( (*( p))) ) {
case 48: {
goto _ctr7;
}
case 49: {
goto _ctr8;
}
}
goto _st0;
_ctr7:
{
#line 19 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
m1 = p; }
#line 213 "gen/ragel/submatch_05__datetime.cc"
goto _st6;
_st6:
p+= 1;
st_case_6:
if ( p == pe )
goto _out6;
if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st7;
}
goto _st0;
_st7:
p+= 1;
st_case_7:
if ( p == pe )
goto _out7;
if ( ( (*( p))) == 45 ) {
goto _ctr11;
}
goto _st0;
_ctr11:
{
#line 19 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
m2 = p; }
#line 238 "gen/ragel/submatch_05__datetime.cc"
goto _st8;
_st8:
p+= 1;
st_case_8:
if ( p == pe )
goto _out8;
switch( ( (*( p))) ) {
case 48: {
goto _ctr13;
}
case 51: {
goto _ctr15;
}
}
if ( 49 <= ( (*( p))) && ( (*( p))) <= 50 ) {
goto _ctr14;
}
goto _st0;
_ctr13:
{
#line 20 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
d1 = p; }
#line 262 "gen/ragel/submatch_05__datetime.cc"
goto _st9;
_st9:
p+= 1;
st_case_9:
if ( p == pe )
goto _out9;
if ( 49 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st10;
}
goto _st0;
_st10:
p+= 1;
st_case_10:
if ( p == pe )
goto _out10;
if ( ( (*( p))) == 84 ) {
goto _ctr18;
}
goto _st0;
_ctr18:
{
#line 20 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
d2 = p; }
#line 287 "gen/ragel/submatch_05__datetime.cc"
goto _st11;
_st11:
p+= 1;
st_case_11:
if ( p == pe )
goto _out11;
if ( ( (*( p))) == 50 ) {
goto _ctr21;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 49 ) {
goto _ctr20;
}
goto _st0;
_ctr20:
{
#line 21 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
h1 = p; }
#line 306 "gen/ragel/submatch_05__datetime.cc"
goto _st12;
_st12:
p+= 1;
st_case_12:
if ( p == pe )
goto _out12;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st13;
}
goto _st0;
_st13:
p+= 1;
st_case_13:
if ( p == pe )
goto _out13;
if ( ( (*( p))) == 58 ) {
goto _ctr24;
}
goto _st0;
_ctr24:
{
#line 21 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
h2 = p; }
#line 331 "gen/ragel/submatch_05__datetime.cc"
goto _st14;
_st14:
p+= 1;
st_case_14:
if ( p == pe )
goto _out14;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 53 ) {
goto _ctr26;
}
goto _st0;
_ctr26:
{
#line 22 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
M1 = p; }
#line 347 "gen/ragel/submatch_05__datetime.cc"
goto _st15;
_st15:
p+= 1;
st_case_15:
if ( p == pe )
goto _out15;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st16;
}
goto _st0;
_st16:
p+= 1;
st_case_16:
if ( p == pe )
goto _out16;
if ( ( (*( p))) == 58 ) {
goto _ctr29;
}
goto _st0;
_ctr29:
{
#line 22 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
M2 = p; }
#line 372 "gen/ragel/submatch_05__datetime.cc"
goto _st17;
_st17:
p+= 1;
st_case_17:
if ( p == pe )
goto _out17;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 53 ) {
goto _ctr31;
}
goto _st0;
_ctr31:
{
#line 23 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
s1 = p; }
#line 388 "gen/ragel/submatch_05__datetime.cc"
goto _st18;
_st18:
p+= 1;
st_case_18:
if ( p == pe )
goto _out18;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st19;
}
goto _st0;
_st19:
p+= 1;
st_case_19:
if ( p == pe )
goto _out19;
switch( ( (*( p))) ) {
case 43: {
goto _ctr34;
}
case 45: {
goto _ctr34;
}
case 90: {
goto _ctr35;
}
}
goto _st0;
_ctr34:
{
#line 23 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
s2 = p; }
#line 421 "gen/ragel/submatch_05__datetime.cc"
{
#line 24 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
z1 = p; }
#line 426 "gen/ragel/submatch_05__datetime.cc"
goto _st20;
_st20:
p+= 1;
st_case_20:
if ( p == pe )
goto _out20;
if ( ( (*( p))) == 50 ) {
goto _st26;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 49 ) {
goto _st21;
}
goto _st0;
_st21:
p+= 1;
st_case_21:
if ( p == pe )
goto _out21;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st22;
}
goto _st0;
_st22:
p+= 1;
st_case_22:
if ( p == pe )
goto _out22;
if ( ( (*( p))) == 58 ) {
goto _st23;
}
goto _st0;
_st23:
p+= 1;
st_case_23:
if ( p == pe )
goto _out23;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 53 ) {
goto _st24;
}
goto _st0;
_st24:
p+= 1;
st_case_24:
if ( p == pe )
goto _out24;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st25;
}
goto _st0;
_ctr35:
{
#line 23 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
s2 = p; }
#line 481 "gen/ragel/submatch_05__datetime.cc"
{
#line 24 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
z1 = p; }
#line 486 "gen/ragel/submatch_05__datetime.cc"
goto _st25;
_st25:
p+= 1;
st_case_25:
if ( p == pe )
goto _out25;
if ( ( (*( p))) == 10 ) {
goto _ctr43;
}
goto _st0;
_st26:
p+= 1;
st_case_26:
if ( p == pe )
goto _out26;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 51 ) {
goto _st22;
}
goto _st0;
_ctr21:
{
#line 21 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
h1 = p; }
#line 511 "gen/ragel/submatch_05__datetime.cc"
goto _st27;
_st27:
p+= 1;
st_case_27:
if ( p == pe )
goto _out27;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 51 ) {
goto _st13;
}
goto _st0;
_ctr14:
{
#line 20 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
d1 = p; }
#line 527 "gen/ragel/submatch_05__datetime.cc"
goto _st28;
_st28:
p+= 1;
st_case_28:
if ( p == pe )
goto _out28;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st10;
}
goto _st0;
_ctr15:
{
#line 20 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
d1 = p; }
#line 543 "gen/ragel/submatch_05__datetime.cc"
goto _st29;
_st29:
p+= 1;
st_case_29:
if ( p == pe )
goto _out29;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 49 ) {
goto _st10;
}
goto _st0;
_ctr8:
{
#line 19 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
m1 = p; }
#line 559 "gen/ragel/submatch_05__datetime.cc"
goto _st30;
_st30:
p+= 1;
st_case_30:
if ( p == pe )
goto _out30;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 50 ) {
goto _st7;
}
goto _st0;
_ctr54:
{
#line 18 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
y1 = p; }
#line 575 "gen/ragel/submatch_05__datetime.cc"
goto _st31;
_st31:
p+= 1;
st_case_31:
if ( p == pe )
goto _out31;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st32;
}
goto _st0;
_st32:
p+= 1;
st_case_32:
if ( p == pe )
goto _out32;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st33;
}
goto _st0;
_st33:
p+= 1;
st_case_33:
if ( p == pe )
goto _out33;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st34;
}
goto _st0;
_st34:
p+= 1;
st_case_34:
if ( p == pe )
goto _out34;
if ( ( (*( p))) == 45 ) {
goto _ctr5;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st34;
}
goto _st0;
_out35: cs = 35; goto _out;
_out0: cs = 0; goto _out;
_out1: cs = 1; goto _out;
_out2: cs = 2; goto _out;
_out3: cs = 3; goto _out;
_out4: cs = 4; goto _out;
_out5: cs = 5; goto _out;
_out6: cs = 6; goto _out;
_out7: cs = 7; goto _out;
_out8: cs = 8; goto _out;
_out9: cs = 9; goto _out;
_out10: cs = 10; goto _out;
_out11: cs = 11; goto _out;
_out12: cs = 12; goto _out;
_out13: cs = 13; goto _out;
_out14: cs = 14; goto _out;
_out15: cs = 15; goto _out;
_out16: cs = 16; goto _out;
_out17: cs = 17; goto _out;
_out18: cs = 18; goto _out;
_out19: cs = 19; goto _out;
_out20: cs = 20; goto _out;
_out21: cs = 21; goto _out;
_out22: cs = 22; goto _out;
_out23: cs = 23; goto _out;
_out24: cs = 24; goto _out;
_out25: cs = 25; goto _out;
_out26: cs = 26; goto _out;
_out27: cs = 27; goto _out;
_out28: cs = 28; goto _out;
_out29: cs = 29; goto _out;
_out30: cs = 30; goto _out;
_out31: cs = 31; goto _out;
_out32: cs = 32; goto _out;
_out33: cs = 33; goto _out;
_out34: cs = 34; goto _out;
_out: {}
}
#line 50 "../../../benchmarks/c/src/ragel/submatch_05__datetime.rl"
in->p = p;
in->pe = pe;
return count;
}
RAGEL_BENCH_AND_TEST()
} // namespace ragel_submatch_05__datetime
@@ -0,0 +1,407 @@
#line 1 "../../../benchmarks/c/src/ragel/submatch_06__email.rl"
#include "ragel/base.h"
namespace ragel_submatch_06__email {
const char *delim = "\n";
#line 28 "../../../benchmarks/c/src/ragel/submatch_06__email.rl"
#line 11 "gen/ragel/submatch_06__email.cc"
static const int email_start = 10;
static const int email_first_final = 10;
static const int email_error = 0;
static const int email_en_main = 10;
#line 30 "../../../benchmarks/c/src/ragel/submatch_06__email.rl"
static int lex(Input *in, int count) {
char *p = in->p;
char *pe = in->pe;
char *p1, *p2;
int cs;
#line 26 "gen/ragel/submatch_06__email.cc"
{
cs = (int)email_start;
}
#line 38 "../../../benchmarks/c/src/ragel/submatch_06__email.rl"
#line 31 "gen/ragel/submatch_06__email.cc"
{
switch ( cs ) {
case 10:
goto st_case_10;
case 1:
goto st_case_1;
case 0:
goto st_case_0;
case 2:
goto st_case_2;
case 3:
goto st_case_3;
case 4:
goto st_case_4;
case 5:
goto st_case_5;
case 6:
goto st_case_6;
case 7:
goto st_case_7;
case 8:
goto st_case_8;
case 9:
goto st_case_9;
}
_ctr11:
{
#line 19 "../../../benchmarks/c/src/ragel/submatch_06__email.rl"
OUTC(' ');
OUTS(p1, p2 - 1);
OUTC(' ');
OUTS(p2, p);
OUTC('\n');
}
#line 67 "gen/ragel/submatch_06__email.cc"
goto _st10;
_st10:
p+= 1;
st_case_10:
if ( p == pe )
goto _out10;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st10;
}
case 33: {
goto _ctr13;
}
case 45: {
goto _ctr13;
}
case 61: {
goto _ctr13;
}
case 63: {
goto _ctr13;
}
}
if ( ( (*( p))) < 42 ) {
if ( 35 <= ( (*( p))) && ( (*( p))) <= 39 ) {
goto _ctr13;
}
} else if ( ( (*( p))) > 43 ) {
if ( ( (*( p))) > 57 ) {
if ( 94 <= ( (*( p))) && ( (*( p))) <= 126 ) {
goto _ctr13;
}
} else if ( ( (*( p))) >= 47 ) {
goto _ctr13;
}
} else {
goto _ctr13;
}
goto _st1;
_st1:
p+= 1;
st_case_1:
if ( p == pe )
goto _out1;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st10;
}
}
goto _st1;
_st0:
st_case_0:
goto _out0;
_ctr13:
{
#line 17 "../../../benchmarks/c/src/ragel/submatch_06__email.rl"
p1 = p; }
#line 132 "gen/ragel/submatch_06__email.cc"
goto _st2;
_st2:
p+= 1;
st_case_2:
if ( p == pe )
goto _out2;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st10;
}
case 33: {
goto _st2;
}
case 46: {
goto _st3;
}
case 61: {
goto _st2;
}
case 63: {
goto _st2;
}
case 64: {
goto _st4;
}
}
if ( ( (*( p))) < 42 ) {
if ( 35 <= ( (*( p))) && ( (*( p))) <= 39 ) {
goto _st2;
}
} else if ( ( (*( p))) > 43 ) {
if ( ( (*( p))) > 57 ) {
if ( 94 <= ( (*( p))) && ( (*( p))) <= 126 ) {
goto _st2;
}
} else if ( ( (*( p))) >= 45 ) {
goto _st2;
}
} else {
goto _st2;
}
goto _st1;
_st3:
p+= 1;
st_case_3:
if ( p == pe )
goto _out3;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st10;
}
case 33: {
goto _st2;
}
case 45: {
goto _st2;
}
case 61: {
goto _st2;
}
case 63: {
goto _st2;
}
}
if ( ( (*( p))) < 42 ) {
if ( 35 <= ( (*( p))) && ( (*( p))) <= 39 ) {
goto _st2;
}
} else if ( ( (*( p))) > 43 ) {
if ( ( (*( p))) > 57 ) {
if ( 94 <= ( (*( p))) && ( (*( p))) <= 126 ) {
goto _st2;
}
} else if ( ( (*( p))) >= 47 ) {
goto _st2;
}
} else {
goto _st2;
}
goto _st1;
_st4:
p+= 1;
st_case_4:
if ( p == pe )
goto _out4;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st10;
}
}
if ( ( (*( p))) > 57 ) {
if ( 97 <= ( (*( p))) && ( (*( p))) <= 122 ) {
goto _ctr6;
}
} else if ( ( (*( p))) >= 48 ) {
goto _ctr6;
}
goto _st1;
_ctr6:
{
#line 18 "../../../benchmarks/c/src/ragel/submatch_06__email.rl"
p2 = p; }
#line 245 "gen/ragel/submatch_06__email.cc"
goto _st5;
_st5:
p+= 1;
st_case_5:
if ( p == pe )
goto _out5;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st10;
}
case 45: {
goto _st6;
}
case 46: {
goto _st7;
}
}
if ( ( (*( p))) > 57 ) {
if ( 97 <= ( (*( p))) && ( (*( p))) <= 122 ) {
goto _st5;
}
} else if ( ( (*( p))) >= 48 ) {
goto _st5;
}
goto _st1;
_st6:
p+= 1;
st_case_6:
if ( p == pe )
goto _out6;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st10;
}
case 45: {
goto _st6;
}
}
if ( ( (*( p))) > 57 ) {
if ( 97 <= ( (*( p))) && ( (*( p))) <= 122 ) {
goto _st5;
}
} else if ( ( (*( p))) >= 48 ) {
goto _st5;
}
goto _st1;
_st7:
p+= 1;
st_case_7:
if ( p == pe )
goto _out7;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st10;
}
}
if ( ( (*( p))) > 57 ) {
if ( 97 <= ( (*( p))) && ( (*( p))) <= 122 ) {
goto _st8;
}
} else if ( ( (*( p))) >= 48 ) {
goto _st8;
}
goto _st1;
_st8:
p+= 1;
st_case_8:
if ( p == pe )
goto _out8;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _ctr11;
}
case 45: {
goto _st9;
}
case 46: {
goto _st7;
}
}
if ( ( (*( p))) > 57 ) {
if ( 97 <= ( (*( p))) && ( (*( p))) <= 122 ) {
goto _st8;
}
} else if ( ( (*( p))) >= 48 ) {
goto _st8;
}
goto _st1;
_st9:
p+= 1;
st_case_9:
if ( p == pe )
goto _out9;
switch( ( (*( p))) ) {
case 0: {
goto _st0;
}
case 10: {
goto _st10;
}
case 45: {
goto _st9;
}
}
if ( ( (*( p))) > 57 ) {
if ( 97 <= ( (*( p))) && ( (*( p))) <= 122 ) {
goto _st8;
}
} else if ( ( (*( p))) >= 48 ) {
goto _st8;
}
goto _st1;
_out10: cs = 10; goto _out;
_out1: cs = 1; goto _out;
_out0: cs = 0; goto _out;
_out2: cs = 2; goto _out;
_out3: cs = 3; goto _out;
_out4: cs = 4; goto _out;
_out5: cs = 5; goto _out;
_out6: cs = 6; goto _out;
_out7: cs = 7; goto _out;
_out8: cs = 8; goto _out;
_out9: cs = 9; goto _out;
_out: {}
}
#line 39 "../../../benchmarks/c/src/ragel/submatch_06__email.rl"
in->p = p;
in->pe = pe;
return count;
}
RAGEL_BENCH_AND_TEST()
} // namespace ragel_submatch_06__email
@@ -0,0 +1,328 @@
#line 1 "../../../benchmarks/c/src/ragel/submatch_07__ipv4.rl"
#include "ragel/base.h"
namespace ragel_submatch_07__ipv4 {
const char *delim = "\n";
#line 29 "../../../benchmarks/c/src/ragel/submatch_07__ipv4.rl"
#line 11 "gen/ragel/submatch_07__ipv4.cc"
static const int ipv4_start = 16;
static const int ipv4_first_final = 16;
static const int ipv4_error = 0;
static const int ipv4_en_main = 16;
#line 31 "../../../benchmarks/c/src/ragel/submatch_07__ipv4.rl"
static int lex(Input *in, int count) {
char *p = in->p;
char *pe = in->pe;
const char *p1, *p2, *p3, *p4;
int cs;
#line 26 "gen/ragel/submatch_07__ipv4.cc"
{
cs = (int)ipv4_start;
}
#line 39 "../../../benchmarks/c/src/ragel/submatch_07__ipv4.rl"
#line 31 "gen/ragel/submatch_07__ipv4.cc"
{
switch ( cs ) {
case 16:
goto st_case_16;
case 0:
goto st_case_0;
case 1:
goto st_case_1;
case 2:
goto st_case_2;
case 3:
goto st_case_3;
case 4:
goto st_case_4;
case 5:
goto st_case_5;
case 6:
goto st_case_6;
case 7:
goto st_case_7;
case 8:
goto st_case_8;
case 9:
goto st_case_9;
case 10:
goto st_case_10;
case 11:
goto st_case_11;
case 12:
goto st_case_12;
case 13:
goto st_case_13;
case 14:
goto st_case_14;
case 15:
goto st_case_15;
}
_ctr14:
{
#line 17 "../../../benchmarks/c/src/ragel/submatch_07__ipv4.rl"
OUTS(p1, p2 - 1);
OUTC(',');
OUTS(p2, p3 - 1);
OUTC(',');
OUTS(p3, p4 - 1);
OUTC(',');
OUTS(p4, p);
OUTC('\n');
}
#line 82 "gen/ragel/submatch_07__ipv4.cc"
goto _st16;
_st16:
p+= 1;
st_case_16:
if ( p == pe )
goto _out16;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _ctr21;
}
goto _st0;
_st0:
st_case_0:
goto _out0;
_ctr21:
{
#line 13 "../../../benchmarks/c/src/ragel/submatch_07__ipv4.rl"
p1 = p; }
#line 101 "gen/ragel/submatch_07__ipv4.cc"
goto _st1;
_st1:
p+= 1;
st_case_1:
if ( p == pe )
goto _out1;
if ( ( (*( p))) == 46 ) {
goto _st2;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st14;
}
goto _st0;
_st2:
p+= 1;
st_case_2:
if ( p == pe )
goto _out2;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _ctr4;
}
goto _st0;
_ctr4:
{
#line 14 "../../../benchmarks/c/src/ragel/submatch_07__ipv4.rl"
p2 = p; }
#line 129 "gen/ragel/submatch_07__ipv4.cc"
goto _st3;
_st3:
p+= 1;
st_case_3:
if ( p == pe )
goto _out3;
if ( ( (*( p))) == 46 ) {
goto _st4;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st12;
}
goto _st0;
_st4:
p+= 1;
st_case_4:
if ( p == pe )
goto _out4;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _ctr8;
}
goto _st0;
_ctr8:
{
#line 15 "../../../benchmarks/c/src/ragel/submatch_07__ipv4.rl"
p3 = p; }
#line 157 "gen/ragel/submatch_07__ipv4.cc"
goto _st5;
_st5:
p+= 1;
st_case_5:
if ( p == pe )
goto _out5;
if ( ( (*( p))) == 46 ) {
goto _st6;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st10;
}
goto _st0;
_st6:
p+= 1;
st_case_6:
if ( p == pe )
goto _out6;
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _ctr12;
}
goto _st0;
_ctr12:
{
#line 16 "../../../benchmarks/c/src/ragel/submatch_07__ipv4.rl"
p4 = p; }
#line 185 "gen/ragel/submatch_07__ipv4.cc"
goto _st7;
_st7:
p+= 1;
st_case_7:
if ( p == pe )
goto _out7;
if ( ( (*( p))) == 10 ) {
goto _ctr14;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st8;
}
goto _st0;
_st8:
p+= 1;
st_case_8:
if ( p == pe )
goto _out8;
if ( ( (*( p))) == 10 ) {
goto _ctr14;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st9;
}
goto _st0;
_st9:
p+= 1;
st_case_9:
if ( p == pe )
goto _out9;
if ( ( (*( p))) == 10 ) {
goto _ctr14;
}
goto _st0;
_st10:
p+= 1;
st_case_10:
if ( p == pe )
goto _out10;
if ( ( (*( p))) == 46 ) {
goto _st6;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st11;
}
goto _st0;
_st11:
p+= 1;
st_case_11:
if ( p == pe )
goto _out11;
if ( ( (*( p))) == 46 ) {
goto _st6;
}
goto _st0;
_st12:
p+= 1;
st_case_12:
if ( p == pe )
goto _out12;
if ( ( (*( p))) == 46 ) {
goto _st4;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st13;
}
goto _st0;
_st13:
p+= 1;
st_case_13:
if ( p == pe )
goto _out13;
if ( ( (*( p))) == 46 ) {
goto _st4;
}
goto _st0;
_st14:
p+= 1;
st_case_14:
if ( p == pe )
goto _out14;
if ( ( (*( p))) == 46 ) {
goto _st2;
}
if ( 48 <= ( (*( p))) && ( (*( p))) <= 57 ) {
goto _st15;
}
goto _st0;
_st15:
p+= 1;
st_case_15:
if ( p == pe )
goto _out15;
if ( ( (*( p))) == 46 ) {
goto _st2;
}
goto _st0;
_out16: cs = 16; goto _out;
_out0: cs = 0; goto _out;
_out1: cs = 1; goto _out;
_out2: cs = 2; goto _out;
_out3: cs = 3; goto _out;
_out4: cs = 4; goto _out;
_out5: cs = 5; goto _out;
_out6: cs = 6; goto _out;
_out7: cs = 7; goto _out;
_out8: cs = 8; goto _out;
_out9: cs = 9; goto _out;
_out10: cs = 10; goto _out;
_out11: cs = 11; goto _out;
_out12: cs = 12; goto _out;
_out13: cs = 13; goto _out;
_out14: cs = 14; goto _out;
_out15: cs = 15; goto _out;
_out: {}
}
#line 40 "../../../benchmarks/c/src/ragel/submatch_07__ipv4.rl"
in->p = p;
in->pe = pe;
return count;
}
RAGEL_BENCH_AND_TEST()
} // namespace ragel_submatch_07__ipv4
@@ -0,0 +1,207 @@
#line 1 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
#include "ragel/base.h"
namespace ragel_submatch_10__alt1_2 {
const char *delim = "\n";
#line 23 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
#line 11 "gen/ragel/submatch_10__alt1_2.cc"
static const int m_start = 3;
static const int m_first_final = 3;
static const int m_error = 0;
static const int m_en_main = 3;
#line 25 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
static int lex(Input *in, int count) {
char *p = in->p;
char *pe = in->pe;
const char
*a1, *b1,
*a2, *b2;
int cs;
#line 28 "gen/ragel/submatch_10__alt1_2.cc"
{
cs = (int)m_start;
}
#line 35 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
#line 33 "gen/ragel/submatch_10__alt1_2.cc"
{
switch ( cs ) {
case 3:
goto st_case_3;
case 0:
goto st_case_0;
case 1:
goto st_case_1;
case 2:
goto st_case_2;
}
_ctr2:
{
#line 14 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
a2 = p; b1 = b2 = NULL; }
#line 49 "gen/ragel/submatch_10__alt1_2.cc"
{
#line 16 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
if (a1) { OUTC('A'); OUTS(a1, a2); }
else if (b1) { OUTC('B'); OUTS(b1, b2); }
OUTC('\n');
}
#line 58 "gen/ragel/submatch_10__alt1_2.cc"
goto _st3;
_ctr4:
{
#line 13 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
b2 = p; a1 = a2 = NULL; }
#line 65 "gen/ragel/submatch_10__alt1_2.cc"
{
#line 16 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
if (a1) { OUTC('A'); OUTS(a1, a2); }
else if (b1) { OUTC('B'); OUTS(b1, b2); }
OUTC('\n');
}
#line 74 "gen/ragel/submatch_10__alt1_2.cc"
goto _st3;
_ctr6:
{
#line 13 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
b1 = p; }
#line 81 "gen/ragel/submatch_10__alt1_2.cc"
{
#line 13 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
b2 = p; a1 = a2 = NULL; }
#line 86 "gen/ragel/submatch_10__alt1_2.cc"
{
#line 14 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
a1 = p; }
#line 91 "gen/ragel/submatch_10__alt1_2.cc"
{
#line 14 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
a2 = p; b1 = b2 = NULL; }
#line 96 "gen/ragel/submatch_10__alt1_2.cc"
{
#line 16 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
if (a1) { OUTC('A'); OUTS(a1, a2); }
else if (b1) { OUTC('B'); OUTS(b1, b2); }
OUTC('\n');
}
#line 105 "gen/ragel/submatch_10__alt1_2.cc"
goto _st3;
_st3:
p+= 1;
st_case_3:
if ( p == pe )
goto _out3;
switch( ( (*( p))) ) {
case 10: {
goto _ctr6;
}
case 97: {
goto _ctr7;
}
case 98: {
goto _ctr8;
}
}
goto _st0;
_st0:
st_case_0:
goto _out0;
_ctr7:
{
#line 14 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
a1 = p; }
#line 132 "gen/ragel/submatch_10__alt1_2.cc"
goto _st1;
_st1:
p+= 1;
st_case_1:
if ( p == pe )
goto _out1;
switch( ( (*( p))) ) {
case 10: {
goto _ctr2;
}
case 97: {
goto _st1;
}
}
goto _st0;
_ctr8:
{
#line 13 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
b1 = p; }
#line 153 "gen/ragel/submatch_10__alt1_2.cc"
goto _st2;
_st2:
p+= 1;
st_case_2:
if ( p == pe )
goto _out2;
switch( ( (*( p))) ) {
case 10: {
goto _ctr4;
}
case 98: {
goto _st2;
}
}
goto _st0;
_out3: cs = 3; goto _out;
_out0: cs = 0; goto _out;
_out1: cs = 1; goto _out;
_out2: cs = 2; goto _out;
_out: {}
}
#line 36 "../../../benchmarks/c/src/ragel/submatch_10__alt1_2.rl"
in->p = p;
in->pe = pe;
return count;
}
RAGEL_BENCH_AND_TEST()
} // namespace ragel_submatch_10__alt1_2
@@ -0,0 +1,333 @@
#line 1 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
#include "ragel/base.h"
namespace ragel_submatch_11__alt1_4 {
const char *delim = "\n";
#line 27 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
#line 11 "gen/ragel/submatch_11__alt1_4.cc"
static const int m_start = 5;
static const int m_first_final = 5;
static const int m_error = 0;
static const int m_en_main = 5;
#line 29 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
static int lex(Input *in, int count) {
char *p = in->p;
char *pe = in->pe;
const char
*a1, *b1, *c1, *d1,
*a2, *b2, *c2, *d2;
int cs;
#line 28 "gen/ragel/submatch_11__alt1_4.cc"
{
cs = (int)m_start;
}
#line 39 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
#line 33 "gen/ragel/submatch_11__alt1_4.cc"
{
switch ( cs ) {
case 5:
goto st_case_5;
case 0:
goto st_case_0;
case 1:
goto st_case_1;
case 2:
goto st_case_2;
case 3:
goto st_case_3;
case 4:
goto st_case_4;
}
_ctr2:
{
#line 16 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
a2 = p; b1 = b2 = c1 = c2 = d1 = d2 = NULL; }
#line 53 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 18 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
if (a1) { OUTC('A'); OUTS(a1, a2); }
else if (b1) { OUTC('B'); OUTS(b1, b2); }
else if (c1) { OUTC('C'); OUTS(c1, c2); }
else if (d1) { OUTC('D'); OUTS(d1, d2); }
OUTC('\n');
}
#line 64 "gen/ragel/submatch_11__alt1_4.cc"
goto _st5;
_ctr4:
{
#line 13 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
b2 = p; a1 = a2 = c1 = c2 = d1 = d2 = NULL; }
#line 71 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 18 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
if (a1) { OUTC('A'); OUTS(a1, a2); }
else if (b1) { OUTC('B'); OUTS(b1, b2); }
else if (c1) { OUTC('C'); OUTS(c1, c2); }
else if (d1) { OUTC('D'); OUTS(d1, d2); }
OUTC('\n');
}
#line 82 "gen/ragel/submatch_11__alt1_4.cc"
goto _st5;
_ctr6:
{
#line 14 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
c2 = p; a1 = a2 = b1 = b2 = d1 = d2 = NULL; }
#line 89 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 18 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
if (a1) { OUTC('A'); OUTS(a1, a2); }
else if (b1) { OUTC('B'); OUTS(b1, b2); }
else if (c1) { OUTC('C'); OUTS(c1, c2); }
else if (d1) { OUTC('D'); OUTS(d1, d2); }
OUTC('\n');
}
#line 100 "gen/ragel/submatch_11__alt1_4.cc"
goto _st5;
_ctr8:
{
#line 15 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
d2 = p; a1 = a2 = b1 = b2 = c1 = c2 = NULL; }
#line 107 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 18 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
if (a1) { OUTC('A'); OUTS(a1, a2); }
else if (b1) { OUTC('B'); OUTS(b1, b2); }
else if (c1) { OUTC('C'); OUTS(c1, c2); }
else if (d1) { OUTC('D'); OUTS(d1, d2); }
OUTC('\n');
}
#line 118 "gen/ragel/submatch_11__alt1_4.cc"
goto _st5;
_ctr10:
{
#line 13 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
b1 = p; }
#line 125 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 13 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
b2 = p; a1 = a2 = c1 = c2 = d1 = d2 = NULL; }
#line 130 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 14 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
c1 = p; }
#line 135 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 14 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
c2 = p; a1 = a2 = b1 = b2 = d1 = d2 = NULL; }
#line 140 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 15 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
d1 = p; }
#line 145 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 15 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
d2 = p; a1 = a2 = b1 = b2 = c1 = c2 = NULL; }
#line 150 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 16 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
a1 = p; }
#line 155 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 16 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
a2 = p; b1 = b2 = c1 = c2 = d1 = d2 = NULL; }
#line 160 "gen/ragel/submatch_11__alt1_4.cc"
{
#line 18 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
if (a1) { OUTC('A'); OUTS(a1, a2); }
else if (b1) { OUTC('B'); OUTS(b1, b2); }
else if (c1) { OUTC('C'); OUTS(c1, c2); }
else if (d1) { OUTC('D'); OUTS(d1, d2); }
OUTC('\n');
}
#line 171 "gen/ragel/submatch_11__alt1_4.cc"
goto _st5;
_st5:
p+= 1;
st_case_5:
if ( p == pe )
goto _out5;
switch( ( (*( p))) ) {
case 10: {
goto _ctr10;
}
case 97: {
goto _ctr11;
}
case 98: {
goto _ctr12;
}
case 99: {
goto _ctr13;
}
case 100: {
goto _ctr14;
}
}
goto _st0;
_st0:
st_case_0:
goto _out0;
_ctr11:
{
#line 16 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
a1 = p; }
#line 204 "gen/ragel/submatch_11__alt1_4.cc"
goto _st1;
_st1:
p+= 1;
st_case_1:
if ( p == pe )
goto _out1;
switch( ( (*( p))) ) {
case 10: {
goto _ctr2;
}
case 97: {
goto _st1;
}
}
goto _st0;
_ctr12:
{
#line 13 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
b1 = p; }
#line 225 "gen/ragel/submatch_11__alt1_4.cc"
goto _st2;
_st2:
p+= 1;
st_case_2:
if ( p == pe )
goto _out2;
switch( ( (*( p))) ) {
case 10: {
goto _ctr4;
}
case 98: {
goto _st2;
}
}
goto _st0;
_ctr13:
{
#line 14 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
c1 = p; }
#line 246 "gen/ragel/submatch_11__alt1_4.cc"
goto _st3;
_st3:
p+= 1;
st_case_3:
if ( p == pe )
goto _out3;
switch( ( (*( p))) ) {
case 10: {
goto _ctr6;
}
case 99: {
goto _st3;
}
}
goto _st0;
_ctr14:
{
#line 15 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
d1 = p; }
#line 267 "gen/ragel/submatch_11__alt1_4.cc"
goto _st4;
_st4:
p+= 1;
st_case_4:
if ( p == pe )
goto _out4;
switch( ( (*( p))) ) {
case 10: {
goto _ctr8;
}
case 100: {
goto _st4;
}
}
goto _st0;
_out5: cs = 5; goto _out;
_out0: cs = 0; goto _out;
_out1: cs = 1; goto _out;
_out2: cs = 2; goto _out;
_out3: cs = 3; goto _out;
_out4: cs = 4; goto _out;
_out: {}
}
#line 40 "../../../benchmarks/c/src/ragel/submatch_11__alt1_4.rl"
in->p = p;
in->pe = pe;
return count;
}
RAGEL_BENCH_AND_TEST()
} // namespace ragel_submatch_11__alt1_4

Some files were not shown because too many files have changed in this diff Show More