Compare commits

..
396 Commits
Author SHA1 Message Date
Ulya Trofimovich 4424a0dd1e CMake: set C++17 standard for benchmarks (required by newer re2). 2023-07-24 08:05:35 +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
Ulya Trofimovich 3a7c3fedf2 Release 3.0. 2022-01-27 08:41:08 +00:00
Ulya Trofimovich e6cd3eaaec Update CHANGELOG. 2022-01-24 23:11:59 +00:00
Ulya Trofimovich f18ce1b7d3 Update README.md and BUILD.md. 2022-01-24 07:38:02 +00:00
Ulya Trofimovich f8ea4ea47d Fix the build on FreeBSD.
The build was broken by https://github.com/skvadrik/re2c/pull/376, which
added define of _POSIX_SOURCE to unbreak the build on Cygwin. The build
on FreeBSD is fixed by additionally defining _POSIX_C_SOURCE, which is
required by fdopen.
2022-01-23 19:40:18 +00:00
Ulya Trofimovich e262466260 Adjust build script for non-multilib environments.
Instead of passing compiler and linker option -m32, call 32-bit compiler
binaries directly (prefixed with "i686-pc-linux-gnu-"). This allows one
to run the script on NixOS where it's hard to get a system-wide multilib
environment.
2022-01-23 10:48:49 +00:00
Ulya Trofimovich 85dab53916 Add missing header include. 2022-01-23 10:23:40 +00:00
Ulya Trofimovich 38a07a3304 Rust backend: add example of a C lexer contributed by Perry Metzger. 2022-01-22 20:51:56 +00:00
Ulya Trofimovich 039c189491 Emit an error when repetition lower bound exceeds upper bound.
Historically this was allowed and re2c swapped the bounds. However, it
most likely indicates an error in user code and there is only a single
occurrence in the tests (and the test in an artificial one), so although
the change is backwards incompatible there is low chance of breaking
real-world code.

This fixes second test case in the bug #394 "Stack overflow due to
recursion in src/dfa/dead_rules.cc" (the actual fix is to limit DFA size
but the test also has counted repetition with swapped bounds).
2022-01-21 23:30:04 +00:00
Ulya Trofimovich a3473fd7be Limit maximum allowed NFA and DFA size.
Instead of failing with an out of memory exception or crashing with a
stack overflow, emit an error message and exit. This is a partial fix
for bug #394 "Stack overflow due to recursion in src/dfa/dead_rules.cc",
where re2c hit stack overflow on a counted repetition regexp with high
upper bound.

The patch adds the following limits:
  1. the number of NFA states
  2. NFA depth (maximum length of a non-looping path from start to end)
  3. the number of DFA states
  3. total DFA size (sum total of all NFA substates in all DFA states)

There are tests for the first three limits, but not for the DFA size as
all examples that trigger this behavior take a long time to finish (a
few seconds), which increases test run time almost twice.
2022-01-21 21:58:20 +00:00
Ulya Trofimovich aa02264d2f More documentation updates (rewrote parts of different sections). 2022-01-20 08:23:09 +00:00
Ulya Trofimovich d9f431c9bd Small fixes in a few more examples.
- Add `assert` to the basic C example (to clarify the intent).
- Change `types:re2c` to its new alias `conditions:re2c`.
2022-01-19 07:38:06 +00:00
Ulya Trofimovich f3016baacb Restructure a few initial sections in the manual. 2022-01-15 20:10:02 +00:00
Ulya Trofimovich 638c1db7fc Update docs following recent example changes. 2022-01-15 19:06:24 +00:00
Ulya Trofimovich 37cfc0b63f Rust backend: add a test for function-like API.
Function-like API is difficult to use in Rust, because API primitives
cannot be defined as functions or hygienic macros (they do not accept
all the necessary parameters), and closures are problematic due to the
borrow checker (in this test `Cell` is used as a workaround).
2022-01-15 09:28:35 +00:00
Ulya Trofimovich c01efa343a Unify the basic example across language backends. 2022-01-15 09:26:22 +00:00
Ulya Trofimovich 4dc0a787ee Examples: avoid explicit YYFILL call when initializing lexer state.
Instead, add more comments explaining how the lexer state is initialized
and why YYFILL is triggered automatically.
2022-01-15 09:08:05 +00:00
Ulya Trofimovich 9054e09967 Docs: update configuration description. 2022-01-14 22:21:22 +00:00
Ulya Trofimovich ff18b2b5b4 Docs: describe new options and new aliases for old options. 2022-01-13 07:28:14 +00:00
Ulya Trofimovich 769ecc83c7 Docs: add initial documentation for Rust. 2022-01-12 08:52:37 +00:00
Ulya Trofimovich 87f0fb454b Docs: regenerate manpages for C and Go with updated examples. 2022-01-10 23:51:43 +00:00
Ulya Trofimovich 644a151070 Cosmetic fixes in examples for all backends. 2022-01-10 22:39:43 +00:00
Ulya Trofimovich e0c7d453e3 Rewrite POSIX captures example for C and Go backends. 2022-01-10 07:34:26 +00:00
Ulya Trofimovich 38226f2a6b Rust backend: add example of submatch extraction with POSIX captures. 2022-01-09 20:46:23 +00:00
Ulya Trofimovich 1d515be714 Rewrite m-tags example for C and Go backends. 2022-01-09 17:07:44 +00:00
Ulya Trofimovich b48833c5a7 Rust backend: add example of submatch extraction with m-tags. 2022-01-09 16:21:54 +00:00
Ulya Trofimovich ee88b9670a Rewrite s-tags example with YYFILL for C and Go backends. 2022-01-08 19:58:50 +00:00
Ulya Trofimovich f8aa528686 Rust backend: add example of submatch extraction with s-tags and YYFILL. 2022-01-08 19:58:50 +00:00
Ulya Trofimovich 552ba7e687 Rewrite s-tags example for C and Go backends.
The new example parses semantic versions, while the old one parsed
IPv4 addresses. The new example demonstrates a conditional tag, as the
last version part may be missing.
2022-01-07 23:03:28 +00:00
Ulya Trofimovich 2251d3813a Rust backend: add example of submatch extraction with s-tags. 2022-01-07 08:20:35 +00:00
Ulya Trofimovich 6df5cc4024 Rust backend: add another example of reuse mode (!use directive). 2022-01-06 08:36:52 +00:00
Ulya Trofimovich faffbd78a7 Rust backend: add example of reuse mode (use:re2c blocks). 2022-01-06 08:09:03 +00:00
Ulya Trofimovich f60aedbf65 Rust backend: add example with include directives. 2022-01-05 23:49:41 +00:00
Ulya Trofimovich 282fbc0791 Simplify example for autogenerated header feature (for C, Go, Rust). 2022-01-05 23:49:41 +00:00
Ulya Trofimovich bb27b0e6ef Rust backend: completely disable line directives.
This is necessary because some parts of codegen conditionally generate
newlines depending on the line directives option. In Rust mode, unless
line directives are disabled codegen generates redundant newlines (e.g.
for the `stags:re2c` directive).
2022-01-05 23:03:52 +00:00
Ulya Trofimovich 2d60c74d00 Rust backend: add example with an autogenerated header. 2022-01-05 08:42:35 +00:00
Ulya Trofimovich c05af363e6 Go backend: use loop label to avoid potential continue ambiguity. 2022-01-05 07:31:15 +00:00
Ulya Trofimovich ef05cd2bc0 Add configuration re2c:label:yyloop.
The default is empty for C or Go, and "'yyl" for Rust.
2022-01-04 23:30:46 +00:00
Ulya Trofimovich 58c71a9e3f Rust backend: use loop label to avoid potential continue ambiguity. 2022-01-04 23:17:06 +00:00
Ulya Trofimovich 3ec2e646fa Rust backend: add example with blocks (functions) instead of conditions. 2022-01-03 14:42:16 +00:00
Ulya Trofimovich cca31d2225 Do not generate redundant YYPEEK statements.
YYPEEK statement is redundant if the assigned `yych` value is
overwritten before it is read. This may happen if a state has a single
transition to a non-move state (so there is no need to match on `yych`).
Transitions to a move state is different because a move state does not
have its own YYPEEK (it relies on a previously read `yych` value).
2022-01-02 23:35:04 +00:00
Ulya Trofimovich 919570c46a Do not allocate indices for unused state labels (in goto/label mode).
This change affects nearly every test (with the exception of tests for
errors that abort before code generation, and tests that use loop/switch
approach that have been updated earlier).

Since the change affects so many tests, it is impossible to verify
manually, but skeleton tests pass (and they actually compile and run the
generated code).
2022-01-02 17:06:24 +00:00
Ulya Trofimovich 82b704f693 Do not allocate indices for unused state labels (in loop/switch mode). 2022-01-02 16:47:44 +00:00
Ulya Trofimovich a46f01e603 Do not generate YYDEBUG statements for unused states labels.
Currently DFA states with unused labels still have their own index, but
this will change soon and there won't be any state number to pass to
YYDEBUG. This patch prepares the code by removing YYDEBUG statements for
states with unused labels.

One exception is the initial label: it may be unused (if there are no
transitions into the initial state), but still have a valid index. Keep
YYDEBUG statements for the initial label as they may be useful.
2022-01-02 16:38:41 +00:00
Ulya Trofimovich 705e687028 Split label generation and numbering into separate passes.
Labels should be generated before DFA transitions, because the pass that
generates transitions performs used label analysis: for every transition
its destination state label is marked as used. However label indices
should be assigned after used label analysis, otherwise indices may be
assigned to unused labels.

This is particularly important with the loop/switch approach, as label
indices map to `yystate` switch cases which should have consecutive
numbers.

This patch does not change label numbering yet, it only prepares the
code for the change (so no tests are updated).
2022-01-02 15:42:44 +00:00
Ulya Trofimovich 99ff66bc23 Add run scripts for a few test directories.
The scrips heuristically check if a test is complete (can be compiled
and run as a standalone program) and if so, compiles and runs it.
2022-01-02 15:37:04 +00:00
Ulya Trofimovich 2e7935e569 Optimize loop/switch code: avoid redundant looping via yystate switch.
As long as the following state has no incoming transitions (its label is
unused), generate it as a continuation of the current state. This avoids
looping through the `yystate` switch only to return to the next case.

The optimization is based on used label analysis for DFA state labels.
2021-12-31 23:22:17 +00:00
Ulya Trofimovich 51d3808418 Move used label analysis before the actual codegen.
This is necessary in order to generate better code with loop/switch
(avoid looping through the `yystate` switch in cases when the only
transition from a DFA state goes to the state immediately following the
current one). For that we need to know which DFA states are used (have
incoming transitions) before actually generating them.

Previously used label analysis was needed only to avoid generating
unused labels with goto/label approach. Since the decision whether to
output a label or not is taken at a late stage in codegen, it was ok to
perform the analysis when generating the states. With the loop/switch
approach this is no longer sufficient.

This patch moves used label analysis to an earlier codegen pass. A few
special labels are still handled at a late phase (such as the start
labels of blocks, some of which are only marked as used after expanding
`getstate` directives). These few exceptions do not affect DFA state
labels that matter for the loop/switch approach.
2021-12-31 23:22:17 +00:00
Ulya Trofimovich 1d72fbe950 Rust backend: add a Unicode example. 2021-12-28 12:48:10 +00:00
Ulya Trofimovich 0fcedefbfb Rust backend: emit correct code with -s, --nested-ifs option.
In Rust there is no implicit coersion between `u8` and `char` literals,
so it is necessary to emit hexadecimal literals in `yych` comparisons.
2021-12-28 12:21:24 +00:00
Ulya Trofimovich 005cdc7b84 Rust backend: add YYFILL example. Refactor examples for other backends.
Try to make YYFILL examples coherent across different backends.
2021-12-27 22:24:13 +00:00
Ulya Trofimovich d191cd86ac Rust backend: use isize as condition type in storable state mode.
With storable states `yystate` may have value -1, so it needs to have
signed type. Conditions have the same type as they are assigned to
`yystate`.

Also add a test for the combination of storable state and conditions.
2021-12-27 14:50:42 +00:00
Ulya Trofimovich d40ed35011 Rust backend: always generate braces around if body. 2021-12-27 13:37:58 +00:00
Ulya Trofimovich 8727e11e85 Emit better code for -1 state in loop/switch mode.
In loop/switch mode case -1 should be the same as case 0. Previously
the generated code handled these two as different cases, but they should
be handled as one case with a range of values.

This commit allows using ranges not only for characters (the switch on
`yych`), but also for numbers (the switch on `yystate`). In storable
state mode -1 is appended to the range of the first case 0.
2021-12-27 13:37:58 +00:00
Ulya Trofimovich 32a757f84c Rust backend: add an example for storable state. 2021-12-27 13:37:58 +00:00
Ulya Trofimovich 1bd47e0244 Rust backend: in storable state mode handle -1 state correctly.
With loop/switch approach (which is implied for the Rust backend) case
-1 is the same as case 0. Normally this is handled by falling through
from case -1 to case 0, but since Rust doesn't have fallthrough it is
necessary to set `yystate` to 0 and loop back to the head of the switch.
2021-12-27 12:06:30 +00:00
Ulya Trofimovich 87f335c560 Correctly parse single-line comments in indented semantic actions.
Semantic actions that start with `:=` are not enclosed in curly braces,
so re2c uses indentation to find the end of user-defined code: as long
as a line has nonzero indentation it is parsed as a continuation of
semantic action. In order to do that re2c needs to analyze if a newline
is followed by a whitespace. Previously this analysis was missing in the
case of newlines in single-line comments.
2021-12-24 21:38:00 +00:00
Ulya Trofimovich dba7d055aa Restrict lexical contexts where %{ is recognized as a block start.
As Krishna noticed in bug #392 "Cannot compile when user c string has a
special pattern", `%{` in the middle of a string makes re2c think that
this is a start of a re2c block. The user has to braek the string in two
in order to separate `%` from `{`.

The problem is exacerbated by the fact that `%{` does not require -F,
--flex-support option. It affects all re2c programs.

In general re2c cannot be sure if `%{` appears in the middle of a
string, a comment, a macro defintion or some other lexical context where
it is a part of a larger lexeme and not a standalone block start marker.
This is because re2c doesn't parse user-defined code in-between re2c
blocks (doing that would require implementing multiple language
frontends in re2c, which is out of the question).

This commit mitigates the problem in #392 by restricting lexical context
wheer `%{` is recognized as a block start: the marker must be on a new
line, optionally preceded by whitespace characters. This does not cover
all the cases and it may break some re2c programs that used block start
`%{` in other lexical contexts, but it is a reasonable compromise
between usability and backards compatibility.
2021-12-24 14:20:32 +00:00
Ulya Trofimovich 92c1a456ae Github Actions: fix path for uploading artifacts when the build fails.
Reorder steps so that 'Get build dir' step is executd before build and
test steps. Otherwise if the build or test steps fail, subsequent steps
are skipped and the path for uploading artifacts is not set properly.
2021-12-19 11:46:27 +00:00
Ulya Trofimovich f80c4995de Update configuration names in examples. Cosmetic formatting changes. 2021-12-19 11:46:27 +00:00
Ulya Trofimovich 0716f1d59b Use option alias --header instead of --type-header in tests and examples. 2021-12-19 11:46:27 +00:00
Ulya Trofimovich 886b73af33 Provide simpler names for some re2c options.
For example, --type-header should be just --header: it used to be for
`/*!types:re2c*/` directives initially, but after the addition of
`/*!header:re2c...*/` it may contain anything.

Also, --input is confusing and should be --api, as we refer to this as
"generic API" or "default API" in the documentation.
2021-12-19 11:46:27 +00:00
Ulya Trofimovich 091df3ab02 Update message for -Wcondition-order warning. 2021-12-17 23:02:04 +00:00
Ulya Trofimovich ad2ddd249c Add directive conditions:re2c (an alias for types:re2c).
Also guard against confusing error when instead of a local block
`local:re2c` the user specifies a named block `re2c:local`.
2021-12-17 22:41:35 +00:00
Ulya Trofimovich 45dbbe88b1 Revise re2c configurations, provide simpler aliases for some.
Configurations have evolved over time, and some of the names are quite
illogical. For example `re2c:flags:tags` should be just `re2c:tags`,
and `re2c:flags:unicode` should be `re2c:encoding:utf-32`. While we
cannot remove the old names (that would break existing programs), we can
still provide simpler and more logical aliases.

Take that opportunity to clean up configuration lexer a bit.
2021-12-17 22:02:42 +00:00
Ulya Trofimovich 4c88da02c5 Add option --no-unsafe and configuration re2c:flags:unsafe.
This allows to suppress generation of `unsafe { ... }` wrapper around
YYPEEK (for the Rust backend). Normally YYPEEK should avoid bounds
checks, as the lexer already does them (and goes to great lengths in
order to minimize the number of checks). However it may be useful to
enable bounds checks in YYPEEK for debug purposes, or just extra safety.
In that case the new option/configuration is needed to avoid warnings
emitted by the Rust compiler about redundant `unsafe`.

Also extend the script that compiles and runs examples for Rust to run
each test twice: first with the unsafe YYPEEK definition, and second
time after patching it to avoid `unsafe`. This allows to check that the
examples do not have trivial memory errors.
2021-12-15 22:53:26 +00:00
Ulya Trofimovich f081edd09e C backend: fix a memory leak in one of the examples.
Build and run examples with LeakSanitizer and AddressSanitizer.
2021-12-15 22:45:27 +00:00
Ulya Trofimovich 01a46937a0 Rust backend: avoid redundant braces around sematic actions.
Normally sematic are surrounded by line directives, so they occupy
multiple lines and should be wrapped in curly braces. In Rust there are
no line directives, but the codegen was still confused by empty stubs
and rendered semantic actions as multiline code blocks.

In order to fix this, it was necessary to separate removal of empty
code blocks into a separate pass (previously it was a part of `combine`,
but `combine` is too specialized and does not remove all empty blocks).
2021-12-14 00:17:56 +00:00
Ulya Trofimovich 0575cf7291 Rust backend: suppress warnings about unused yych initializer.
It is necessary to initialize `yych` (even though the initial value will
never be used) because in Rust a potentially uninitialized variable is a
compilation error. However, in cases when the compiler is able to see
that the variable is overwritten on all code paths, it instead emits a
warning about unused assignments.

Suppress the warning with `#[allow(unused_assignments)]`.
2021-12-13 23:26:16 +00:00
Ulya Trofimovich 0ff77971aa Rust backend: add an example for conditions. 2021-12-13 22:28:09 +00:00
Ulya Trofimovich c9eb8622c3 Rust backend: fix codegen for condition enum.
Generate standalone constants for each condition instead of an enum in
order to avoid casting to `yystate` type on each operation.
2021-12-12 19:22:39 +00:00
Ulya Trofimovich ed88e12e60 C backend: change formatting of switch statements.
Do indent cases with the default indent string. Do not auto-align cases
that fit on one line with tabs, use a single space before the case body.
Tab alignment didn't work very well and required special handling (for
example with --case-ranges it had to be turned off, because case length
varies more than one tab).

Over a thousand of tests were updated, but all the changes are trivial.
2021-12-11 20:53:52 +00:00
Ulya Trofimovich 4131ae7244 Rust backend: add YYFILL example with re2c:eof. 2021-12-11 10:21:28 +00:00
Ulya Trofimovich 48f2a0ca10 Rust backend: add end-of-input example with generic API and re2c:eof. 2021-12-09 22:20:55 +00:00
Ulya Trofimovich 0c2dfbdd96 Rewrite Go examples to be normal programs with main rather than tests.
Also delete a useless configuration YYLESSTHAN in one example.
2021-12-08 23:46:02 +00:00
Ulya Trofimovich 6715a02339 Cosmetic fixes in the C examples (also delete a useless configuration). 2021-12-08 00:26:15 +00:00
Ulya Trofimovich 7a1d0aaf2d Rust backend: add end-of-input example with generic API and sentinel. 2021-12-07 22:39:38 +00:00
Ulya Trofimovich de5e439187 Rust backend: add a re2c:eof example. 2021-12-07 22:22:31 +00:00
Ulya Trofimovich 62c3c6a567 Rust backend: wrap YYPEEK in unsafe rather than the whole lexer.
Also restructure YYPEEK generation to avoid code duplication.
2021-12-06 23:40:22 +00:00
Ulya Trofimovich 9df4c535e9 Fix unused variable warning in non-debug mode. 2021-12-06 22:05:19 +00:00
Ulya Trofimovich 7a4b317288 Rust backend: fix YYMAXFILL generation, add a bounds-checking example. 2021-12-06 21:50:27 +00:00
Ulya Trofimovich 297ee84733 Clean up if-then-else code generation and fix it for Rust. 2021-12-06 07:31:58 +00:00
Ulya Trofimovich 92276e73a2 Rust backend: add example for sentinel-based end-of-input check. 2021-12-04 21:07:51 +00:00
Ulya Trofimovich 1501b4df45 Correctly lex Rust code with standalone single quotes.
When lexing code blocks we need to lex string literals because they may
contain closing brace symbol that would otherwise be erroneously lexed
as a real closing brace.

However, single quote in Rust may be either the beginning of a char
literal as in '\u{1F600}', or a standalone one as in 'label. In the
latter case trying to lex a generic string literal will consume a
fragment of the file until the next single quote (if any) and result in
either a spurios parse error, or incorrect generated code. Therefore in
Rust we try to lex a char literal, or else consume the quote.
2021-12-04 20:57:54 +00:00
Ulya Trofimovich 9198728b43 Rust backend: wrap lexer in "unsafe" to avoid it in user-defined code. 2021-12-04 16:53:11 +00:00
Ulya Trofimovich d5bbfbd41d Adjust Github Actions config and CMake presets for re2rust. 2021-12-04 09:15:36 +00:00
Ulya Trofimovich 0c0d674e1d Rust backend: add the first (working) example. 2021-12-04 09:09:22 +00:00
Ulya Trofimovich 27b0008c56 Adjust testing script for Rust. 2021-12-04 09:08:49 +00:00
Ulya Trofimovich 01046e779c Autotools: build re2rust (option RE2C_BUILD_RE2RUST is on by default).
Documentation is yet to be done, so do not add build rules for it.
2021-12-04 09:08:25 +00:00
Ulya Trofimovich 3c02670f0f CMake: build re2rust tool (option RE2C_BUILD_RE2RUST is on by default).
Documentation is yet to be done, so do not add build rules for it.
2021-12-04 09:08:25 +00:00
Ulya Trofimovich 59e3223d0d Rust backend: add support for basic cases. 2021-12-03 23:59:55 +00:00
Ulya Trofimovich 09161b1444 Go backend: render continuous character ranges in compact form.
Use a comma-separated list instead of multiple switch cases.
2021-12-03 23:38:12 +00:00
Ulya Trofimovich e7ffdc5574 Small cleanup in codegen function that renders switch cases.
The only updated test has insignificant changes (comment moved before
the colon in `case ... :`).
2021-12-03 23:17:58 +00:00
Ulya Trofimovich 4937938362 Use abstract variable types in codegen. 2021-12-02 23:21:11 +00:00
Ulya Trofimovich 7e21423866 Abort in the default case in loop/switch mode.
Except for C/C++ when `re2c:state:abort` is not set, as `abort()`
requires including a header, which we don't want to enforce on the user.
2021-12-02 22:36:09 +00:00
Ulya Trofimovich 38f2d1fcd4 Add option stub --lang rust (currently generates incorrect code). 2021-12-01 22:29:53 +00:00
Ulya Trofimovich 987e7e17c3 Add a test for loop/switch used with storable state and conditions. 2021-12-01 22:09:19 +00:00
Ulya Trofimovich 2c0dd72332 Always generate YYSETSTATE in final states in storable state mode.
If the user has an outer loop that goes via YYGETSTATE switch, they
would expect the next iteration of the loop to start from the intiial
state rather than from some YYFILL state left after the last YYFILL
invocation. This especially matters when there is no explicit
`getstate:re2c` and no user-defined code between the YYGETSTATE switch
and the lexer entry (which is always the case in loop/switch mode).

A lot of (54) tests have been updated (they now have additional
YYSETSTATE invocations). One of them (conditions/condition_08_cbif.c)
previously resulted in a crashing program on input file "??(??)", and
now due to the addition of YYSETSTATE it doesn't crash.

Also, use state -1 rather than 0 as the default one in loop/switch mode.
Although it is safe to use 0 (cases always start from zero), using -1 is
unifies it with goto/label mode, where 0 cannot be used (start label
does not have to be `yy0`). And -1 is always safe for both modes, as
the YYGETSTATE switch always has either a default case or an explicit -1
case that goes to the initial state.
2021-11-30 23:53:38 +00:00
Ulya Trofimovich d308e4ed6f Store Msg reference in Opt to give options access to warnings.
Options are managed by `Opt`, and warnings are managed by `Msg`. Both
are created in `main` and have the lifetime of the whole program, so it
is not difficult to connect them.
2021-11-28 21:04:41 +00:00
Ulya Trofimovich 61af1763fd Add missing <assert.h> include. 2021-11-28 18:12:02 +00:00
Ulya Trofimovich edf3cbbd3e CMake: create output directory before building docs.
Previously trying to run rst2man.py with an output file in a nonexistent
directory resulted in the following build error:

  $ cmake --preset=linux-gcc-debug-ootree-skeleton-full
  $ cmake --build --preset=linux-gcc-debug-ootree-skeleton-full
  ...
  [  1%] Generating src/msg/help.cc
  Unable to open destination file for writing:
    OutputError: [Errno 2] No such file or directory:
      '[...]/linux-gcc-debug-ootree-skeleton-full/src/msg/help.cc.1'
2021-11-28 18:03:29 +00:00
Ulya Trofimovich 06c85fb955 CMakePresets.json: inherit "full" configuration before "fast".
Otherwise variable definitions from "fast" configuration take precedence
over the "full" configuration, resulting in disabling some important
configrations, such as Go language support.

For example, if "fast" is inherited before "full" we have the following
incorrect configrations that sets RE2C_BUILD_RE2GO:BOOL="FALSE":

  $ cmake -S .. --preset=linux-gcc-release-ootree-skeleton-full
  Preset CMake variables:

    CMAKE_BUILD_TYPE="Release"
    CMAKE_CXX_COMPILER="g++"
    CMAKE_C_COMPILER="gcc"
    CMAKE_INSTALL_PREFIX:PATH="[CUT]/re2c/install"
    RE2C_BUILD_LIBS:BOOL="TRUE"
    RE2C_BUILD_RE2GO:BOOL="FALSE"
    RE2C_FOR_BUILD="[CUT]/re2c/install/bin/re2c"
    RE2C_REBUILD_DOCS:BOOL="TRUE"
    RE2C_REBUILD_LEXERS:BOOL="TRUE"

But if "full" is inherited after "fast" we have the following (correct):

  $ cmake -S .. --preset=linux-gcc-release-ootree-skeleton-full
  Preset CMake variables:

    CMAKE_BUILD_TYPE="Release"
    CMAKE_CXX_COMPILER="g++"
    CMAKE_C_COMPILER="gcc"
    CMAKE_INSTALL_PREFIX:PATH="[CUT]/re2c/install-2"
    RE2C_BUILD_LIBS:BOOL="TRUE"
    RE2C_BUILD_RE2GO:BOOL="TRUE"
    RE2C_FOR_BUILD="[CUT]/re2c/install/bin/re2c"
    RE2C_REBUILD_DOCS:BOOL="TRUE"
    RE2C_REBUILD_LEXERS:BOOL="TRUE"
2021-11-28 16:49:44 +00:00
Ulya Trofimovich 2d28bfea79 Make --loop-switch work with conditions.
Merge all conditions in one loop/switch where DFA for each condition has
its own set of cases. Use `yystate` variable to switch between
conditions in the same way as between DFA states.

The => rules set user-defined condition variable with YYSETCONDITION.
The :=> rules set `yystate` and continue to the head of the loop/switch.
2021-11-28 16:49:44 +00:00
Ulya Trofimovich 9d58618750 Respect define:YYGETSTATE:naked configuration in loop/switch mode. 2021-11-28 16:49:44 +00:00
Ulya Trofimovich c38c965434 For skeleton and .dot targets merge header file into the output file.
Header file may contain blocks with regular expressions and rules. They
should be handled as well as the blocks in the output file.

This patch fixed a failing skeleton test.
2021-11-28 16:49:40 +00:00
Ulya Trofimovich 96cacc78c0 Use initial state indices as condition numbers with --loop-switch.
Normally with the goto/label approach condition enumeration uses
implicit consecutive indices starting from zero. With the loop/switch
approach it is more convenient to represent conditions with their
initial DFA state index. This allows one to assign condition numbers to
the state variable `yystate` and get rid of the entry condition switch.
2021-11-28 16:48:30 +00:00
Ulya Trofimovich 6f2801248c Factor out block list construction into a separate function. 2021-11-28 16:48:30 +00:00
Ulya Trofimovich cbc33f36f5 Delay YYMAXFILL / YYMAXNMATCH computation until handling the directive.
The `maxfill:re2c` and `maxnmatch:re2c` directives may specify an
optional list of block names. If the list is specified, the directives
compute maximum value over the specified blocks, otherwise they compute
global maximum across all blocks in the program.

Previously the global maximum was prepared in advance even if the
directives were not used. This patch delays the computation of global
YYMAXFILL / YYMAXNMATCH until they are needed, as is already done in
the case when the directive specifies a list of blocks.
2021-11-28 16:48:30 +00:00
Ulya Trofimovich 41f503de5d Delay global tag list construction until handling the directive.
The `stags:re2c` and `mtags:re2c` directives may specify an optional
list of block names. If the list is specified, the directives gather
condition nems from the specified blocks, otherwise they use a global
set of tag names gathered across all blocks.

Previously the global set was prepared in advance even if the directives
were not used, but a set for specific block list was constructed only if
needed. This patch delays global set construction until it is needed and
unifies it with the case of a specific block list.
2021-11-28 16:48:30 +00:00
Ulya Trofimovich 64405f6f62 Do not autogenerate condition enum if there is an explicit types:re2c.
The rationale is, if the user specified an explicit `types:re2c`
directive, they probably do not want the autogenerated enum as well. If
for some reason they need multiple enum definitions (either in the
output file or in the header file), they can use multiple `types:re2c`
directives.
2021-11-28 16:48:26 +00:00
Ulya Trofimovich 64961bf692 Search for named blocks both in the output file and in header.
This fixes a test for condition enum: previously re2c emitted an error
because one of the `types:re2c` directives listed block name for a block
defined in another file, and re2c failed to find it. Now it finds it.
2021-11-28 16:46:56 +00:00
Ulya Trofimovich 9fdd7fca0b Do not generate empty condition enum.
Some compilers or language standards allow it, but generally it's more
likely to indicate an error in user code.

Fix a few tests that generated empty condition enum by mistake.
2021-11-28 16:46:56 +00:00
Ulya Trofimovich eb30417eed Clean up old tests for condition enum and header.
Replace a bunch of simple and similar tests with a few more
comprehensive ones that cover recent re2c features like named blocks and
block lists in the `types:re2c` directive, in addition to older features
such as the --type-header option.

One of the new tests reveals an error in re2c: it fails to find
conditions in header. The error will be fixed in a follow-up commit.
2021-11-28 16:46:56 +00:00
Sergei Trofimovich a6220b8f4b avoid using reserved identifiers (underscores)
clang with -Weverything detects these as:

    ./src/util/free_list.h:9:16:
      warning: identifier '_Ty' is reserved
      because it starts with '_' followed by a capital letter [-Wreserved-identifier]
    template<class _Ty>
                   ^
2021-11-28 16:46:56 +00:00
Sergei Trofimovich bbb9dae8a3 fix struct/class declaration mismatch (-Wmismatched-tags)
Detected by clang's-Weverything:

    ./src/regexp/re.h:17:1: warning: struct 'Msg' was previously declared as a class;
      this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags]
    struct Msg;
    ^
2021-11-28 16:46:56 +00:00
Ulya Trofimovich 53259db5e7 Make --loop-switch work with storable state.
With the loop/switch approach there is no `goto` statement, so it is
impossible to jump from a `getstate:re2c` block to an YYFILL label,
bypassing all the user-defined code in the middle (as it normally
happens with the goto/label approach).

Therefore `getstate:re2c` is forbidden with --loop-switch, and the
initial switch on storable state is merged into the `yystate` switch:

  - case -1 falls through to case 0 (the initial state)

  - transitions to YYFILL states are moved to cases that occupy
    contiguous numbers after the last regular DFA state

In order to make it possible to wrap the generated lexer in a
user-defined loop, an `YYSETSTATE(1)` statement is emitted in each final
state before the user-defined semantic action: if the action jumps to
the head of the outer loop, the next iteration will start from state -1,
as the user might expect. Note that `YYSETSTATE(1)` is not needed with
goto/label approach, because one can jump directly to the start label.
2021-11-28 16:46:56 +00:00
Ulya Trofimovich 28bc929bb6 Make --loop-switch and --eager-skip options non-configurable.
Having configuration for the --loop-switch option is only useful if one
needs to enable loop/switch approach on a per-block basis. Mixing the
two approaches (goto/label and loop/switch) would mean that some of the
blocks have start labels and can use cross-block transitions, while
others cannot. This would create confusion for whole-program directives
like `getstate:re2c` that cover multiple blocks.

With the loop/switch approach `getstate:re2c` should be forbidden, as it
requires a cross-block transition from the state switch to the lexer
entry, which is unsupported in the absence of the `goto` statement.
2021-11-28 16:46:52 +00:00
Ulya Trofimovich 031ddb7bb8 With --loop-switch, start state enumeration from zero in each block.
Normally with the goto/label approach re2c uses a program-wide state
enumeration that starts from zero and increases with each block. Since
each state has a label, global enumeration allows one to have multiple
blocks in the same function without the risk of label collision.
Moreover, different blocks can be connected with cross-block `goto`
transitions, so all state labels should have different numbers.

The situation is different with the loop/switch approach: there are no
labels and no cross-block `goto` transtions; instead every state has a
switch on the `yystate` variable. Since different block have different
switches, it makes sense to start state enumeration from zero in each
block (so that switch cases start from zero, and the zeroth case
corresponds to the start state of every block).
2021-11-28 16:41:17 +00:00
Ulya Trofimovich 8d219a6b27 Drop useless -c option in some of the Go examples.
These examples do not use conditions, so -c does nothing. It has been
accidentally copy-pasted from another example that uses conditions.
2021-11-28 16:41:17 +00:00
Ulya Trofimovich 1c244eb19b Add tests for the new --loop-switch option (for C and Go backends).
The added tests are copy-pasted from examples, but the generated code is
different: it uses loop/switch constructs instead of goto/label. All
tests except for conditions and storable state are valid programs that
can be compiled and run without errors.
2021-11-28 16:41:17 +00:00
Raekye c74080e656 Initial implementation of the --loop-switch option.
With this option, instead of the usual goto/label approach DFA is
wrapped in a loop with a `switch` statement on `yystate` variable. Each
DFA state is an individual `case`. Transitions between states are done
by setting the `yystate` variable to the numeric index of the target
state and executing `continue` that jumps to the head of the loop and
goes via the `switch` again. This is less efficient than direct jumps
with the goto/label approach, but it is the only way we can implement a
DFA for languages that do not have `goto` statement (such as Rust).

YYFILL labels are problematic for the loop/switch approach, because they
are normally in the middle of a DFA state (after the YYSKIP operation,
but before YYPEEK and transitions to other states). To fix this, we use
the --eager-skip option that moves YYSKIP operations from DFA states to
transitions.

The initial value of `yystate` is the numeric index (label) of the first
DFA state. It is _not_ the intiial label, because initial label does not
have a state (so there is no `case` in the `switch` for it), and it is
only needed to bypass YYSKIP operation in the first DFA state (which is
not there anyway because of the --eager-skip option).

Current limitations:
  - Conditions are not supported. We need a per-condition `yystate`, and
    ideally transitions between conditions should also use a loop/switch
    approach instead of goto/label (it will be required for Rust, but it
    is optional for C and Go).

  - Storable state is not supported. We need to rewrite user-defined
    code to use the same state variable as `yystate` and the one in
    `YYGETSTATE`/`YYSETSTATE`, as well as to put `getstate` block
    immediately before DFA entry (if there is any code between state
    dispatch and DFA entry, it needs to be bypassed when re-entering
    the lexer after YYFILL, which is easily done with goto/label
    approach in C and Go, but not in Rust that has no `goto`).

Test results with the --loop-switch option enabled by default:
  - Skeleton tests pass (320 soft errors).

  - Examples for C and Go compile and run without errors, except for
    conditions, storable state and cases when user-defined code needs to
    be rewritten (e.g. when it uses an outer loop and `continue`/`break`
    statements end up referring to the wrong loop).
2021-11-28 16:41:17 +00:00
Raekye cba165c27b Don't generate initial label if --eager-skip option is used.
The initial label is not needed in such cases as there is no need to
bypass YYSKIP statement (--eager-skip moves it from states to
transitions).
2021-11-28 16:41:17 +00:00
Raekye e73b93f61f Add stubs for --loop-switch option and related configurations.
The following has been added:
  - option --loop-switch
  - configuration `re2c:flags:loop-switch`
  - configuration `re2c:variable:yystate`

Currently they are no-ops.
2021-11-28 16:41:17 +00:00
Raekye 8011459a1e Move --eager-skip option from constant to mutable.
This is necessary to support the future --loop-switch option.

With --loop-switch we cannot have labels (goto targets) in the middle of
a state. This affects YYFILL labels which normally go after YYSKIP but
before YYPEEK. The --eager-skip option resolves the problem by moving
YYSKIP statements from states to transitions. The plan is to enforce it
automatically if --loop-switch is enabled, but since --loop-switch will
be a mutable option, --eager-skip also needs to be mutable.
2021-11-28 16:41:17 +00:00
Raekye 6695fcd3af Skeleton: use goto-loop instead of for-loop.
To support the future --loop-switch option, this change avoids
unexpected control flow with `continue`.

The skeleton tests are verified and updated.
2021-11-28 16:41:17 +00:00
Ulya Trofimovich 5ac98bc208 Correctly handle nested include files with identical paths.
The previous commit fixed bug #386 "#line directives around !include
contents" by reading every include directive twice: for the first time
on entry (when the file is included), and for the second time on exit
(when the file has been processed).

However that commit used a crude criterion to distinguish the first and
the second times: it compared the include file path (specified in the
include directive) to the path of the file on top of the stack. This
doesn't work for nested include files that have the same relative path.

This patch adds a test and fixes the problem by using a different
criterion: it checks if the parent file is topmost after popping all
finished files from stack (the comments in src/parse/scanner.cc explain
why this works in detail).
2021-11-28 11:29:41 +00:00
Ulya Trofimovich 48e83fcaab Mark start and end of included .re files with line directives.
This fixes bug #386 "#line directives around !include contents"
reported by Cyan Ogilvie.

It is easy to generate line directive at the beginning of the include
file, but much more difficult to find the end of it: file contents are
just a stream of bytes in the input buffer, and the continuation of the
parent file follows immediately after the end of the inlude file.

Therefore we use a hack and "unread" the include directive in the parent
file before filling the buffer with the contents of the include file (as
if the include directive appeared after the contens of include file).
This makes the lexer read the directive for the second time; at this
point we know it's the same include directive because the include file
is already on top of the file stack. So we ignore the directive and
simply generate line info.

The current implementation has a problem with nested includes that have
identical relative file paths. This will be fixed in a follow-up patch
by looking at the resolved paths when comparing files.
2021-11-27 12:16:48 +00:00
Ulya Trofimovich 7c6b5c955e Generate non-overlapping names for s-tag and m-tag variables.
This fixes bug #385 "mtag/stag automatic variable generation collision"
reported by Cyan Ogilvie.

Previously s-tag and m-tag variables used non-overlapping numbers
within a single DFA. With start conditions this is insufficient, as
variables in different conditions (DFAs) may have identical numbers.

If both tag variables are single-valued, or if they are both
multi-valued, having one variable is fine: there are no transitions to
or from the middle of DFA, so tag variables in different conditions are
never used at the same time.

However if one of the variables is single-valued and the other one
multi-valued (or vice versa), they cannot share the same tag variable.
To avoid collision in such cases, this patch gives m-tag variables an
extram "m" affix that makes them different from any s-tag variable.
S-tag variables do not get an "s" affix primarily to avoid updating over
600 tests. Tag variables are internal to re2c and the user should not
use them directly, so this change does not break user code.
2021-11-23 23:25:14 +00:00
Ulya Trofimovich 68e1ab7160 Correctly compute fixed tags in trailing context.
Tags in trailing context may be fixed on the rightmost cursor position.
Their values must be updated before cursor is reset to the position of
the trailing context, otherwise the values would be incorrect.
Previously this was not so, which resulted in incorrect tag values.

This fixes bug #380 "Tags incorrectly set with lookahead" reported by
Terry Sanders .
2021-11-04 23:51:01 +00:00
Ryan Mast 8920ef895b Setup Java for the benchmarks workflow using actions/setup-java 2021-11-02 07:25:00 +00:00
Perry E. Metzger 73dc6295a7 minor fixes to interface.rst_
Improve grammar, make some small style improvements, and keep the
lines consistently under 80 columns. Also update boostrap docs for
resulting changes.
2021-10-31 20:30:35 +00:00
Ulya Trofimovich 6d7c3cbb47 Small fixes in distcheck script.
Changes:
  - use 'sh' instead of 'bash' as interpreter
  - split build into stages 1 and 2 and rebuild lexers at stage 2
  - double-quote shell variables to make shellcheck happy
2021-10-24 13:10:47 +01:00
Ulya Trofimovich 072d49e59c Autotools: link google-benchmark binaries with pthread. 2021-10-22 16:52:36 +01:00
Ulya Trofimovich eb8720d5ea Use unsigned integers for register versions in TDFA states.
Previously we used negative numbers for register versions that were
allocated for transitions on negative tags. This is pointless, because
state mapping may biject positive versions to negative ones or vice
versa, erasing the distinction. And it wasn't used anyway.
2021-09-15 22:42:55 +01:00
Ulya Trofimovich b90b78c79c Mark each register as not interfering with itself.
Exclude diagonal pairs from interference table. This does not affect
subsequent register allocation, because the algorithm that partitions
registers into non-interfering classes does not check is a register
interferes with itself. So the fix does not affect the generated code,
except for one test that draws the interference table.
2021-09-04 09:41:08 +01:00
Ulya Trofimovich 6b434e934c run_tests.py: make tests fast again by fixing Wine check.
Commit ec1dc2b3ec incorrectly compared
Wine path against `None` to determine if the tests run under Wine. That
doesn't work as expected because the default value is empty string, not
`None`, so the checks always succeeded and as a result the script did
unnecessary work (patched newlines in the generated output). That made
it a few times slower.
2021-09-04 09:16:04 +01:00
Biswapriyo Nath 15376f4393 Define _POSIX_SOURCE for fdopen in cygwin
This fixes the error:
error: ‘fdopen’ was not declared in this scope; did you mean ‘fopen’?
2021-09-03 16:35:42 +01:00
Serghei Iakovlev dff1b6cd36 Provide support of CMake Presets
Since 3.19.8 CMake looks in the top source directory of a project for files
named CMakePresets.json and CMakeUserPresets.json. Neither file is required
to be present, but if the user tries to list or use presets, at least one of
the files must exist. If both files are present, they will effectively be
merged by reading the CMakePresets.json file first and then the
CMakeUserPresets.json file.

CMakePresets.json can be used to define presets for things like continuous
integration jobs or cross-compilation setups using toolchains provided as
part of the project. In general this feature allows us to simplify CI
configuration phase by taking out all the logic into presets-file and helps
us to make reproducible builds. From now on, you no longer need to carefully
read and copy all the flags locally in order to reproduce CI configuration or
build. Simple use the same one line command as at CI.

As a bonus, users of modern CMake can use a cross-platform and portable way
instead of build/__cmake*.sh scripts.

To see the list of available presets use:
    cmake --list-presets

To configure re2c use:
    cmake --preset=<NAME>

To build re2c use:
    cmake --build --preset=<NAME>

To test re2c use:
    cmake --build --preset=<NAME> --target tests

References:

- https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html
- https://gitlab.kitware.com/cmake/cmake/-/issues/21164
- https://cmake.org/cmake/help/latest/guide/user-interaction/index.html#presets
2021-08-12 12:30:44 +01:00
Ulya Trofimovich aa2da70299 Release 2.2. 2021-08-01 10:05:50 +01:00
Ulya Trofimovich cf13205c63 Update CHANGELOG. 2021-08-01 08:34:40 +01:00
Ulya Trofimovich ec1dc2b3ec run_tests.py: patch newlines under Wine and get rid of Wine warnings. 2021-07-31 20:42:52 +01:00
Ulya Trofimovich a9ba2c4d91 Add forgotten includes to make headers self-contained. 2021-07-31 20:42:52 +01:00
Ulya Trofimovich 36e4a0e5ee run_tests.py: use a local reimplementation of shutil.copytree.
We need to copy multiple directories (test/ and examples/) into one
(temporary test directory). `shutil.copytree` is problematic for two
reasons:

 1) it requires `dirs_exist_ok` parameter which was added only in
    python-3.8

 2) `make distcheck` fails when trying to copy the second directory
    because it makes source files read-only
2021-07-31 09:10:28 +01:00
Ulya Trofimovich a779585cb3 split_man.sh: allow substitution RE2C_LANG_NAME -> {C,Go}. 2021-07-31 09:10:28 +01:00
Ulya Trofimovich 53ee23a54f Update docs: rewrite the introduction section of the manual. 2021-07-25 21:13:51 +01:00
3132 changed files with 1439509 additions and 1384118 deletions
+2
View File
@@ -0,0 +1,2 @@
* text=auto
test/newlines/** -text
+5 -3
View File
@@ -33,15 +33,15 @@ jobs:
steps:
- name: Checkout Code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/setup-python@v3
with:
python-version: '3.8'
- name: Setup Java
uses: actions/setup-python@v2
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '11'
@@ -52,6 +52,7 @@ jobs:
Linux*)
echo "CC=gcc" >> $GITHUB_ENV
echo "CXX=g++" >> $GITHUB_ENV
sudo apt update
sudo apt install libre2-dev libbenchmark-dev
;;
macOS*)
@@ -71,6 +72,7 @@ jobs:
-G "Unix Makefiles" \
-DRE2C_BUILD_LIBS=ON \
-DRE2C_BUILD_RE2GO=OFF \
-DRE2C_BUILD_RE2RUST=OFF \
-DRE2C_BUILD_BENCHMARKS=ON \
-DCMAKE_CXX_FLAGS="-O3"
+158
View File
@@ -0,0 +1,158 @@
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@v3
- name: Setup apt cache (Linux)
if: startsWith(runner.os, 'Linux')
uses: actions/cache@v3
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@v3
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-golang \
--disable-rust \
--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@v3
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
+177
View File
@@ -0,0 +1,177 @@
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@v3
- name: Setup chocolatey Cache (Windows)
if: startsWith(runner.os, 'Windows')
uses: actions/cache@v3
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@v3
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@v3
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="$(pwd)/.build/${{ matrix.name }}-full"
else
BUILD_DIR="$(pwd)"
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@v3
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
-276
View File
@@ -1,276 +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
generator: Unix Makefiles
build-type: Ubsan
build-dir: .build
cxx-flags: -O2
skeleton: ${{ false }}
- name: linux-gcc-asan-ootree
os: ubuntu-latest
generator: Unix Makefiles
build-type: Asan
build-dir: .build
cxx-flags: -O2
skeleton: ${{ false }}
- name: linux-gcc-debug-ootree-skeleton
os: ubuntu-latest
generator: Unix Makefiles
build-type: Debug
build-dir: .build
cxx-flags: -O2
skeleton: ${{ true }}
- name: linux-gcc-debug-intree-m32-skeleton
os: ubuntu-latest
generator: Unix Makefiles
build-type: Debug
build-dir: .
cxx-flags: -O2 -m32
ld-flags: -m32
skeleton: ${{ true }}
- name: linux-gcc-release-ootree-skeleton
os: ubuntu-latest
generator: Unix Makefiles
build-type: Release
build-dir: .build
skeleton: ${{ true }}
# macOS
- name: macos-clang-debug-ootree-skeleton
os: macos-latest
generator: Unix Makefiles
build-type: Debug
build-dir: .build
cxx-flags: -O2
skeleton: ${{ true }}
- name: macos-clang-debug-intree-skeleton
os: macos-latest
generator: Unix Makefiles
build-type: Debug
build-dir: .
cxx-flags: -O2
skeleton: ${{ true }}
- name: macos-clang-release-ootree-skeleton
os: macos-latest
generator: Unix Makefiles
build-type: Release
build-dir: .build
skeleton: ${{ true }}
# Windows
- name: windows-msvc-debug-ootree
os: windows-latest
generator: Visual Studio 16 2019
build-type: Debug
build-dir: .build
skeleton: ${{ false }}
- name: windows-msvc-debug-intree
os: windows-latest
generator: Visual Studio 16 2019
build-type: Debug
build-dir: .
skeleton: ${{ false }}
- name: windows-msvc-release-ootree
os: windows-latest
generator: Visual Studio 16 2019
build-type: Release
build-dir: .build
skeleton: ${{ false }}
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
echo "CC=gcc" >> $GITHUB_ENV
echo "CXX=g++" >> $GITHUB_ENV
;;
macOS*)
sudo xcode-select -switch /Applications/Xcode.app
echo "CC=$(xcrun -f clang)" >> $GITHUB_ENV
echo "CXX=$(xcrun -f clang++)" >> $GITHUB_ENV
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: Prepare Configure Command
id: configure-command
run: |
# Common CMake arguments
args=( -S . -B ${{ matrix.build-dir }} )
# Generator's specific stuff.
args+=( -G "${{ matrix.generator }}" )
case "${{ matrix.generator }}" in
'Visual Studio'*)
args+=( -A x64 )
;;
*)
# CMAKE_BUILD_TYPE is not used by multi-config build
# types (e.g Visual Studio) at the configure time
# thus we add it only for single-config build types
args+=( -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} )
;;
esac
# CFLAGS, CXXFLAGS, LDFLAGS
args+=( -DCMAKE_C_FLAGS="${{ matrix.cxx-flags }}" )
args+=( -DCMAKE_CXX_FLAGS="${{ matrix.cxx-flags }}" )
args+=( -DCMAKE_EXE_LINKER_FLAGS="${{ matrix.ld-flags }}" )
args+=( -DCMAKE_SHARED_LINKER_FLAGS="${{ matrix.ld-flags }}" )
# Quote each argument to prevent word split.
echo "::set-output name=cmake::$(printf " '%s'" "${args[@]}")"
- name: Fast Configure
run: |
# Read prepared command into an array
args=( ${{ steps.configure-command.outputs.cmake }} )
# Amend Build Options
args+=( -DCMAKE_INSTALL_PREFIX="$(pwd)/install" )
# Disable some defaults for now to speed up the build as
# they are not necessary in a minimal installation
args+=( -DRE2C_BUILD_RE2GO=OFF )
# Print the resulting command line for debugging purposes
printf "cmake" && printf " '%s'" "${args[@]}" && printf "\n"
# Run CMake, pass quoted arguments to prevent word split.
printf " '%s'" "${args[@]}" | xargs cmake
- name: Fast Build
run: cmake --build ${{ matrix.build-dir }} --config ${{ matrix.build-type }}
- name: Install
run: |
cmake --build ${{ matrix.build-dir }} --config ${{ matrix.build-type }} --target install
echo -e "Install tree:\n$(find install | sed 's/^/-- /')"
- name: Minimal Install Test
working-directory: ./install/bin
run: ./re2c --version
- name: Full Configure
run: |
# Read prepared command into an array
args=( ${{ steps.configure-command.outputs.cmake }} )
# Amend Build Options
args+=( -DCMAKE_INSTALL_PREFIX="$(pwd)/install-2" -DRE2C_BUILD_RE2GO=ON -DRE2C_BUILD_LIBS=ON )
args+=( -DRE2C_REBUILD_LEXERS=ON -DRE2C_FOR_BUILD="$(pwd)/install/bin/re2c" )
# Windows does not have a native 'man' and 'sed' commands.
# Disabled until this https://github.com/skvadrik/re2c/issues/327
# will be implemented
case ${{ runner.os }} in
Windows*)
args+=( -DRE2C_REBUILD_DOCS=OFF )
;;
*)
args+=( -DRE2C_REBUILD_DOCS=ON )
;;
esac
# Print the resulting command line for debugging purposes
printf "cmake" && printf " '%s'" "${args[@]}" && printf "\n"
# Run CMake, pass quoted arguments to prevent word split.
printf " '%s'" "${args[@]}" | xargs cmake
- name: Full Build
run: |
find src -name '*.re' | xargs touch
cmake --build ${{ matrix.build-dir }} --config ${{ matrix.build-type }}
- name: Test
# Remove the following line after fix Windows tests
working-directory: ${{ matrix.build-dir }}
run: |
# main test suite
cmake --build . --target check
# skeleton tests (if enabled)
if [[ "x${{ matrix.skeleton }}" == "xtrue" ]] ; then
python run_tests.py --skeleton
fi
- 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: ${{ matrix.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
+4
View File
@@ -11,6 +11,10 @@
/m4
/test_*
/.build*
/bazel-*
# Ignore user defined CMake presets
CMakeUserPresets.json
# The files autogenerated by automake.
Makefile.in
+20 -30
View File
@@ -1,9 +1,5 @@
language: cpp
os:
- linux
- freebsd
# use Ubuntu 20.04 (Focal Fossa) that defaults to Python 3
dist: focal
@@ -14,35 +10,25 @@ compiler:
- gcc
- clang
before_install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then apt install bison python3-docutils ; fi
- if [ "$TRAVIS_OS_NAME" = "freebsd" ]; then pkg install textproc/py-docutils; fi
# preinstalled packages
addons:
apt:
packages:
- bison
- python3-docutils
# configurations: cmake/autotools, in-tree/out-of-tree, release/debug, etc.
env:
- CMAKE=no BUILD_DIR=. CONFIG_DIR=. COMMON_FLAGS="-O2 -g"
- CMAKE=no BUILD_DIR=.build CONFIG_DIR=.. COMMON_FLAGS="-O2 -g"
- CMAKE=yes BUILD_DIR=. CONFIG_DIR=. BUILD_TYPE=Debug
- CMAKE=no BUILD_DIR=. CONFIG_DIR=. COMMON_FLAGS="-O2 -g"
- CMAKE=no BUILD_DIR=.build CONFIG_DIR=.. CONFIG_FLAGS="--enable-debug" COMMON_FLAGS="-O2 -g"
- CMAKE=yes BUILD_DIR=. CONFIG_DIR=. BUILD_TYPE=Debug COMMON_FLAGS="-O2 -g"
- CMAKE=yes BUILD_DIR=.build CONFIG_DIR=.. BUILD_TYPE=Debug COMMON_FLAGS="-O2 -g" SKELETON=yes
- CMAKE=yes BUILD_DIR=.build CONFIG_DIR=.. BUILD_TYPE=Release
- CMAKE=yes BUILD_DIR=. CONFIG_DIR=. BUILD_TYPE=Asan
- CMAKE=yes BUILD_DIR=.build CONFIG_DIR=.. BUILD_TYPE=Ubsan
jobs:
exclude:
- os: freebsd
env: BUILD_TYPE=Asan
- os: freebsd
env: BUILD_TYPE=Ubsan
- CMAKE=yes BUILD_DIR=.build CONFIG_DIR=.. BUILD_TYPE=Debug COMMON_FLAGS="-O2 -g -fsanitize=address"
- CMAKE=yes BUILD_DIR=.build CONFIG_DIR=.. BUILD_TYPE=Debug COMMON_FLAGS="-O2 -g -fsanitize=undefined"
script:
- |
function ncpus() {
if [ "$TRAVIS_OS_NAME" = "freebsd" ]; then
sysctl -n hw.ncpu
else
nproc
fi
}
function run_cmake() {
cmake \
-B . -S ${CONFIG_DIR} \
@@ -55,6 +41,7 @@ script:
}
function run_configure() {
${CONFIG_DIR}/configure \
${CONFIG_FLAGS} \
CFLAGS="${COMMON_FLAGS}" \
CXXFLAGS="${COMMON_FLAGS}" \
LDFLAGS="${COMMON_FLAGS}" \
@@ -69,7 +56,7 @@ script:
mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR}
run_configure --prefix="$(pwd)/install"
fi
- make -j$(ncpus)
- make -j$(nproc)
- make install
- |
if [ x${CMAKE} = "xyes" ]; then
@@ -88,7 +75,10 @@ script:
RE2C_FOR_BUILD="$(pwd)/install/bin/re2c"
fi
- find ${CONFIG_DIR}/src -name '*.re' | xargs touch
- make -j$(ncpus)
- make -j$(nproc)
- |
make -j$(ncpus) check VERBOSE=1
./run_tests.py --skeleton
if [ x${SKELETON} = "xyes" ]; then
./run_tests.py --skeleton
else
make -j$(nproc) check VERBOSE=1
fi
+45
View File
@@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:private"])
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",
]),
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"],
)
+64 -36
View File
@@ -2,27 +2,24 @@ How to build
============
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. Re2c can be built with either
of the two build systems, and they are both maintained and tested on CI. Other
build dependencies include Bison (to rebuild parsers), rst2man (to rebuild
documentation), Sphinx (to rebuild the website), and optionally Mingw and Wine
(to run Windows tests on Linux). A few helper scripts are written in Haskell,
but they are not essential for re2c development.
To develop re2c one also needs CMake or Autotools (both build systems are
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
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).
By default re2c builds from pregenerated bootstrap files. To regenerate these
files it is necessary to configure re2c in a special way and provide a path to
an existing re2c binary (see the details below). Normally this is not necessary,
and the pregenerated files can be used as long as the *.re* files are unchanged.
By default re2c builds from pre-generated bootstrap files. To build from source
*.re* files, it is necessary to reconfigure the build and provide a path to an
existing re2c binary that will be used for bootstrap (see the details below).
Build (Autotools)
@@ -51,20 +48,27 @@ The configure script has many options (to see them all, run
* `--enable-golang`
Build re2go (identical to `re2c --lang go`). This is on by default.
* `--enable-rust`
Build re2rust (identical to `re2c --lang rust`). 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-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
build Ragel and Kleenex). Re2c benchmarks are always regenerated.
build Ragel and Kleenex). re2c benchmarks are always regenerated.
* `--enable-libs`
Build the experimental libre2c library that provides POSIX
@@ -82,10 +86,27 @@ There is a bunch of build scripts for specialized builds with Asan, Ubsan,
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
@@ -130,20 +151,28 @@ specific to re2c:
* `-DRE2C_BUILD_RE2GO=yes`
Build re2go executable (an alias to `re2c --lang go`). Enabled by default.
* `-DRE2C_BUILD_RE2RUST=yes`
Build re2rust executable (an alias to `re2c --lang rust`). 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_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
build Ragel and Kleenex). Re2c benchmarks are always regenerated.
build Ragel and Kleenex). re2c benchmarks are always regenerated.
* `-DRE2C_BUILD_LIBS=yes`
Build the experimental libre2c library that provides POSIX
@@ -161,11 +190,10 @@ There is a bunch of build scripts for specialized builds with Asan, Ubsan,
GLIBCXX_DEBUG, etc. in the ``build`` subdirectory.
Test
----
Re2c has a main test suite and a number of unit tests. Run them all:
re2c has a main test suite and a number of unit tests. Run them all:
```
$ make check
```
@@ -190,9 +218,9 @@ Check the distribution (works with Autotools):
$ make distcheck
```
Re2c provides a helper script `build/__alltest.sh` that builds and tests
various re2c build flavours with Asan, Ubsan, GLIBCXX_DEBUG, etc. There is a
couple of 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.
re2c provides a helper script `build/__alltest.sh` that builds and tests various
re2c build flavours with Asan, Ubsan, GLIBCXX_DEBUG, etc. There is a couple of
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.
+249
View File
@@ -1,6 +1,255 @@
Changelog
=========
----
3.0x
----
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)
~~~~~~~~~~~~~~~~
- Added code generation backend for Rust:
+ Enabled with ``--lang rust`` option.
+ A new ``re2rust`` binary (built by default, or configured with
``--enable-rust`` Autoconf option and ``RE2C_BUILD_RE2RUST`` CMake option).
- Added options:
+ ``--loop-switch``
+ ``--no-unsafe``
- Added configurations;
+ ``re2c:label:yyloop``
+ ``re2c:unsafe``
- Renamed options to use common naming scheme. The old names are supported as
aliases, so the change does not break existing code. Documentation has been
updated to use new names.
+ ``--api`` is a new alias for ``--input``
+ ``--ebcdic`` is a new alias for ``--ecb``
+ ``--ucs2`` is a new alias for ``--wide-chars``
+ ``--utf32`` is a new alias for ``--unicode``
+ ``--utf16`` is a new alias for ``--utf-16``
+ ``--utf8`` is a new alias for ``--utf-8``
+ ``--header`` is a new alias for ``--type-header``
- Renamed configurations to use common naming scheme and support proper scoping
under subcategories such as ``:define``, ``:label``, ``:variable``, etc. The
old names are supported as aliases, so the change does not break existing
code. Documentation has been updated to use new names.
+ ``re2c:api`` is a new alias for ``re2c:flags:input``
+ ``re2c:bit-vectors`` is a new alias for ``re2c:flags:bit-vectors``
+ ``re2c:case-insensitive`` is a new alias for ``re2c:flags:case-insensitive``
+ ``re2c:case-inverted`` is a new alias for ``re2c:flags:case-inverted``
+ ``re2c:case-ranges`` is a new alias for ``re2c:flags:case-ranges``
+ ``re2c:cond:prefix`` is a new alias for ``re2c:condprefix``
+ ``re2c:cond:enumprefix`` is a new alias for ``re2c:condenumprefix``
+ ``re2c:computed-gotos`` is a new alias for ``re2c:flags:computed-gotos``
+ ``re2c:computed-gotos:threshold`` is a new alias for ``re2c:cgoto:threshold``
+ ``re2c:debug-output`` is a new alias for ``re2c:flags:debug-output``
+ ``re2c:encoding:ebcdic`` is a new alias for ``re2c:flags:ecb``
+ ``re2c:encoding:utf32`` is a new alias for ``re2c:flags:unicode``
+ ``re2c:encoding:ucs2`` is a new alias for ``re2c:flags:wide-chars``
+ ``re2c:encoding:utf16`` is a new alias for ``re2c:flags:utf-16``
+ ``re2c:encoding:utf8`` is a new alias for ``re2c:flags:utf-8``
+ ``re2c:encoding-policy`` is a new alias for ``re2c:flags:encoding-policy``
+ ``re2c:empty-class`` is a new alias for ``re2c:flags:empty-class``
+ ``re2c:header`` is a new alias for ``re2c:flags:type-header``
+ ``re2c:label:prefix`` is a new alias for ``re2c:labelprefix``
+ ``re2c:label:yyfill`` is a new alias for ``re2c:label:yyFillLabel``
+ ``re2c:label:start`` is a new alias for ``re2c:startlabel``
+ ``re2c:nested-ifs`` is a new alias for ``re2c:flags:nested-ifs``
+ ``re2c:posix-captures`` is a new alias for ``re2c:flags:posix-captures``
+ ``re2c:tags`` is a new alias for ``re2c:flags:tags``
+ ``re2c:variable:yych:conversion`` is a new alias for ``re2c:yych:conversion``
+ ``re2c:variable:yych:emit`` is a new alias for ``re2c:yych:emit``
+ ``re2c:variable:yybm:hex`` is a new alias for ``re2c:yybm:hex``
+ ``re2c:unsafe`` is a new alias for ``re2c:flags:unsafe``
- Added directive alias ``conditions:re2c`` for ``types:re2c``.
- Multiple small changes in code generation, including some formatting changes
that result in large diffs in the generated code:
+ Do not allocate indices for unused state labels (this results in a change in
state enumeration), commits
`919570c4 <https://github.com/skvadrik/re2c/commit/919570c4>`_ and
`82b704f6 <https://github.com/skvadrik/re2c/commit/82b704f6>`_.
+ Do not generate redundant ``YYPEEK`` statements, commit
`cca31d22 <https://github.com/skvadrik/re2c/commit/cca31d22>`_.
+ Do not generate ``YYDEBUG`` statements for unused states labels, commit
`a46f01e6 <https://github.com/skvadrik/re2c/commit/a46f01e6>`_.
+ C backend: change formatting of switch statements, commit
`ed88e12e <https://github.com/skvadrik/re2c/commit/ed88e12e>`_.
+ Go backend: render continuous character ranges in compact form, commit
`09161b14 <https://github.com/skvadrik/re2c/commit/09161b14>`_.
+ Mark start and end of included .re files with line directives, commit
`48e83fca <https://github.com/skvadrik/re2c/commit/48e83fca>`_.
- A fix to limit maximum allowed NFA and DFA size (to avoid out of memory
crashes and stack overflows), commit
`a3473fd7 <https://github.com/skvadrik/re2c/commit/a3473fd7>`_.
- A fix to correctly compute fixed tags in trailing context, commit
`68e1ab71 <https://github.com/skvadrik/re2c/commit/68e1ab71>`_.
- A fix to generate non-overlapping names for s-tag and m-tag variables, commit
`7c6b5c95 <https://github.com/skvadrik/re2c/commit/7c6b5c95>`_.
- Infrastructural: added support for CMake presets.
- Updated documentation.
- Backwards-incompatible changes that are unlikely to affect any users:
+ Restrict lexical contexts where ``%{`` is recognized as a block start,
commit `dba7d055 <https://github.com/skvadrik/re2c/commit/dba7d055>`_.
+ Emit an error when repetition lower bound exceeds upper bound, commit
`039c1894 <https://github.com/skvadrik/re2c/commit/039c1894>`_.
----
2.2x
----
2.2 (2021-08-01)
~~~~~~~~~~~~~~~~
- Added named blocks and block lists in directives.
- Added local blocks ``/*!local:re2c ... */``.
- Added in-block ``!include`` directive.
- Added in-block ``!use`` directive.
- Allowed reusable blocks without ``-r --reusable`` option.
- Allowed customizing the generated code with configurations for directives
``max:re2c``, ``maxnmatch:re2c``, ``stags:re2c``, ``mtags:re2c`` and
``types:re2c`` (see directive descriptions for details).
- Forbid arbitrary text at the end of ``max:re2c`` directive. This may break
backwards compatibility, although it is unlikely that this was used by anyone.
The change was necessary in order to allow customization of the generated code
with configurations.
- Deprecated configurations ``flags:i``, ``flags:no-debug-info`` in favour of
the global options ``-i``, ``--no-debug-info``.
- Reimplemented re2c test runner in Python (thanks to
`Serghei Iakovlev <https://github.com/sergeyklay>`_). Improved integration
with GitHub Actions.
- Changes in the experimental libre2c library: added new algorithms that
construct t-string or extract submatch on all repetitions; added TDFA
benchmark written in Java by Angelo Borsotti.
- Updated documentation.
----
2.1x
----
+113 -104
View File
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.12)
project(re2c VERSION 2.1.1 HOMEPAGE_URL "https://re2c.org/")
project(re2c VERSION 3.1 HOMEPAGE_URL "https://re2c.org/")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
@@ -17,46 +17,45 @@ 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_DOCS "Regenerate manpage" OFF)
option(RE2C_BUILD_LIBS "Build libraries" OFF)
option(RE2C_BUILD_RE2GO "Build re2go executable (an alias for `re2c --lang go`)" ON)
option(RE2C_BUILD_RE2RUST "Build re2rust executable (an alias for `re2c --lang rust`)" ON)
option(RE2C_BUILD_BENCHMARKS "Build benchmarks" OFF)
option(RE2C_REGEN_BENCHMARKS "Regenerate C code for benchmarks" OFF)
# checks for programs
find_package(BISON)
find_package(Python3 COMPONENTS Interpreter)
# starting from cmake 3.19 find_package can do version check, but we are on 3.12
if(Python3_VERSION VERSION_LESS 3.7)
message(FATAL_ERROR "python version 3.7 or higher is required")
endif()
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()
# checks for C++ compiler flags
set(CMAKE_CXX_STANDARD 98)
set(CMAKE_CXX_EXTENSIONS OFF)
# 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
set(CMAKE_POSITION_INDEPENDENT_CODE ON) # make sure object libraries work with shared libraries
# 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")
@@ -65,34 +64,25 @@ 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_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_manpage_bootstrap_rust "${CMAKE_CURRENT_SOURCE_DIR}/bootstrap/doc/re2rust.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_manpage_rust "${CMAKE_CURRENT_BINARY_DIR}/doc/re2rust.1")
set(re2c_help "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help.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_RE2GO}>:${re2c_manpage_go}>"
"$<$<BOOL:${RE2C_BUILD_RE2RUST}>:${re2c_manpage_rust}>"
)
set(top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
@@ -136,19 +126,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/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
@@ -174,27 +159,21 @@ 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/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
@@ -202,12 +181,8 @@ 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>
@@ -220,7 +195,13 @@ add_executable(re2c ${re2c_sources})
# re2go
if (RE2C_BUILD_RE2GO)
add_executable(re2go ${re2c_sources})
target_compile_definitions(re2go PUBLIC "RE2C_LANG=LANG_GO")
target_compile_definitions(re2go PUBLIC "RE2C_LANG=Lang::GO")
endif()
# re2rust
if (RE2C_BUILD_RE2RUST)
add_executable(re2rust ${re2c_sources})
target_compile_definitions(re2rust PUBLIC "RE2C_LANG=Lang::RUST")
endif()
re2c_bootstrap_lexer("src/parse/lex.re" "src/parse/lex.cc" "src/parse/lex.h")
@@ -232,8 +213,8 @@ re2c_bootstrap_parser("src/parse/parser.ypp" "src/parse/parser.cc" "src/parse/pa
# docs
set(re2c_docs_sources
"${re2c_manpage_source}"
"doc/manual/api/api.rst_"
"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_"
@@ -258,13 +239,22 @@ set(re2c_docs_sources
"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.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"
@@ -274,17 +264,19 @@ set(re2c_docs_sources
"examples/c/fill/01_fill.re"
"examples/c/fill/02_fill.re"
"examples/c/headers/header.re"
"examples/c/headers/src/lexer/lexer.h"
"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.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"
@@ -294,18 +286,42 @@ set(re2c_docs_sources
"examples/go/fill/01_fill.re"
"examples/go/fill/02_fill.re"
"examples/go/headers/header.re"
"examples/go/headers/src/lexer/lexer.go"
"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_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_manpage("${re2c_manpage_source}" "${re2c_manpage_rust}" "${re2c_manpage_bootstrap_rust}" "rust")
re2c_gen_help("${re2c_help_source}" "${re2c_help}" "${re2c_help_bootstrap}")
add_custom_target(docs DEPENDS "${re2c_docs}")
@@ -318,6 +334,10 @@ if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
install(TARGETS re2go RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_go}" DESTINATION "share/man/man1")
endif()
if(RE2C_BUILD_RE2RUST)
install(TARGETS re2rust RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_rust}" DESTINATION "share/man/man1")
endif()
install(FILES include/unicode_categories.re DESTINATION "${RE2C_STDLIB_DIR}")
# rebuild all re2c sources using newly built re2c
@@ -352,11 +372,10 @@ if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
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
@@ -398,21 +417,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
@@ -438,36 +455,28 @@ 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/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>
)
+498
View File
@@ -0,0 +1,498 @@
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21,
"patch": 1
},
"configurePresets": [
{
"name": "default-full-configuration",
"hidden": true,
"installDir": "${sourceDir}/install-2",
"cacheVariables": {
"RE2C_BUILD_RE2GO": true,
"RE2C_BUILD_RE2RUST": true,
"RE2C_BUILD_LIBS": true,
"RE2C_REBUILD_LEXERS": true,
"RE2C_REBUILD_DOCS": true,
"RE2C_FOR_BUILD": "${sourceDir}/install/bin/re2c"
}
},
{
"name": "linux-config-base",
"hidden": true,
"generator": "Unix Makefiles",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "gcc",
"CMAKE_CXX_COMPILER": "g++"
}
},
{
"name": "linux-gcc-ubsan-ootree-fast",
"displayName": "Linux x86_64: GCC / Ubsan / Out of tree (fast)",
"inherits": "linux-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Ubsan",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
}
},
{
"name": "linux-gcc-ubsan-ootree-full",
"displayName": "Linux x86_64: GCC / Ubsan / Out of tree (full)",
"inherits": ["default-full-configuration", "linux-gcc-ubsan-ootree-fast"]
},
{
"name": "linux-gcc-asan-ootree-fast",
"displayName": "Linux x86_64: GCC / Asan / Out of tree (fast)",
"inherits": "linux-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Asan",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
}
},
{
"name": "linux-gcc-asan-ootree-full",
"displayName": "Linux x86_64: GCC / Asan / Out of tree (full)",
"inherits": ["default-full-configuration", "linux-gcc-asan-ootree-fast"]
},
{
"name": "linux-gcc-debug-ootree-skeleton-fast",
"displayName": "Linux x86_64: GCC / Debug / Skeleton / Out of tree (fast)",
"inherits": "linux-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
}
},
{
"name": "linux-gcc-debug-ootree-skeleton-full",
"displayName": "Linux x86_64: GCC / Debug / Skeleton / Out of tree (full)",
"inherits": ["default-full-configuration", "linux-gcc-debug-ootree-skeleton-fast"]
},
{
"name": "linux-gcc-debug-intree-m32-skeleton-fast",
"displayName": "Linux x86: GCC / Debug / Skeleton / In tree (fast)",
"inherits": "linux-config-base",
"binaryDir": "${sourceDir}",
"installDir": "${sourceDir}/install",
"architecture": {
"value": "x86",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-O2 -m32",
"CMAKE_CXX_FLAGS": "-O2 -m32",
"CMAKE_EXE_LINKER_FLAGS": "-m32",
"CMAKE_SHARED_LINKER_FLAGS": "-m32",
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
}
},
{
"name": "linux-gcc-debug-intree-m32-skeleton-full",
"displayName": "Linux x86: GCC / Debug / Skeleton / In tree (full)",
"inherits": ["default-full-configuration", "linux-gcc-debug-intree-m32-skeleton-fast"]
},
{
"name": "linux-gcc-release-ootree-skeleton-fast",
"displayName": "Linux x86_64: GCC / Release / Skeleton / Out of tree (fast)",
"inherits": "linux-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
}
},
{
"name": "linux-gcc-release-ootree-skeleton-full",
"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"]
},
{
"name": "macos-config-base",
"hidden": true,
"generator": "Unix Makefiles",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
},
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++"
}
},
{
"name": "macos-clang-debug-ootree-skeleton-fast",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / Out of tree (fast)",
"inherits": "macos-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
}
},
{
"name": "macos-clang-debug-ootree-skeleton-full",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / Out of tree (full)",
"inherits": ["default-full-configuration", "macos-clang-debug-ootree-skeleton-fast"]
},
{
"name": "macos-clang-debug-intree-skeleton-fast",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / In tree (fast)",
"inherits": "macos-config-base",
"binaryDir": "${sourceDir}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
}
},
{
"name": "macos-clang-debug-intree-skeleton-full",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / In tree (full)",
"inherits": ["default-full-configuration", "macos-clang-debug-intree-skeleton-fast"]
},
{
"name": "macos-clang-release-ootree-skeleton-fast",
"displayName": "macOS x86_64: CLang / Release / Skeleton / Out of tree (fast)",
"inherits": "macos-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": false
}
},
{
"name": "macos-clang-release-ootree-skeleton-full",
"displayName": "macOS x86_64: CLang / Release / Skeleton / Out of tree (full)",
"inherits": ["default-full-configuration", "macos-clang-release-ootree-skeleton-fast"]
},
{
"name": "windows-config-base",
"hidden": true,
"generator": "Visual Studio 17 2022",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "cl",
"CMAKE_CXX_COMPILER": "cl"
}
},
{
"name": "windows-msvc-debug-ootree-fast",
"displayName": "Windows x86_64: MSVC / Debug / Out of tree (fast)",
"inherits": "windows-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": 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"]
},
{
"name": "windows-msvc-debug-intree-fast",
"displayName": "Windows x86_64: MSVC / Debug / In tree (fast)",
"inherits": "windows-config-base",
"binaryDir": "${sourceDir}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": 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"]
},
{
"name": "windows-msvc-release-ootree-fast",
"displayName": "Windows x86_64: MSVC / Release / Out of tree (fast)",
"inherits": "windows-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"RE2C_BUILD_RE2GO": false,
"RE2C_BUILD_RE2RUST": 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"]
}
],
"buildPresets": [
{
"name": "linux-build-base",
"hidden": true,
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
}
},
{
"name": "linux-gcc-ubsan-ootree-fast",
"displayName": "Linux x86_64: GCC / Ubsan / Out of tree (fast)",
"configurePreset": "linux-gcc-ubsan-ootree-fast",
"inherits": "linux-build-base",
"configuration": "Ubsan"
},
{
"name": "linux-gcc-ubsan-ootree-full",
"displayName": "Linux x86_64: GCC / Ubsan / Out of tree (full)",
"configurePreset": "linux-gcc-ubsan-ootree-full",
"inherits": "linux-build-base",
"configuration": "Ubsan"
},
{
"name": "linux-gcc-asan-ootree-fast",
"displayName": "Linux x86_64: GCC / Asan / Out of tree (fast)",
"configurePreset": "linux-gcc-asan-ootree-fast",
"inherits": "linux-build-base",
"configuration": "Asan"
},
{
"name": "linux-gcc-asan-ootree-full",
"displayName": "Linux x86_64: GCC / Asan / Out of tree (full)",
"configurePreset": "linux-gcc-asan-ootree-full",
"inherits": "linux-build-base",
"configuration": "Asan"
},
{
"name": "linux-gcc-debug-ootree-skeleton-fast",
"displayName": "Linux x86_64: GCC / Debug / Skeleton / Out of tree (fast)",
"configurePreset": "linux-gcc-debug-ootree-skeleton-fast",
"inherits": "linux-build-base",
"configuration": "Debug"
},
{
"name": "linux-gcc-debug-ootree-skeleton-full",
"displayName": "Linux x86_64: GCC / Debug / Skeleton / Out of tree (full)",
"configurePreset": "linux-gcc-debug-ootree-skeleton-full",
"inherits": "linux-build-base",
"configuration": "Debug"
},
{
"name": "linux-gcc-debug-intree-m32-skeleton-fast",
"displayName": "Linux x86: GCC / Debug / Skeleton / In tree (fast)",
"configurePreset": "linux-gcc-debug-intree-m32-skeleton-fast",
"inherits": "linux-build-base",
"configuration": "Debug"
},
{
"name": "linux-gcc-debug-intree-m32-skeleton-full",
"displayName": "Linux x86: GCC / Debug / Skeleton / In tree (full)",
"configurePreset": "linux-gcc-debug-intree-m32-skeleton-full",
"inherits": "linux-build-base",
"configuration": "Debug"
},
{
"name": "linux-gcc-release-ootree-skeleton-fast",
"displayName": "Linux x86_64: GCC / Release / Skeleton / Out of tree (fast)",
"configurePreset": "linux-gcc-release-ootree-skeleton-fast",
"inherits": "linux-build-base",
"configuration": "Release"
},
{
"name": "linux-gcc-release-ootree-skeleton-full",
"displayName": "Linux x86_64: GCC / Release / Skeleton / Out of tree (full)",
"configurePreset": "linux-gcc-release-ootree-skeleton-full",
"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"
},
{
"name": "macos-build-base",
"hidden": true,
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
}
},
{
"name": "macos-clang-debug-ootree-skeleton-fast",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / Out of tree (fast)",
"configurePreset": "macos-clang-debug-ootree-skeleton-fast",
"inherits": "macos-build-base",
"configuration": "Debug"
},
{
"name": "macos-clang-debug-ootree-skeleton-full",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / Out of tree (full)",
"configurePreset": "macos-clang-debug-ootree-skeleton-full",
"inherits": "macos-build-base",
"configuration": "Debug"
},
{
"name": "macos-clang-debug-intree-skeleton-fast",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / In tree (fast)",
"configurePreset": "macos-clang-debug-intree-skeleton-fast",
"inherits": "macos-build-base",
"configuration": "Debug"
},
{
"name": "macos-clang-debug-intree-skeleton-full",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / In tree (full)",
"configurePreset": "macos-clang-debug-intree-skeleton-full",
"inherits": "macos-build-base",
"configuration": "Debug"
},
{
"name": "macos-clang-release-ootree-skeleton-fast",
"displayName": "macOS x86_64: CLang / Release / Skeleton / Out of tree (fast)",
"configurePreset": "macos-clang-release-ootree-skeleton-fast",
"inherits": "macos-build-base",
"configuration": "Release"
},
{
"name": "macos-clang-release-ootree-skeleton-full",
"displayName": "macOS x86_64: CLang / Release / Skeleton / Out of tree (full)",
"configurePreset": "macos-clang-release-ootree-skeleton-full",
"inherits": "macos-build-base",
"configuration": "Release"
},
{
"name": "windows-build-base",
"hidden": true,
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "windows-msvc-debug-ootree-fast",
"displayName": "Windows x86_64: MSVC / Debug / Out of tree (fast)",
"configurePreset": "windows-msvc-debug-ootree-fast",
"inherits": "windows-build-base",
"configuration": "Debug"
},
{
"name": "windows-msvc-debug-ootree-full",
"displayName": "Windows x86_64: MSVC / Debug / Out of tree (full)",
"configurePreset": "windows-msvc-debug-ootree-full",
"inherits": "windows-build-base",
"configuration": "Debug"
},
{
"name": "windows-msvc-debug-intree-fast",
"displayName": "Windows x86_64: MSVC / Debug / In tree (fast)",
"configurePreset": "windows-msvc-debug-intree-fast",
"inherits": "windows-build-base",
"configuration": "Debug"
},
{
"name": "windows-msvc-debug-intree-full",
"displayName": "Windows x86_64: MSVC / Debug / In tree (full)",
"configurePreset": "windows-msvc-debug-intree-full",
"inherits": "windows-build-base",
"configuration": "Debug"
},
{
"name": "windows-msvc-release-ootree-fast",
"displayName": "Windows x86_64: MSVC / Release / Out of tree (fast)",
"configurePreset": "windows-msvc-release-ootree-fast",
"inherits": "windows-build-base",
"configuration": "Release"
},
{
"name": "windows-msvc-release-ootree-full",
"displayName": "Windows x86_64: MSVC / Release / Out of tree (full)",
"configurePreset": "windows-msvc-release-ootree-full",
"inherits": "windows-build-base",
"configuration": "Release"
}
]
}
+34 -19
View File
@@ -11,30 +11,45 @@ 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 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 inforamtion). 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.
+134 -98
View File
@@ -10,7 +10,7 @@ if DEBUG
AM_CXXFLAGS += -DRE2C_DEBUG
endif
RE2CFLAGS = -br -W -Wno-match-empty-string
RE2CFLAGS = -b -W -Wno-match-empty-string --no-generation-date
# binary
bin_PROGRAMS = re2c
@@ -20,6 +20,7 @@ noinst_PROGRAMS =
re2c_HDR = \
src/constants.h \
src/codegen/code.h \
src/codegen/output.h \
src/codegen/helpers.h \
src/options/opt.h \
src/options/symtab.h \
@@ -30,70 +31,49 @@ re2c_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/mtag_trie.h \
src/skeleton/path.h \
src/skeleton/skeleton.h \
src/parse/ast.h \
src/parse/input.h \
src/parse/parse.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/containers.h \
src/util/check.h \
src/util/file_utils.h \
src/util/fixed_allocator.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/temp_file.h \
src/util/u32lim.h \
src/util/uniq_vector.h
src/util/u32lim.h
re2c_SRC = \
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/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 \
@@ -119,27 +99,21 @@ re2c_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/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/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 \
@@ -147,12 +121,8 @@ re2c_SRC = \
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
re2c_SOURCES = \
src/main.cc \
@@ -188,10 +158,12 @@ re2c_BOOT_PARSER = bootstrap/src/parse/parser.cc
re2c_BOOT_PARSER_HDR = bootstrap/src/parse/parser.h
re2c_BOOT_DOC_C = bootstrap/doc/re2c.1
re2c_BOOT_DOC_GO = bootstrap/doc/re2go.1
re2c_BOOT_DOC_RUST = bootstrap/doc/re2rust.1
re2c_BOOT_HELP = bootstrap/src/msg/help.cc
re2c_BOOT = \
$(re2c_BOOT_DOC_C) \
$(re2c_BOOT_DOC_GO) \
$(re2c_BOOT_DOC_RUST) \
$(re2c_BOOT_HELP) \
$(re2c_BOOT_PARSER) \
$(re2c_BOOT_PARSER_HDR) \
@@ -215,8 +187,8 @@ re2c_CUSTOM = \
# docs
re2c_SRC_DOC = doc/manpage.rst
re2c_SRC_DOC_EXT = \
doc/manual/api/api.rst_ \
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_ \
@@ -241,13 +213,22 @@ re2c_SRC_DOC_EXT = \
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.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 \
@@ -257,17 +238,19 @@ re2c_SRC_DOC_EXT = \
examples/c/fill/01_fill.re \
examples/c/fill/02_fill.re \
examples/c/headers/header.re \
examples/c/headers/src/lexer/lexer.h \
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.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 \
@@ -277,38 +260,79 @@ re2c_SRC_DOC_EXT = \
examples/go/fill/01_fill.re \
examples/go/fill/02_fill.re \
examples/go/headers/header.re \
examples/go/headers/src/lexer/lexer.go \
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/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
DOC_C = doc/re2c.1
DOCS = $(DOC_C)
if WITH_GOLANG
DOC_GO = doc/re2go.1
DOCS += $(DOC_GO)
endif
if WITH_RUST
DOC_RUST = doc/re2rust.1
DOCS += $(DOC_RUST)
endif
man_MANS = $(DOCS)
# include files (stdlib)
dist_stdlib_DATA = include/unicode_categories.re
BAZELFILES := \
BUILD.bazel \
WORKSPACE \
bazel
CMAKEFILES := \
CMakeLists.txt \
CMakePresets.json \
cmake
EXTRA_DIST = \
$(re2c_BOOT) \
$(re2c_CUSTOM) \
$(re2c_SRC_DOC_EXT) \
$(BAZELFILES) \
$(CMAKEFILES) \
BUILD.md \
CHANGELOG \
CONTRIBUTING.md \
IDEAS.md \
LICENSE \
MAINTAINERS.md \
NO_WARRANTY \
README.md \
autogen.sh \
@@ -324,13 +348,8 @@ if REBUILD_LEXERS
# generate lexer and update bootstrap files
.re.cc:
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)if test -x $(RE2C_FOR_BUILD); \
then \
$(RE2C_FOR_BUILD) $(RE2CFLAGS) -o $@ $< && \
cp $(@:cc=[ch]*) $(top_srcdir)/bootstrap/$(@D); \
else \
echo "RE2C is not an executable file" && exit 1 ; \
fi
$(AM_V_GEN)$(RE2C_FOR_BUILD) $(RE2CFLAGS) -o $@ $<
$(AM_V_GEN)cp $(@:cc=[ch]*) $(top_srcdir)/bootstrap/$(@D);
else
# copy bootstrap files
.re.cc:
@@ -339,19 +358,19 @@ else
$(AM_V_at)echo "Reconfigure with --enable-lexers to regenerate $@"
endif
# cannot update bootstrap with distcheck (it makes srcdir readonly),
# so we update bootstrap only on incremental build (if re2c binary exists)
if REBUILD_PARSERS
# generate lexer and update bootstrap files
.ypp.cc:
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)if test $(BISON) = "no"; \
then \
cp $(top_srcdir)/bootstrap/$(@:cc=*) $(@D); \
else \
$(BISON) --output=$@ --defines=$(@:cc=h) $< && \
if test -x $(top_builddir)/re2c$(EXEEXT); then \
cp $@ $(@:cc=h) $(top_srcdir)/bootstrap/$(@D); \
fi; \
fi
$(AM_V_GEN)$(BISON) --warnings --output=$@ --defines=$(@:cc=h) $<
$(AM_V_GEN)cp $@ $(@:cc=h) $(top_srcdir)/bootstrap/$(@D);
else
# copy bootstrap files
.ypp.cc:
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)cp $(top_srcdir)/bootstrap/$(@:cc=*) $(@D);
$(AM_V_at)echo "Reconfigure with --enable-parsers to regenerate $@"
endif
# lexer depends on bison-generated header
$(re2c_GEN_LEX): $(re2c_GEN_PARSER)
@@ -365,29 +384,35 @@ bootstrap: all
.PHONY: docs
if REBUILD_DOCS
docs: $(DOCS) $(re2c_GEN_HELP)
GENHELP = $(top_srcdir)/build/gen_help.sh
SPLITMAN = $(top_srcdir)/build/split_man.sh
RST2TXT = $(top_srcdir)/build/rst2txt.py
RST2MAN = $(top_srcdir)/build/rst2man.py
SPLITMAN = $(top_srcdir)/build/split_man.py
# generate manpage for C
$(DOC_C): $(re2c_SRC_DOC) $(re2c_SRC_DOC_EXT) $(SPLITMAN)
$(DOC_C): $(re2c_SRC_DOC) $(re2c_SRC_DOC_EXT) $(SPLITMAN) $(RST2MAN)
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)$(SPLITMAN) $(top_builddir)/$(re2c_SRC_DOC) $(top_builddir)/$(re2c_SRC_DOC).c c \
&& $(RST2MAN) --tab-width=4 $(top_builddir)/$(re2c_SRC_DOC).c > $@ \
$(AM_V_GEN)$(PYTHON) $(SPLITMAN) $(top_builddir)/$(re2c_SRC_DOC) $(top_builddir)/$(re2c_SRC_DOC).c c \
&& $(PYTHON) $(RST2MAN) --tab-width=4 $(top_builddir)/$(re2c_SRC_DOC).c > $@ \
&& cp $@ $(top_srcdir)/$(re2c_BOOT_DOC_C) \
&& rm $(top_builddir)/$(re2c_SRC_DOC).c
# generate manpage for Go
$(DOC_GO): $(re2c_SRC_DOC) $(re2c_SRC_DOC_EXT) $(SPLITMAN)
$(DOC_GO): $(re2c_SRC_DOC) $(re2c_SRC_DOC_EXT) $(SPLITMAN) $(RST2MAN)
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)$(SPLITMAN) $(top_builddir)/$(re2c_SRC_DOC) $(top_builddir)/$(re2c_SRC_DOC).go go \
&& $(RST2MAN) --tab-width=4 $(top_builddir)/$(re2c_SRC_DOC).go > $@ \
$(AM_V_GEN)$(PYTHON) $(SPLITMAN) $(top_builddir)/$(re2c_SRC_DOC) $(top_builddir)/$(re2c_SRC_DOC).go go \
&& $(PYTHON) $(RST2MAN) --tab-width=4 $(top_builddir)/$(re2c_SRC_DOC).go > $@ \
&& cp $@ $(top_srcdir)/$(re2c_BOOT_DOC_GO) \
&& rm $(top_builddir)/$(re2c_SRC_DOC).go
# generate help
$(re2c_GEN_HELP): $(re2c_CUSTOM_HELP) $(GENHELP)
# generate manpage for Rust
$(DOC_RUST): $(re2c_SRC_DOC) $(re2c_SRC_DOC_EXT) $(SPLITMAN) $(RST2MAN)
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)$(RST2MAN) $(top_builddir)/$(re2c_CUSTOM_HELP) > $@.1 \
&& $(GENHELP) $@.1 $@ \
&& cp $@ $(top_srcdir)/$(re2c_BOOT_HELP) \
&& rm $@.1
$(AM_V_GEN)$(PYTHON) $(SPLITMAN) $(top_builddir)/$(re2c_SRC_DOC) $(top_builddir)/$(re2c_SRC_DOC).rust rust \
&& $(PYTHON) $(RST2MAN) --tab-width=4 $(top_builddir)/$(re2c_SRC_DOC).rust > $@ \
&& cp $@ $(top_srcdir)/$(re2c_BOOT_DOC_RUST) \
&& rm $(top_builddir)/$(re2c_SRC_DOC).rust
# generate help
$(re2c_GEN_HELP): $(re2c_CUSTOM_HELP) $(re2c_SRC_DOC_EXT) $(RST2TXT)
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)$(PYTHON) $(RST2TXT) --variable-name=help $(top_builddir)/$(re2c_CUSTOM_HELP) $@ \
&& cp $@ $(top_srcdir)/$(re2c_BOOT_HELP)
else
docs: $(DOCS) $(re2c_GEN_HELP)
$(AM_V_at)echo "Reconfigure with --enable-docs to rebuild docs"
@@ -399,6 +424,10 @@ $(DOC_C): $(re2c_BOOT_DOC_C)
$(DOC_GO): $(re2c_BOOT_DOC_GO)
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)cp $(top_srcdir)/$(re2c_BOOT_DOC_GO) $@
# copy bootstrap manpage for Rust
$(DOC_RUST): $(re2c_BOOT_DOC_RUST)
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)cp $(top_srcdir)/$(re2c_BOOT_DOC_RUST) $@
# copy bootstrap help
$(re2c_GEN_HELP): $(re2c_BOOT_HELP)
$(AM_V_at)$(MKDIR_P) $(@D)
@@ -411,25 +440,24 @@ all-local: docs $(re2c_BOOT_PARSER)
re2c_TESTSUITE = run_tests.py
.PHONY: tests
tests: all $(re2c_TESTSUITE)
$(top_builddir)/$(re2c_TESTSUITE)
$(PYTHON) $(top_builddir)/$(re2c_TESTSUITE)
.PHONY: vtests
vtests: all $(re2c_TESTSUITE)
$(top_builddir)/$(re2c_TESTSUITE) --valgrind
$(PYTHON) $(top_builddir)/$(re2c_TESTSUITE) --valgrind
.PHONY: wtests
wtests: all $(re2c_TESTSUITE)
$(top_builddir)/$(re2c_TESTSUITE) --wine -j1
$(PYTHON) $(top_builddir)/$(re2c_TESTSUITE) --wine -j1
re2c_test_range_SOURCES = \
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
src/util/range.cc \
src/util/range.h
re2c_test_s_to_n32_unsafe_SOURCES = \
src/test/s_to_n32_unsafe/test.cc \
src/util/s_to_n32_unsafe.cc
src/util/string_utils.cc
re2c_test_ver_to_vernum_SOURCES = \
src/test/ver_to_vernum/test.cc \
@@ -464,7 +492,15 @@ endif
# re2go
if WITH_GOLANG
bin_PROGRAMS += re2go
re2go_CXXFLAGS = $(AM_CXXFLAGS) -DRE2C_LANG=LANG_GO
re2go_CXXFLAGS = $(AM_CXXFLAGS) -DRE2C_LANG=Lang::GO
re2go_SOURCES = $(re2c_SOURCES)
nodist_re2go_SOURCES = $(nodist_re2c_SOURCES)
endif
# re2rust
if WITH_RUST
bin_PROGRAMS += re2rust
re2rust_CXXFLAGS = $(AM_CXXFLAGS) -DRE2C_LANG=Lang::RUST
re2rust_SOURCES = $(re2c_SOURCES)
nodist_re2rust_SOURCES = $(nodist_re2c_SOURCES)
endif
+18 -40
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,28 @@ 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/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) \
+6 -5
View File
@@ -1,7 +1,7 @@
DESCRIPTION
-----------
re2c is a free and open-source lexer generator for C, C++ and Go.
re2c is a free and open-source lexer generator for C/C++, Go and Rust.
Its main goal is generating fast lexers: at least as fast as their reasonably
optimized hand-coded counterparts. Instead of using traditional table-driven
@@ -40,8 +40,8 @@ CONTRIBUTING
------------
re2c is an Open Source, community-driven project. See
[CONTRIBUTING.md](https://github.com/skvadrik/re2c/blob/master/CONTRIBUTING.md) for
details about contributions to this repository.
[CONTRIBUTING.md](https://github.com/skvadrik/re2c/blob/master/CONTRIBUTING.md)
for details about contributions to this repository.
BUILD
@@ -73,6 +73,7 @@ You are welcome to ask for help or share your thoughts and ideas.
AUTHORS
-------
Re2c was originally written by Peter Bumbulis <peter@csg.uwaterloo.ca>.
Since then many people contributed to the project. The current maintainer is
re2c was originally written by Peter Bumbulis <peter@csg.uwaterloo.ca>. Since
then many volunteers have contributed to the project. The current maintainer is
Ulya Trofimovich <skvadrik@gmail.com>.
+14
View File
@@ -0,0 +1,14 @@
workspace(name = "re2c")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "bazel_skylib",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
],
sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506",
)
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()
-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 + [err_file],
tools = [ctx.executable._re2c_tool],
inputs = ctx.files.srcs + ctx.files.data,
command = """
"{re2c}" "{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
+1 -2
View File
@@ -5,7 +5,7 @@
#include <string>
#include <vector>
#include "src/util/c99_stdint.h"
#include <stdint.h>
enum engine_t {
@@ -23,7 +23,6 @@ struct bench_t {
const char *name;
const char *regexp;
const char **strings;
int not_flags;
};
// Need to define benchmarks as functors for benchmark::RegisterBenchmark.
Executable → Regular
+138 -59
View File
@@ -1,4 +1,4 @@
#!/bin/env python3
#!/usr/bin/env python3
import argparse
import json
@@ -12,7 +12,12 @@ plot_preamble = """
\\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.
@@ -47,23 +52,23 @@ plot_begin = """
axis y line*=none,
axis x line=none,
y=0.12in,
width=(\\plotwidth * 0.75),
width=\\plotwidth*1.15,
bar width=\\barwidth,
xshift=\\xplotshift,
yshift=\\yplotshift,
xmax=\\xmax,
xmin=-\\xmax/50,
xmin=0,
ymax=0.7,
ymin=0.3 - \\nrows,
ytick=data,
yticklabels from table={\\table}{algo},
every axis title/.style={below right, at={(-0.5in,0)}},
title=\\title,
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 \\!\\Large{...}\\scriptsize\\! \\fi
\\ifdim \\xoverflow pt=1pt \\!\\ding{220}\\! \\scriptsize \\fi
\\pgfmathprintnumber[assume math mode=true]{\\pgfplotspointmeta}
},
nodes near coords style={shift={(axis direction cs:\\xshift,0)}},
@@ -71,13 +76,21 @@ plot_begin = """
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}
\\def\\xmax{%lf}
\\begin{scope}[xshift=-0.2in, yshift=%sin * 0.75]
%s
\\end{scope}
"""
plot_middle = """
@@ -85,12 +98,13 @@ plot_middle = """
\\def\\yplotshift{%lfin}
\\def\\nrows{%d},
\\def\\title{%s},
\\def\\xmax{%lf}
\\pgfplotstableread {%s} \\table
\\begin{axis}[styleX]
\\begin{axis}[styleX,%s]
\\clip(current axis.south west) rectangle(current axis.north east);
\\addplot[fill=lightgray] table[x=value, y expr=-\\coordindex] from \\table;
\\addplot[fill=%s] table[x=value, y expr=-\\coordindex] from \\table;
\\end{axis}
"""
@@ -103,19 +117,35 @@ plot_end = """
"""
VARIANTS = ['dfa_aot', 'dfa_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)")
return parser.parse_args()
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):
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
@@ -158,6 +188,68 @@ def time_format(time):
return '%%.%dlf' % (-order + 1)
class Params:
def __init__(self, args):
self.barwidth = 0.08
if args.variant == 'dfa_aot':
self.override_params_dfa_aot()
elif args.variant == 'dfa_jit':
self.override_params_dfa_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_dfa_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_dfa_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.
@@ -175,7 +267,7 @@ def time_format(time):
# ], ...
# }
#
def group_benchmarks(benchmarks, relative_to):
def group_benchmarks(benchmarks, params):
benchcount = len(benchmarks)
groups = OrderedDict()
@@ -199,14 +291,14 @@ def group_benchmarks(benchmarks, relative_to):
for name in groups:
group = groups[name]
relto = index_of_algo(group, relative_to)
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 relative_to != None else 1)
time = time / (cputime0 if params.relative_to != None else 1)
maxtime = max(maxtime, time)
avgtime += time
table += ('{%s} ' + time_format(time) + '\n') % (algo, time)
@@ -221,74 +313,60 @@ def group_benchmarks(benchmarks, relative_to):
table += '{%s} %lf\n' % (algo, size)
sizetbl = table
title = gen_title(name)
title = gen_title(name, params.title_suffix)
nrows = len(group)
benchgroups[title] = (timetbl, sizetbl, nrows, regsize, captures)
benchgroups[name] = (title, timetbl, sizetbl, nrows, regsize, captures)
nbench += nrows
maxrows = max(maxrows, nrows)
avgtime /= nbench
avgsize /= nbench
maxtime = min(maxtime, 5 * avgtime)
maxsize = min(maxsize, 5 * avgsize)
factor = 10 if params.relative_to != None else 3
maxtime = min(maxtime, factor * avgtime)
maxsize = min(maxsize, factor * avgsize)
return benchgroups, maxtime, maxsize, maxrows
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(groups, font):
(benchgroups, maxtime, maxsize, maxrows) = groups
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)
# Plot width is approximately half the usual page width.
plotwidth = 3.5
# Bar width is chosen impirically so that it looks good.
barwidth = 0.08
# Plot height is roughly bar width times maximum group size.
plotheight = 0.15 + maxrows * barwidth * 0.75
plot_time = ''
plot_size = ''
i = 0
for name, benchgroup in benchgroups.items():
even = i % 2 == 0
i += 1
(timetbl, sizetbl, nrows, regsize, captures) = benchgroup
(title, timetbl, sizetbl, nrows, regsize, captures) = benchgroup
xshift = 0 if even else plotwidth
yshift = -plotheight * (i if even else i - 1)
title = '\\textbf{%s}' % name
if regsize != None and captures != None:
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_time += plot_middle % (xshift, yshift, nrows, title, timetbl)
plot += plot_middle % (xshift, yshift, nrows, title, params.maxtime,
timetbl, params.local_styles if even else '', 'colorX')
# Generate binary size plots.
if sizetbl != None:
plot_size += plot_middle % (xshift, yshift, nrows, title, sizetbl)
# Glue plots together in one TeX document
plot = plot_preamble
if font == 'comicneue':
plot += plot_font_comicneue
elif font == 'cmbright':
plot += plot_font_cmbright
elif font != None:
sys.exit('error: unsupported font: "%s"' % font)
plot += plot_begin % (plotwidth, barwidth)
if plot_time != '':
plot += (plot_begin_picture % maxtime) + plot_time + plot_end_picture
if plot_size != '':
plot += (plot_begin_picture % maxsize) + plot_size + plot_end_picture
xshift += params.plotwidth
plot += plot_middle % (xshift, yshift, nrows, title, params.maxsize,
sizetbl, '', 'colorY')
plot += plot_end_picture
plot += plot_end
return plot
@@ -300,8 +378,9 @@ def main():
with open(args.input) as f:
input = json.load(f)
groups = group_benchmarks(input['benchmarks'], args.relative_to)
plot = generate_plot(groups, args.font)
params = Params(args)
groups = group_benchmarks(input['benchmarks'], params)
plot = generate_plot(groups, params)
with open(args.output, 'w') as f:
f.write(plot)
-47
View File
@@ -1,47 +0,0 @@
To run benchmarks:
1. Create symlink to the RE2C binary (version 1.0 or older) in the current
directory.
2. Generate input data: files ./http/gen/http.dat and ./uri/gen/uri.dat.
Random data can be generated with the following programs (written in
haskell):
http/gen/gen_http.hs
uri/gen/gen_uri.hs
Use the following scripts to build generators:
http/gen/mk_gen.sh
uri/gen/mk_gen.sh
The size of the generated data is hard-coded in the source code of
generators (and can be easily tweaked).
Alternatively, if you don't have haskell compiler or for any other reason
are unable to build generators, use small data samples provided for each
benchmark (one can copy-paste them many times with 'cat' to obtain a large
input file):
http/gen/sample.dat
uri/gen/sample.dat
3.Run scripts:
./http/simple/__bench.sh
./http/simple/__bench_b.sh
./http/simple/__bench_unopt.sh
./http/rfc7230/__bench.sh
./http/rfc7230/__bench_b.sh
./http/rfc7230/__bench_unopt.sh
./uri/simple/__bench.sh
./uri/simple/__bench_b.sh
./uri/simple/__bench_unopt.sh
./uri/rfc3986/__bench.sh
./uri/rfc3986/__bench_b.sh
./uri/rfc3986/__bench_unopt.sh
Alternatively, run ./__run.sh (it will drop logs in each subdirectory).
-116
View File
@@ -1,116 +0,0 @@
re2c="../../re2c"
compile() {
name="${1}_${2}"
opts="$3"
[ -e ${re2c} ] || { echo "*** no re2c ***"; exit 1; }
${re2c} ${opts} -W ${name}.re -o ${name}_lookahead.c && ls -l --block-size=K ${name}_lookahead.c
${re2c} ${opts} --no-lookahead -W ${name}.re -o ${name}_no_lookahead.c && ls -l --block-size=K ${name}_no_lookahead.c
${re2c} ${opts} -W ${name}_notags.re -o ${name}_notags.c && ls -l --block-size=K ${name}_notags.c
}
run() {
name1="$1"
name2="$2"
name="${name1}_${name2}"
input="../gen/${name1}.dat"
[ -e ${input} ] || { echo "*** no input file ***"; exit 1; }
strip ${name}
cmd="./${name} ${input}"
for i in `seq 1`; do $cmd >/dev/null 2>&1; done # warmup
npass=4
total=0
for i in `seq $npass`; do
t="`TIMEFORMAT='%E'; time ( $cmd 2>/dev/null ) 2>&1 1>/dev/null`"
echo "t:" $t
total=`echo $total + $t | bc -l`
done
average=`echo "$total / $npass" | bc -l`
echo "time: $average"
ls -l --block-size=K ${name}
}
#cflags="-Wall -O2"
cflags="-O2"
run_all() {
name1="$1"
name2="$2"
name="${name1}_${name2}"
echo "---------------- WARMUP (GCC -O2 lookahead) ----------------"
gcc $cflags ${name}_lookahead.c -o${name} && run ${name1} ${name2}
echo "---------------- END WARMUP ----------------"
echo "---------------- GCC -O2 lookahead ----------------"
gcc $cflags ${name}_lookahead.c -o${name} && run ${name1} ${name2}
echo "---------------- GCC -O2 no-lookahead ----------------"
gcc $cflags ${name}_no_lookahead.c -o${name} && run ${name1} ${name2}
echo "---------------- GCC -O2 notags ----------------"
gcc $cflags ${name}_notags.c -o${name} && run ${name1} ${name2}
echo "---------------- CLANG -O2 lookahead ----------------"
clang $cflags ${name}_lookahead.c -o${name} && run ${name1} ${name2}
echo "---------------- CLANG -O2 no-lookahead ----------------"
clang $cflags ${name}_no_lookahead.c -o${name} && run ${name1} ${name2}
echo "---------------- CLANG -O2 notags ----------------"
clang $cflags ${name}_notags.c -o${name} && run ${name1} ${name2}
echo "---------------- TCC -O2 lookahead ----------------"
tcc $cflags ${name}_lookahead.c -o${name} && run ${name1} ${name2}
echo "---------------- TCC -O2 no-lookahead ----------------"
tcc $cflags ${name}_no_lookahead.c -o${name} && run ${name1} ${name2}
echo "---------------- TCC -O2 notags ----------------"
tcc $cflags ${name}_notags.c -o${name} && run ${name1} ${name2}
echo "---------------- PCC -O2 lookahead ----------------"
pcc $cflags ${name}_lookahead.c -o${name} && run ${name1} ${name2}
echo "---------------- PCC -O2 no-lookahead ----------------"
pcc $cflags ${name}_no_lookahead.c -o${name} && run ${name1} ${name2}
echo "---------------- PCC -O2 notags ----------------"
pcc $cflags ${name}_notags.c -o${name} && run ${name1} ${name2}
# echo "---------------- NWCC -O2 lookahead ----------------"
# nwcc $cflags ${name}_lookahead.c -o${name} && run ${name1} ${name2}
# echo "---------------- NWCC -O2 no-lookahead ----------------"
# nwcc $cflags ${name}_no_lookahead.c -o${name} && run ${name1} ${name2}
# echo "---------------- NWCC -O2 notags ----------------"
# nwcc $cflags ${name}_notags.c -o${name} && run ${name1} ${name2}
rm ${name}_lookahead.c
rm ${name}_no_lookahead.c
rm ${name}_notags.c
rm ${name}
}
verify() {
name1="$1"
name2="$2"
name=${name1}_${name2}
input="../gen/${name1}.dat.short"
output="${name1}.dat.short"
[ -e ${input} ] || { echo "*** no input file ***"; exit 1; }
[ -e ${re2c} ] || { echo "*** no re2c ***"; exit 1; }
${re2c} -W ${name}.re -o ${name}_lookahead.c
${re2c} --no-lookahead -W ${name}.re -o ${name}_no_lookahead.c
${re2c} -W ${name}_notags.re -o ${name}_notags.c
g++ -Wall -O2 -DVERIFY ${name}_lookahead.c -o${name} && ./${name} ${input} > ${output} && diff -q ${input} ${output} || echo "lookahead failed"
g++ -Wall -O2 -DVERIFY ${name}_no_lookahead.c -o${name} && ./${name} ${input} > ${output} && diff -q ${input} ${output} || echo "non-lookahead failed"
g++ -Wall -O2 -DVERIFY ${name}_notags.c -o${name} && ./${name} ${input} > ${output} && diff -q ${input} ${output} || echo "notags failed"
rm ${name}_lookahead.c
rm ${name}_no_lookahead.c
rm ${name}_notags.c
rm ${name}
rm ${output}
}
-21
View File
@@ -1,21 +0,0 @@
#!/usr/bin/env bash
set -e
bench() {
cd "$1/$2/"
# ./__verify.sh
./__bench.sh 1> log._ 2>&1
./__bench_unopt.sh 1> log.unopt 2>&1
./__bench_b.sh 1> log.b 2>&1
cd ../..
}
bench http rfc7230
bench http simple
bench uri rfc3986
bench uri simple
@@ -1,365 +0,0 @@
import qualified Test.QuickCheck as Q
import Data.List (intercalate)
import Control.Monad (forM_, when, replicateM)
{-!re2c
crlf = "\n";
sp = " ";
htab = "\t";
ows = (sp | htab)*;
rws = (sp | htab)+;
bws = ows;
digit = [0-9];
alpha = [a-zA-Z];
hexdigit = [0-9a-fA-F];
unreserved = alpha | digit | [-._~];
pct_encoded = "%" hexdigit{2};
sub_delims = [!$&'()*+,;=];
pchar = unreserved | pct_encoded | sub_delims | [:@];
vchar = [\x1f-\x7e];
tchar = [-!#$%&'*+.^_`|~] | digit | alpha;
token = tchar+;
octet = [^\x00];
obs_fold = crlf (sp | htab)+;
obs_text = [\x80-\xff];
field_name = token;
field_vchar = vchar | obs_text;
field_content = field_vchar ((sp | htab)+ field_vchar)?;
field_value = (field_content | obs_fold)*;
header_field = #h1 field_name #h2 ":" ows field_value ows #h3;
method = token;
segment = pchar*;
scheme = alpha (alpha | digit | [-+.])*;
userinfo = (unreserved | pct_encoded | sub_delims | ":")*;
dec_octet
= digit
| [\x31-\x39] digit
| "1" digit{2}
| "2" [\x30-\x34] digit
| "25" [\x30-\x35];
ipv4address = dec_octet "." dec_octet "." dec_octet "." dec_octet;
h16 = hexdigit{1,4};
ls32 = h16 ":" h16 | ipv4address;
ipv6address
= (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)? "::";
ipvfuture = "v" hexdigit+ "." (unreserved | sub_delims | ":" )+;
ip_literal = "[" ( ipv6address | ipvfuture ) "]";
reg_name = (unreserved | pct_encoded | sub_delims)*;
host = ip_literal | ipv4address | reg_name;
port = digit*;
authority = (userinfo "@")? host (":" port)?;
query = (pchar | [/?])*;
path_abempty = ("/" pchar*)*;
path_absolute = "/" (pchar+ ("/" pchar*)*)?;
path_rootless = pchar+ ("/" pchar*)*;
path_empty = "";
hier_part
= "//" authority path_abempty
| (path_absolute | path_rootless | path_empty);
absolute_uri = scheme ":" hier_part ("?" query)?;
absolute_path = ("/" segment)*;
origin_form = absolute_path ("?" query)?;
http_name = "HTTP";
http_version = http_name "/" digit "." digit;
request_target = origin_form | absolute_uri | authority | "*";
request_line = @m1 method @m2 sp @rt1 request_target @rt2 sp @v3 http_version @v4 crlf;
status_code = digit{3};
reason_phrase = (htab | sp | vchar | obs_text)*;
status_line = @v1 http_version @v2 sp @s1 status_code @s2 sp @rp1 reason_phrase @rp2 crlf;
start_line = (request_line | status_line);
message_body = octet*;
message_head = start_line (header_field crlf)* crlf;
-}
type Scheme = String
type User = String
type Password = String
type Host = String
type Port = String
type Path = String
type Query = String
data RequestTarget
= OriginForm Path Query
| AbsoluteURI Scheme User Password Host Port Path Query
| Authority User Password Host Port
| Asterisk
type ReasonPhrase = String
type HTTPVersion = String
type Method = String
type StatusCode = Int
data StartLine
= RequestLine Method RequestTarget HTTPVersion
| StatusLine HTTPVersion StatusCode ReasonPhrase
data HeaderField = HeaderField String
data HTTPMsg = HTTPMsg StartLine [HeaderField]
instance Show RequestTarget where
show (OriginForm p q) = p ++ (if q == "" then "" else "?" ++ q)
show (AbsoluteURI sc us pw ho pr pa q) = concat
[ sc
, ":"
, if ho == "" then "" else "//"
, us
, if us == "" then "" else ":"
, pw
, if pw == "" then "" else "@"
, ho
, if pr == "" then "" else ":"
, pr
, pa
, if q == "" then "" else "?"
, q
]
show (Authority us pw ho pr) = concat
[ us
, if us == "" then "" else ":"
, pw
, if pw == "" then "" else "@"
, ho
, if pr == "" then "" else ":"
, pr
]
show Asterisk = "*"
instance Show StartLine where
show (RequestLine m rt v) = m ++ " " ++ show rt ++ " " ++ v ++ "\n"
show (StatusLine v sc rp) = v ++ " " ++ show sc ++ " " ++ rp ++ "\n"
instance Show HeaderField where show (HeaderField hf) = hf
instance Show HTTPMsg where
show (HTTPMsg sl hfs) = show sl ++ unlines (map show hfs) ++ "\n"
instance Q.Arbitrary HTTPMsg where
arbitrary = do
scheme <- Q.elements ["http", "https", "ftp", "file"]
user <- lstr
password <- anstr
host <- Q.frequency [(10, ipv4), (10, hostname), (1, ipv6)]
port <- mayb $ show <$> (Q.choose (0, 10000) :: Q.Gen Int)
path <- filepath
query <- mayb anstr
request_target <- Q.frequency
[ (1, pure $ OriginForm path query)
, (1, pure $ OriginForm path "")
, (1, pure $ Authority user password host port)
, (1, pure $ Authority user password host "")
, (1, pure $ Authority "" "" host port)
, (1, pure $ Authority "" "" host "")
, (1, pure $ AbsoluteURI scheme user password host port path query)
, (2, pure $ AbsoluteURI scheme "" "" host port path query)
, (1, pure $ AbsoluteURI scheme "" "" "" "" path query)
, (1, pure Asterisk)
]
reason_phrase <- Q.listOf (Q.elements (alphanum ++ space)) :: Q.Gen [Char]
method <- Q.elements
[ "OPTIONS"
, "GET"
, "HEAD"
, "POST"
, "PUT"
, "DELETE"
, "TRACE"
, "CONNECT"
, "PATCH"
]
status_code <- Q.choose (100, 999) :: Q.Gen Int
http_version <- do
n1 <- Q.choose (0, 9) :: Q.Gen Int
n2 <- Q.choose (0, 9) :: Q.Gen Int
return $ "HTTP/" ++ show n1 ++ "." ++ show n2
start_line <- Q.frequency
[ (1, pure $ RequestLine method request_target http_version)
, (1, pure $ StatusLine http_version status_code reason_phrase)
]
-- copy-pasted from https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
header_fields <- Q.listOf1 $ HeaderField <$> Q.elements
-- request examples
[ "Accept: text/plain"
, "Accept-Charset: utf-8"
, "Accept-Encoding: gzip, deflate"
, "Accept-Language: en-US"
, "Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT"
, "Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
, "Cache-Control: no-cache"
, "Connection: keep-alive"
, "Connection: Upgrade"
, "Cookie: $Version=1; Skin=new;"
, "Content-Length: 348"
, "Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ=="
, "Content-Type: application/x-www-form-urlencoded"
, "Date: Tue, 15 Nov 1994 08:12:31 GMT"
, "Expect: 100-continue"
, "Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43"
, "Forwarded: for=192.0.2.43, for=198.51.100.17"
, "From: user@example.com"
, "Host: en.wikipedia.org:8080"
, "Host: en.wikipedia.org"
, "If-Match: \"737060cd8c284d8af7ad3082f209582d\""
, "If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT"
, "If-None-Match: \"737060cd8c284d8af7ad3082f209582d\""
, "If-Range: \"737060cd8c284d8af7ad3082f209582d\""
, "If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT"
, "Max-Forwards: 10"
, "Origin: http://www.example-social-network.com"
, "Pragma: no-cache"
, "Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
, "Range: bytes=500-999"
, "Referer: http://en.wikipedia.org/wiki/Main_Page"
, "TE: trailers, deflate"
, "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0"
, "Upgrade: HTTPS/1.3, IRC/6.9, RTA/x11, websocket"
, "Via: 1.0 fred, 1.1 example.com (Apache/1.1)"
, "Warning: 199 Miscellaneous warning"
, "X-Requested-With: XMLHttpRequest"
, "DNT: 1 (Do Not Track Enabled)"
, "DNT: 0 (Do Not Track Disabled)"
, "X-Forwarded-For: client1, proxy1, proxy2"
, "X-Forwarded-For: 129.78.138.66, 129.78.64.103"
, "X-Forwarded-Host: en.wikipedia.org:8080"
, "X-Forwarded-Host: en.wikipedia.org"
, "X-Forwarded-Proto: https"
, "Front-End-Https: on"
, "X-HTTP-Method-Override: DELETE"
, "X-Att-Deviceid: GT-P7320/P7320XXLPG"
, "x-wap-profile: http://wap.samsungmobile.com/uaprof/SGH-I777.xml"
, "Proxy-Connection: keep-alive"
, "X-UIDH: ..."
, "X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql"
, "X-Request-ID: f058ebd6-02f7-4d3f-942e-904344e8cde5"
-- response examples
, "Access-Control-Allow-Origin: *"
, "Accept-Patch: text/example;charset=utf-8"
, "Accept-Ranges: bytes"
, "Age: 12"
, "Allow: GET, HEAD"
, "Alt-Svc: http/1.1=\"http2.example.com:8001\"; ma=7200"
, "Cache-Control: max-age=3600"
, "Connection: close"
, "Content-Disposition: attachment; filename=\"fname.ext\""
, "Content-Encoding: gzip"
, "Content-Language: da"
, "Content-Length: 51"
, "Content-Location: /index.htm"
, "Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ=="
, "Content-Range: bytes 21010-47021/47022"
, "Content-Type: text/html; charset=utf-8"
, "Date: Tue, 15 Nov 1994 08:12:31 GMT"
, "ETag: \"737060cd8c284d8af7ad3082f209582d\""
, "Expires: Thu, 01 Dec 1994 16:00:00 GMT"
, "Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT"
, "Link: </feed>; rel=\"alternate\""
, "Location: http://www.w3.org/pub/WWW/People.html"
, "P3P: CP=\"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.\""
, "Pragma: no-cache"
, "Proxy-Authenticate: Basic"
, "Public-Key-Pins: max-age=2592000; pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\";"
, "Refresh: 5; url=http://www.w3.org/pub/WWW/People.html"
, "Retry-After: 120"
, "Retry-After: Fri, 07 Nov 2014 23:59:59 GMT"
, "Server: Apache/2.4.1 (Unix)"
, "Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1"
, "Strict-Transport-Security: max-age=16070400; includeSubDomains"
, "Trailer: Max-Forwards"
, "Transfer-Encoding: chunked"
, "Tk: ?"
, "Upgrade: HTTPS/1.3, IRC/6.9, RTA/x11, websocket"
, "Vary: *"
, "Vary: Accept-Language"
, "Via: 1.0 fred, 1.1 example.com (Apache/1.1)"
, "Warning: 199 Miscellaneous warning"
, "WWW-Authenticate: Basic"
, "X-Frame-Options: deny"
, "Status: 200 OK"
, "X-XSS-Protection: 1; mode=block"
, "X-WebKit-CSP: default-src 'self'"
, "X-Content-Type-Options: nosniff"
, "X-Powered-By: PHP/5.4.0"
, "X-UA-Compatible: IE=EmulateIE7"
, "X-UA-Compatible: IE=edge"
, "X-UA-Compatible: Chrome=1"
, "X-Content-Duration: 42.666"
, "Upgrade-Insecure-Requests: 1"
, "X-Request-ID: f058ebd6-02f7-4d3f-942e-904344e8cde5"
]
return $ HTTPMsg start_line header_fields
lalpha :: [Char]
lalpha = ['a'..'z']
ualpha :: [Char]
ualpha = ['A'..'Z']
alpha :: [Char]
alpha = lalpha ++ ualpha
digit :: [Char]
digit = ['0'..'9']
hexdigit :: [Char]
hexdigit = ['a'..'f'] ++ ['A'..'F'] ++ digit
alphanum :: [Char]
alphanum = alpha ++ digit
space :: [Char]
space = [' ', '\t']
lstr :: Q.Gen String
lstr = Q.listOf1 (Q.elements lalpha) :: Q.Gen [Char]
anstr :: Q.Gen String
anstr = Q.listOf1 (Q.elements alphanum) :: Q.Gen [Char]
ipv4 :: Q.Gen String
ipv4 = do
let octet = show <$> (Q.choose (0,255) :: Q.Gen Int)
intercalate "." <$> replicateM 4 octet
ipv6 :: Q.Gen String
ipv6 = do
let hexgroup = do
k <- Q.choose (1, 4) :: Q.Gen Int
replicateM k (Q.elements hexdigit)
n <- Q.choose (0, 8) :: Q.Gen Int
m <- Q.choose (1, n) :: Q.Gen Int
hh <- replicateM n hexgroup
return $ (++ "]") . ("[" ++) $ case n of
8 -> intercalate ":" hh
_ -> concat [intercalate ":" (take m hh), "::", intercalate ":" (drop m hh)]
hostname :: Q.Gen String
hostname = do
subdomains <- Q.listOf1 (take 10 <$> lstr)
return $ intercalate "." $ take 5 subdomains
filepath :: Q.Gen String
filepath = do
subdirs <- Q.listOf1 lstr
return $ concat $ map ("/" ++) $ take 10 subdirs
mayb :: Q.Gen String -> Q.Gen String
mayb gen = Q.oneof [gen, pure ""]
main :: IO ()
main = do
let f = "http.dat"
writeFile f ""
forM_ [0 .. 170000 :: Int] $ \i -> do
when (i `mod` 1000 == 0) $ print i
msg <- Q.generate (Q.arbitrary :: Q.Gen HTTPMsg)
appendFile f $ show msg
@@ -1 +0,0 @@
ghc -O2 -Wall gen_http.hs
@@ -1,101 +0,0 @@
HEAD file://cwidoaajjb.pqzeztqtg.iagnuhmdq.npliaihmqn.yuptnwn/hlhkojvjvzmsgccwcpwhh/qfliekillmmdz/aypkwffmdojvpdodmrouzxuupqp/gjqnmbk/mnbtpocjbe/ttvqsflbsqirgahmutddqucg/nkycantossaikwulmgemuqttwx/foqeceoyiowyeftxpr/syjcvolygaguylfkx/gwgx?7B9Jq5CNzjzSFzJl7cCL4oUX HTTP/6.2
Content-Disposition: attachment; filename="fname.ext"
Content-Language: da
If-Match: "737060cd8c284d8af7ad3082f209582d"
If-None-Match: "737060cd8c284d8af7ad3082f209582d"
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
Connection: Upgrade
X-Powered-By: PHP/5.4.0
Proxy-Authenticate: Basic
Warning: 199 Miscellaneous warning
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Retry-After: Fri, 07 Nov 2014 23:59:59 GMT
Upgrade: HTTPS/1.3, IRC/6.9, RTA/x11, websocket
X-Att-Deviceid: GT-P7320/P7320XXLPG
Alt-Svc: http/1.1="http2.example.com:8001"; ma=7200
Accept-Ranges: bytes
Content-Language: da
Cache-Control: no-cache
Age: 12
Accept-Encoding: gzip, deflate
Content-Length: 51
WWW-Authenticate: Basic
Vary: *
Upgrade-Insecure-Requests: 1
Strict-Transport-Security: max-age=16070400; includeSubDomains
Public-Key-Pins: max-age=2592000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
Pragma: no-cache
Content-Length: 51
Host: en.wikipedia.org
X-Frame-Options: deny
POST https://hubgkuzz.qqwqvsfccy.psvyjbuva.afjqkipasn.zrdeeznzgo:7150/yfztaoqwaqlyuxfdkosgkegikcn/xme HTTP/6.6
Cache-Control: max-age=3600
Content-Length: 51
Content-Type: application/x-www-form-urlencoded
Upgrade: HTTPS/1.3, IRC/6.9, RTA/x11, websocket
Alt-Svc: http/1.1="http2.example.com:8001"; ma=7200
Date: Tue, 15 Nov 1994 08:12:31 GMT
Accept-Charset: utf-8
Cookie: $Version=1; Skin=new;
X-Request-ID: f058ebd6-02f7-4d3f-942e-904344e8cde5
CONNECT zwusyxlehg.qxqjpqqjzq.rnrnmjbspj.ugbkvsriyw.gpchzrlqkk:8638 HTTP/7.4
Pragma: no-cache
Transfer-Encoding: chunked
Content-Location: /index.htm
X-Att-Deviceid: GT-P7320/P7320XXLPG
Public-Key-Pins: max-age=2592000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
Accept-Patch: text/example;charset=utf-8
Host: en.wikipedia.org:8080
X-Forwarded-For: client1, proxy1, proxy2
Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT
Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
DNT: 1 (Do Not Track Enabled)
X-UA-Compatible: Chrome=1
Tk: ?
Refresh: 5; url=http://www.w3.org/pub/WWW/People.html
X-UA-Compatible: IE=edge
Expect: 100-continue
DNT: 0 (Do Not Track Disabled)
WWW-Authenticate: Basic
Content-Type: application/x-www-form-urlencoded
Public-Key-Pins: max-age=2592000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
X-Content-Type-Options: nosniff
X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql
X-Forwarded-Host: en.wikipedia.org
X-Att-Deviceid: GT-P7320/P7320XXLPG
Content-Location: /index.htm
Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT
HTTP/9.5 559 u
Date: Tue, 15 Nov 1994 08:12:31 GMT
Content-Length: 348
X-Forwarded-Proto: https
Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Expires: Thu, 01 Dec 1994 16:00:00 GMT
WWW-Authenticate: Basic
Allow: GET, HEAD
Warning: 199 Miscellaneous warning
POST wllvzjwvpp.mhagladifk.joaq.rnprjmcpum.opadaxtssr HTTP/6.4
Warning: 199 Miscellaneous warning
Proxy-Authenticate: Basic
Content-Encoding: gzip
X-Forwarded-Host: en.wikipedia.org
Strict-Transport-Security: max-age=16070400; includeSubDomains
Content-Language: da
Allow: GET, HEAD
Retry-After: Fri, 07 Nov 2014 23:59:59 GMT
If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
X-Forwarded-For: client1, proxy1, proxy2
HTTP/0.6 463 2bs
From: user@example.com
X-Forwarded-Host: en.wikipedia.org
X-Forwarded-Host: en.wikipedia.org
X-UA-Compatible: IE=edge
X-UA-Compatible: IE=edge
Date: Tue, 15 Nov 1994 08:12:31 GMT
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile http rfc7230 ""
run_all http rfc7230
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile http rfc7230 "-b"
run_all http rfc7230
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile http rfc7230 "--no-optimize-tags"
run_all http rfc7230
@@ -1,4 +0,0 @@
. ../../__bench_utils.sh
verify http rfc7230
@@ -1,318 +0,0 @@
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct taglist_t {
struct taglist_t *pred;
long dist;
} taglist_t;
typedef struct taglistpool_t {
taglist_t *head;
taglist_t *next;
taglist_t *last;
} taglistpool_t;
typedef struct {
FILE *file;
char *buf;
char *lim;
char *cur;
char *mar;
char *tok;
/*!stags:re2c format = "char *@@;\n"; */
/*!mtags:re2c format = "taglist_t *@@;\n"; */
taglistpool_t tlp;
int eof;
} input_t;
static void taglistpool_clear(taglistpool_t *tlp, input_t *in)
{
tlp->next = tlp->head;
/*!mtags:re2c format = "in->@@ = 0;\n"; */
}
static void taglistpool_init(taglistpool_t *tlp)
{
static const unsigned size = 1024 * 1024;
tlp->head = (taglist_t*)malloc(size * sizeof(taglist_t));
tlp->next = tlp->head;
tlp->last = tlp->head + size;
}
static void taglistpool_free(taglistpool_t *tlp)
{
free(tlp->head);
tlp->head = tlp->next = tlp->last = NULL;
}
static taglist_t *taglistpool_next(taglistpool_t *tlp)
{
if (tlp->next < tlp->last) {
return tlp->next++;
}
const unsigned size = tlp->last - tlp->head;
taglist_t *head = (taglist_t*)malloc(2 * size * sizeof(taglist_t));
memcpy(head, tlp->head, size * sizeof(taglist_t));
free(tlp->head);
tlp->head = head;
tlp->next = head + size;
tlp->last = head + size * 2;
return tlp->next++;
}
static void taglist(taglist_t **ptl, const char *b, const char *t, taglistpool_t *tlp)
{
taglist_t *tl = taglistpool_next(tlp);
tl->pred = *ptl;
tl->dist = t - b;
*ptl = tl;
}
/*!max:re2c*/
static const size_t SIZE = 4096;
static void init_input(input_t *in, const char *fname)
{
in->file = fopen(fname, "r");
in->buf = (char*) malloc(SIZE + YYMAXFILL);
in->lim = in->buf + SIZE;
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
/*!stags:re2c format = "in->@@ = 0;\n"; */
/*!mtags:re2c format = "in->@@ = 0;\n"; */
taglistpool_init(&in->tlp);
in->eof = 0;
}
static void free_input(input_t *in)
{
fclose(in->file);
free(in->buf);
taglistpool_free(&in->tlp);
}
static int fill(input_t *in, size_t need)
{
size_t free;
if (in->eof) return 1;
free = in->tok - in->buf;
if (free < need) return 2;
memmove(in->buf, in->tok, in->lim - in->tok);
in->lim -= free;
in->cur -= free;
in->mar -= free;
in->tok -= free;
/*!stags:re2c format = "if (in->@@) in->@@ -= free;\n"; */
in->lim += fread(in->lim, 1, free, in->file);
if (in->lim < in->buf + SIZE) {
in->eof = 1;
memset(in->lim, 0, YYMAXFILL);
in->lim += YYMAXFILL;
}
return 0;
}
static void print_headers(const char *tok,
const taglist_t *h1, const taglist_t *h2,
const taglist_t *h3, const taglist_t *h4,
const taglist_t *h5)
{
if (!h1 || !h2 || !h3 || !h4 || !h5) {
assert(!h1 && !h2 && !h3 && !h4 && !h5);
return;
}
print_headers(tok, h1->pred, h2->pred, h3->pred, h4->pred, h5->pred);
printf("%.*s%.*s%.*s%.*s\n",
(int)(h2->dist - h1->dist), tok + h1->dist,
(int)(h3->dist - h2->dist), tok + h2->dist,
(int)(h4->dist - h3->dist), tok + h3->dist,
(int)(h5->dist - h4->dist), tok + h4->dist);
}
#define YYCTYPE char
#define YYCURSOR in->cur
#define YYMARKER in->mar
#define YYLIMIT in->lim
#define YYMTAGP(tl) taglist(&tl, in->tok, in->cur, &in->tlp)
#define YYMTAGN(tl) taglist(&tl, in->tok, NULL, &in->tlp)
#define YYFILL(n) if (fill(in, n) != 0) return 2;
static int lex(input_t *in, long *count, long *total)
{
const char *of, *au, *at,
*hs1, *hs3, *m1, *p1, *p3, *p5, *q1, *q3,
*hs2, *hs4, *m2, *p2, *p4, *p6, *q2, *q4,
*r1, *r3, *rp1, *s1, *st1, *u1, *u3, *v1, *v3,
*r2, *r4, *rp2, *s2, *st2, *u2, *u4, *v2, *v4;
taglist_t *h1, *h2, *h3, *h4, *h5;
long c, t;
c = 0; t = 0;
of = au = at
= hs1 = hs3 = m1 = p1 = p3 = p5 = q1 = q3
= hs2 = hs4 = m2 = p2 = p4 = p6 = q2 = q4
= r1 = r3 = rp1 = s1 = st1 = u1 = u3 = v1 = v3
= r2 = r4 = rp2 = s2 = st2 = u2 = u4 = v2 = v4 = NULL;
loop:
in->tok = in->cur;
/*!re2c
re2c:flags:tags = 1;
re2c:tags:expression = "in->@@";
end = "\x00";
eol = "\n";
crlf = eol;
sp = " ";
htab = "\t";
ows = (sp | htab)*;
digit = [0-9];
alpha = [a-zA-Z];
hexdigit = [0-9a-fA-F];
unreserved = alpha | digit | [-._~];
pct_encoded = "%" hexdigit{2};
sub_delims = [!$&'()*+,;=];
pchar = unreserved | pct_encoded | sub_delims | [:@];
vchar = [\x1f-\x7e];
tchar = [-!#$%&'*+.^_`|~] | digit | alpha;
obs_fold = crlf (sp | htab)+;
obs_text = [\x80-\xff];
field_name = tchar+;
field_vchar = vchar | obs_text;
field_content = field_vchar ((sp | htab)+ field_vchar)?;
field_value = (field_content | obs_fold)*;
header_field = #h1 field_name #h2 ":" ows #h3 field_value #h4 ows #h5;
scheme = alpha (alpha | digit | [-+.])*;
userinfo = (unreserved | pct_encoded | sub_delims | ":")*;
dec_octet
= digit
| [\x31-\x39] digit
| "1" digit{2}
| "2" [\x30-\x34] digit
| "25" [\x30-\x35];
ipv4address = dec_octet "." dec_octet "." dec_octet "." dec_octet;
h16 = hexdigit{1,4};
ls32 = h16 ":" h16 | ipv4address;
ipv6address
= (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)? "::";
ipvfuture = "v" hexdigit+ "." (unreserved | sub_delims | ":" )+;
ip_literal = "[" ( ipv6address | ipvfuture ) "]";
reg_name = (unreserved | pct_encoded | sub_delims)*;
path_abempty = ("/" pchar*)*;
path_absolute = "/" (pchar+ ("/" pchar*)*)?;
path_rootless = pchar+ ("/" pchar*)*;
path_empty = "";
host = ip_literal | ipv4address | reg_name;
port = digit*;
query = (pchar | [/?])*;
absolute_uri = @s1 scheme @s2 ":"
( "//" (@u1 userinfo @u2 "@")? @hs1 host @hs2 (":" @r1 port @r2)? @p1 path_abempty @p2
| @p3 (path_absolute | path_rootless | path_empty) @p4
) ("?" @q1 query @q2)?;
authority = (@u3 userinfo @u4 "@")? @hs3 host @hs4 (":" @r3 port @r4)?;
origin_form = @p5 path_abempty @p6 ("?" @q3 query @q4)?;
http_name = "HTTP";
http_version = http_name "/" digit "." digit;
request_target
= @at authority
| @au absolute_uri
| @of origin_form
| "*";
method = tchar+;
request_line = @m1 method @m2 sp request_target sp @v3 http_version @v4 crlf;
status_code = digit{3};
reason_phrase = (htab | sp | vchar | obs_text)*;
status_line = @v1 http_version @v2 sp @st1 status_code @st2 sp @rp1 reason_phrase @rp2 crlf;
start_line = (request_line | status_line);
message_head = start_line (header_field crlf)* crlf;
* { return 1; }
end { *count = c; *total = t; return 0; }
eol { goto loop; }
message_head {
#ifndef VERIFY
c += 1;
if (st1) t += (v2 - v1) + (st2 - st1) + (rp2 - rp1);
if (m1) {
if (of) t += (p6 - p5) + (q4 - q3);
if (au) t += (s2 - s1) + (u2 - u1) + (hs2 - hs1)
+ (r2 - r1) + (p2 - p1) + (p4 - p3) + (q2 - q1);
if (at) t += (u4 - u3) + (hs4 - hs3) + (r4 - r3);
t += (v4 - v3);
}
for (; h1 != 0; h1 = h1->pred, h2 = h2->pred,
h3 = h3->pred, h4 = h4->pred, h5 = h5->pred) {
t += (h2->dist - h1->dist) + (h3->dist - h2->dist)
+ (h4->dist - h3->dist) + (h5->dist - h4->dist);
}
#else
if (st1) {
printf("%.*s %.*s %.*s\n",
(int)(v2 - v1), v1,
(int)(st2 - st1), st1,
(int)(rp2 - rp1), rp1);
} else if (m1) {
printf("%.*s ", (int)(m2 - m1), m1);
if (of) {
printf("%.*s", (int)(p6 - p5), p5);
if (q3) printf("?%.*s", (int)(q4 - q3), q3);
} else if (au) {
printf("%.*s:", (int)(s2 - s1), s1);
if (p1) printf("//");
if (u1) printf("%.*s@", (int)(u2 - u1), u1);
printf("%.*s", (int)(hs2 - hs1), hs1);
if (r1) printf(":%.*s", (int)(r2 - r1), r1);
if (p1) printf("%.*s", (int)(p2 - p1), p1);
if (p3) printf("%.*s", (int)(p4 - p3), p3);
if (q1) printf("?%.*s", (int)(q2 - q1), q1);
} else if (at) {
if (u3) printf("%.*s@", (int)(u4 - u3), u3);
printf("%.*s", (int)(hs4 - hs3), hs3);
if (r3) printf(":%.*s", (int)(r4 - r3), r3);
} else {
printf("*");
}
printf(" %.*s\n", (int)(v4 - v3), v3);
}
print_headers(in->tok, h1, h2, h3, h4, h5);
printf("\n");
#endif
taglistpool_clear(&in->tlp, in);
goto loop;
}
*/
}
int main(int argc, char **argv)
{
long count, total;
input_t in;
init_input(&in, argv[1]);
switch (lex(&in, &count, &total)) {
case 0: fprintf(stderr, "ok, parsed %ld HTTPs, peeked %ld chars\n", count, total); break;
case 1: fprintf(stderr, "syntax error: %s\n", in.cur); break;
case 2: fprintf(stderr, "fill failed\n"); break;
default: fprintf(stderr, "panic!\n"); break;
}
free_input(&in);
return 0;
}
@@ -1,180 +0,0 @@
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct {
FILE *file;
char *buf;
char *lim;
char *cur;
char *mar;
char *tok;
int eof;
} input_t;
/*!max:re2c*/
static const size_t SIZE = 4096;
static void init_input(input_t *in, const char *fname)
{
in->file = fopen(fname, "r");
in->buf = (char*) malloc(SIZE + YYMAXFILL);
in->lim = in->buf + SIZE;
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
in->eof = 0;
}
static void free_input(input_t *in)
{
fclose(in->file);
free(in->buf);
}
static int fill(input_t *in, size_t need)
{
size_t free;
if (in->eof) return 1;
free = in->tok - in->buf;
if (free < need) return 2;
memmove(in->buf, in->tok, in->lim - in->tok);
in->lim -= free;
in->cur -= free;
in->mar -= free;
in->tok -= free;
in->lim += fread(in->lim, 1, free, in->file);
if (in->lim < in->buf + SIZE) {
in->eof = 1;
memset(in->lim, 0, YYMAXFILL);
in->lim += YYMAXFILL;
}
return 0;
}
#define YYCTYPE char
#define YYCURSOR in->cur
#define YYMARKER in->mar
#define YYLIMIT in->lim
#define YYFILL(n) if (fill(in, n) != 0) return 2;
static int lex(input_t *in, long *count, long *total)
{
long c, t;
c = 0; t = 0;
loop:
in->tok = in->cur;
/*!re2c
end = "\x00";
eol = "\n";
crlf = eol;
sp = " ";
htab = "\t";
ows = (sp | htab)*;
digit = [0-9];
alpha = [a-zA-Z];
hexdigit = [0-9a-fA-F];
unreserved = alpha | digit | [-._~];
pct_encoded = "%" hexdigit{2};
sub_delims = [!$&'()*+,;=];
pchar = unreserved | pct_encoded | sub_delims | [:@];
vchar = [\x1f-\x7e];
tchar = [-!#$%&'*+.^_`|~] | digit | alpha;
obs_fold = crlf (sp | htab)+;
obs_text = [\x80-\xff];
field_name = tchar+;
field_vchar = vchar | obs_text;
field_content = field_vchar ((sp | htab)+ field_vchar)?;
field_value = (field_content | obs_fold)*;
header_field = field_name ":" ows field_value ows;
scheme = alpha (alpha | digit | [-+.])*;
userinfo = (unreserved | pct_encoded | sub_delims | ":")*;
dec_octet
= digit
| [\x31-\x39] digit
| "1" digit{2}
| "2" [\x30-\x34] digit
| "25" [\x30-\x35];
ipv4address = dec_octet "." dec_octet "." dec_octet "." dec_octet;
h16 = hexdigit{1,4};
ls32 = h16 ":" h16 | ipv4address;
ipv6address
= (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)? "::";
ipvfuture = "v" hexdigit+ "." (unreserved | sub_delims | ":" )+;
ip_literal = "[" ( ipv6address | ipvfuture ) "]";
reg_name = (unreserved | pct_encoded | sub_delims)*;
path_abempty = ("/" pchar*)*;
path_absolute = "/" (pchar+ ("/" pchar*)*)?;
path_rootless = pchar+ ("/" pchar*)*;
path_empty = "";
host = ip_literal | ipv4address | reg_name;
port = digit*;
query = (pchar | [/?])*;
absolute_uri = scheme ":"
( "//" (userinfo "@")? host (":" port)? path_abempty
| (path_absolute | path_rootless | path_empty)
) ("?" query)?;
authority = (userinfo "@")? host (":" port)?;
origin_form = path_abempty ("?" query)?;
http_name = "HTTP";
http_version = http_name "/" digit "." digit;
request_target
= authority
| absolute_uri
| origin_form
| "*";
method = tchar+;
request_line = method sp request_target sp http_version crlf;
status_code = digit{3};
reason_phrase = (htab | sp | vchar | obs_text)*;
status_line = http_version sp status_code sp reason_phrase crlf;
start_line = (request_line | status_line);
message_head = start_line (header_field crlf)* crlf;
* { return 1; }
end { *count = c; return 0; }
eol { goto loop; }
message_head {
#ifndef VERIFY
c += 1;
t += in->cur - in->tok;
#else
printf("%.*s", (int)(in->cur - in->tok), in->tok);
#endif
goto loop;
}
*/
}
int main(int argc, char **argv)
{
long count, total;
input_t in;
init_input(&in, argv[1]);
switch (lex(&in, &count, &total)) {
case 0: fprintf(stderr, "ok, parsed %ld HTTPs, peeked %ld chars\n", count, total); break;
case 1: fprintf(stderr, "syntax error: %s\n", in.cur); break;
case 2: fprintf(stderr, "fill failed\n"); break;
default: fprintf(stderr, "panic!\n"); break;
}
free_input(&in);
return 0;
}
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile http simple ""
run_all http simple
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile http simple "-b"
run_all http simple
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile http simple "--no-optimize-tags"
run_all http simple
@@ -1,4 +0,0 @@
. ../../__bench_utils.sh
verify http simple
@@ -1,231 +0,0 @@
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct taglist_t {
struct taglist_t *pred;
long dist;
} taglist_t;
typedef struct taglistpool_t {
taglist_t *head;
taglist_t *next;
taglist_t *last;
} taglistpool_t;
typedef struct {
FILE *file;
char *buf;
char *lim;
char *cur;
char *mar;
char *tok;
/*!stags:re2c format = "char *@@;\n"; */
/*!mtags:re2c format = "taglist_t *@@;\n"; */
taglistpool_t tlp;
int eof;
} input_t;
static void taglistpool_clear(taglistpool_t *tlp, input_t *in)
{
tlp->next = tlp->head;
/*!mtags:re2c format = "in->@@ = 0;\n"; */
}
static void taglistpool_init(taglistpool_t *tlp)
{
static const unsigned size = 1024 * 1024;
tlp->head = (taglist_t*)malloc(size * sizeof(taglist_t));
tlp->next = tlp->head;
tlp->last = tlp->head + size;
}
static void taglistpool_free(taglistpool_t *tlp)
{
free(tlp->head);
tlp->head = tlp->next = tlp->last = NULL;
}
static taglist_t *taglistpool_next(taglistpool_t *tlp)
{
if (tlp->next < tlp->last) {
return tlp->next++;
}
const unsigned size = tlp->last - tlp->head;
taglist_t *head = (taglist_t*)malloc(2 * size * sizeof(taglist_t));
memcpy(head, tlp->head, size * sizeof(taglist_t));
free(tlp->head);
tlp->head = head;
tlp->next = head + size;
tlp->last = head + size * 2;
return tlp->next++;
}
static void taglist(taglist_t **ptl, const char *b, const char *t, taglistpool_t *tlp)
{
taglist_t *tl = taglistpool_next(tlp);
tl->pred = *ptl;
tl->dist = t - b;
*ptl = tl;
}
/*!max:re2c*/
static const size_t SIZE = 4096;
static void init_input(input_t *in, const char *fname)
{
in->file = fopen(fname, "r");
in->buf = (char*) malloc(SIZE + YYMAXFILL);
in->lim = in->buf + SIZE;
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
/*!stags:re2c format = "in->@@ = 0;\n"; */
/*!mtags:re2c format = "in->@@ = 0;\n"; */
taglistpool_init(&in->tlp);
in->eof = 0;
}
static void free_input(input_t *in)
{
fclose(in->file);
free(in->buf);
taglistpool_free(&in->tlp);
}
static int fill(input_t *in, size_t need)
{
size_t free;
if (in->eof) return 1;
free = in->tok - in->buf;
if (free < need) return 2;
memmove(in->buf, in->tok, in->lim - in->tok);
in->lim -= free;
in->cur -= free;
in->mar -= free;
in->tok -= free;
/*!stags:re2c format = "if (in->@@) in->@@ -= free;\n"; */
in->lim += fread(in->lim, 1, free, in->file);
if (in->lim < in->buf + SIZE) {
in->eof = 1;
memset(in->lim, 0, YYMAXFILL);
in->lim += YYMAXFILL;
}
return 0;
}
static void print_headers(const char *tok,
const taglist_t *h1, const taglist_t *h2, const taglist_t *h3)
{
if (!h1 || !h2 || !h3) {
assert(!h1 && !h2 && !h3);
return;
}
print_headers(tok, h1->pred, h2->pred, h3->pred);
printf("%.*s%.*s\n",
(int)(h2->dist - h1->dist), tok + h1->dist,
(int)(h3->dist - h2->dist), tok + h2->dist);
}
#define YYCTYPE char
#define YYCURSOR in->cur
#define YYMARKER in->mar
#define YYLIMIT in->lim
#define YYMTAGP(tl) taglist(&tl, in->tok, in->cur, &in->tlp)
#define YYMTAGN(tl) taglist(&tl, in->tok, NULL, &in->tlp)
#define YYFILL(n) if (fill(in, n) != 0) return 2;
static int lex(input_t *in, long *count, long *total)
{
const char *s1, *s2, *v1, *v2, *v3, *v4, *m1, *m2, *rp1, *rp2, *rt1, *rt2;
taglist_t *h1, *h2, *h3;
long c, t;
c = 0; t = 0;
loop:
in->tok = in->cur;
/*!re2c
re2c:flags:tags = 1;
re2c:tags:expression = "in->@@";
end = "\x00";
eol = "\n";
sp = " ";
htab = "\t";
ows = (sp | htab)*;
char = [-._~%!$&'()*+,;=a-zA-Z0-9];
tchar = [-._~%!$&'*+#^`|a-zA-Z0-9];
vchar = [\x1f-\x7e\x80-\xff];
scheme = [-+.a-zA-Z0-9]+;
userinfo = (char | [:])+;
host = (char | [:[\]])+;
port = [0-9]*;
path = (char | [:@/])*;
query = (char | [:@?/])*;
obs_fold = eol (sp | htab)+;
field_content = vchar ((sp | htab)+ vchar)?;
header_field = #h1 tchar+ ":" #h2 ows (field_content | obs_fold)* ows #h3;
authority = (userinfo "@")? host (":" port)?;
absolute_uri = scheme ":" ("//" (userinfo "@")? host (":" port)?)? path ("?" query)?;
origin_form = "/" path ("?" query)?;
http_version = "HTTP/" [0-9] "." [0-9];
request_target = authority | absolute_uri | origin_form | "*";
method = tchar+;
request_line = @m1 method @m2 sp @rt1 request_target @rt2 sp @v3 http_version @v4 eol;
status_code = [0-9]{3};
reason_phrase = (htab | sp | vchar)*;
status_line = @v1 http_version @v2 sp @s1 status_code @s2 sp @rp1 reason_phrase @rp2 eol;
start_line = (request_line | status_line);
message_head = start_line (header_field eol)* eol;
* { return 1; }
end { *count = c; *total = t; return 0; }
eol { goto loop; }
message_head {
#ifndef VERIFY
c += 1;
t += (v2 - v1) + (s2 - s1) + (rp2 - rp1)
+ (m2 - m1) + (rt2 - rt1) + (v4 - v3);
for (; h1 != 0; h1 = h1->pred, h2 = h2->pred, h3 = h3->pred) {
t += (h2->dist - h1->dist) + (h3->dist - h2->dist);
}
#else
if (s1) printf("%.*s %.*s %.*s\n",
(int)(v2 - v1), v1,
(int)(s2 - s1), s1,
(int)(rp2 - rp1), rp1);
if (m1) printf("%.*s %.*s %.*s\n",
(int)(m2 - m1), m1,
(int)(rt2 - rt1), rt1,
(int)(v4 - v3), v3);
print_headers(in->tok, h1, h2, h3);
printf("\n");
#endif
taglistpool_clear(&in->tlp, in);
goto loop;
}
*/
}
int main(int argc, char **argv)
{
long count, total;
input_t in;
init_input(&in, argv[1]);
switch (lex(&in, &count, &total)) {
case 0: fprintf(stderr, "ok, parsed %ld HTTPs, peeked %ld chars\n", count, total); break;
case 1: fprintf(stderr, "syntax error: %s\n", in.cur); break;
case 2: fprintf(stderr, "fill failed\n"); break;
default: fprintf(stderr, "panic!\n"); break;
}
free_input(&in);
return 0;
}
@@ -1,134 +0,0 @@
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct {
FILE *file;
char *buf;
char *lim;
char *cur;
char *mar;
char *tok;
int eof;
} input_t;
/*!max:re2c*/
static const size_t SIZE = 4096;
static void init_input(input_t *in, const char *fname)
{
in->file = fopen(fname, "r");
in->buf = (char*) malloc(SIZE + YYMAXFILL);
in->lim = in->buf + SIZE;
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
in->eof = 0;
}
static void free_input(input_t *in)
{
fclose(in->file);
free(in->buf);
}
static int fill(input_t *in, size_t need)
{
size_t free;
if (in->eof) return 1;
free = in->tok - in->buf;
if (free < need) return 2;
memmove(in->buf, in->tok, in->lim - in->tok);
in->lim -= free;
in->cur -= free;
in->mar -= free;
in->tok -= free;
in->lim += fread(in->lim, 1, free, in->file);
if (in->lim < in->buf + SIZE) {
in->eof = 1;
memset(in->lim, 0, YYMAXFILL);
in->lim += YYMAXFILL;
}
return 0;
}
#define YYCTYPE char
#define YYCURSOR in->cur
#define YYMARKER in->mar
#define YYLIMIT in->lim
#define YYFILL(n) if (fill(in, n) != 0) return 2;
static int lex(input_t *in, long *count, long *total)
{
long c, t;
c = 0; t = 0;
loop:
in->tok = in->cur;
/*!re2c
end = "\x00";
eol = "\n";
sp = " ";
htab = "\t";
ows = (sp | htab)*;
char = [-._~%!$&'()*+,;=a-zA-Z0-9];
tchar = [-._~%!$&'*+#^`|a-zA-Z0-9];
vchar = [\x1f-\x7e\x80-\xff];
scheme = [-+.a-zA-Z0-9]+;
userinfo = (char | [:])+;
host = (char | [:[\]])+;
port = [0-9]*;
path = (char | [:@/])*;
query = (char | [:@?/])*;
obs_fold = eol (sp | htab)+;
field_content = vchar ((sp | htab)+ vchar)?;
header_field = tchar+ ":" ows (field_content | obs_fold)* ows;
authority = (userinfo "@")? host (":" port)?;
absolute_uri = scheme ":" ("//" (userinfo "@")? host (":" port)?)? path ("?" query)?;
origin_form = "/" path ("?" query)?;
http_version = "HTTP/" [0-9] "." [0-9];
request_target = authority | absolute_uri | origin_form | "*";
method = tchar+;
request_line = method sp request_target sp http_version eol;
status_code = [0-9]{3};
reason_phrase = (htab | sp | vchar)*;
status_line = http_version sp status_code sp reason_phrase eol;
start_line = (request_line | status_line);
message_head = start_line (header_field eol)* eol;
* { return 1; }
end { *count = c; *total = t; return 0; }
eol { goto loop; }
message_head {
#ifndef VERIFY
c += 1;
t += in->cur - in->tok;
#else
printf("%.*s", (int)(in->cur - in->tok), in->tok);
#endif
goto loop;
}
*/
}
int main(int argc, char **argv)
{
long count, total;
input_t in;
init_input(&in, argv[1]);
switch (lex(&in, &count, &total)) {
case 0: fprintf(stderr, "ok, parsed %ld HTTPs, peeked %ld chars\n", count, total); break;
case 1: fprintf(stderr, "syntax error: %s\n", in.cur); break;
case 2: fprintf(stderr, "fill failed\n"); break;
default: fprintf(stderr, "panic!\n"); break;
}
free_input(&in);
return 0;
}
@@ -1,111 +0,0 @@
{-# LANGUAGE LambdaCase #-}
import qualified Test.QuickCheck as Q
import qualified Test.QuickCheck.Monadic as QM
import qualified System.Random as SR
import qualified System.Process as SP
import qualified System.Exit as SE
import qualified Data.ByteString.Char8 as BS
import Data.Char (chr)
import Data.List (intercalate)
import Control.Monad (forM_, when, replicateM)
import Data.Foldable (foldlM)
type Scheme = String
type User = String
type Password = String
type Host = String
type Port = String
type Path = String
type Query = String
type Fragment = String
data URI = URI Scheme User Password Host Port Path Query Fragment
instance Show URI where
show (URI sc us pw ho po pa qu fr) = concat
[ sc
, ":"
, if ho == "" then "" else "//"
, us
, if us == "" then "" else ":"
, pw
, if pw == "" then "" else "@"
, ho
, if po == "" then "" else ":"
, po
, pa
, if qu == "" then "" else "?"
, qu
, if fr == "" then "" else "#"
, fr
]
lalpha = ['a'..'z']
ualpha = ['A'..'Z']
alpha = lalpha ++ ualpha
digit = ['0'..'9']
hexdigit = ['a'..'f'] ++ ['A'..'F'] ++ digit
alphanum = alpha ++ digit
lstr :: Q.Gen String
lstr = Q.listOf1 (Q.elements lalpha) :: Q.Gen [Char]
anstr :: Q.Gen String
anstr = Q.listOf1 (Q.elements alphanum) :: Q.Gen [Char]
ipv4 :: Q.Gen String
ipv4 = do
let octet = show <$> (Q.choose (0,255) :: Q.Gen Int)
intercalate "." <$> replicateM 4 octet
ipv6 :: Q.Gen String
ipv6 = do
let hexgroup = do
k <- Q.choose (1, 4) :: Q.Gen Int
replicateM k (Q.elements hexdigit)
n <- Q.choose (0, 8) :: Q.Gen Int
m <- Q.choose (1, n) :: Q.Gen Int
hh <- replicateM n hexgroup
return $ (++ "]") . ("[" ++) $ case n of
8 -> intercalate ":" hh
_ -> concat [intercalate ":" (take m hh), "::", intercalate ":" (drop m hh)]
hostname :: Q.Gen String
hostname = do
subdomains <- Q.listOf1 (take 10 <$> lstr)
return $ intercalate "." $ take 5 subdomains
filepath :: Q.Gen String
filepath = do
subdirs <- Q.listOf1 lstr
return $ concat $ map ("/" ++) $ take 10 subdirs
mayb :: Q.Gen String -> Q.Gen String
mayb gen = Q.oneof [gen, pure ""]
instance Q.Arbitrary URI where
arbitrary = do
scheme <- Q.elements ["http", "https", "ftp", "file"]
user <- lstr
password <- anstr
host <- Q.frequency [(10, ipv4), (10, hostname), (1, ipv6)]
port <- mayb $ show <$> (Q.choose (0, 10000) :: Q.Gen Int)
path <- filepath
query <- mayb anstr
fragment <- mayb anstr
Q.frequency
[ (1, pure $ URI scheme user password host port path query fragment)
, (2, pure $ URI scheme "" "" host port path query fragment)
, (1, pure $ URI scheme "" "" "" "" path query fragment)
]
main = do
let f = "uri.dat"
writeFile f ""
forM_ [0..600000] $ \i -> do
when (i `mod` 100 == 0) $ print i
uri <- Q.generate (Q.arbitrary :: Q.Gen URI)
appendFile f $ show uri ++ "\n"
@@ -1 +0,0 @@
ghc -O2 -Wall gen_uri.hs
@@ -1,20 +0,0 @@
https://130.226.207.254/jbtvkjzrjthmbnypntksydqelq/jjdsj/udvjilrctugdnuolrrzkr/cwkvkxjhehiodwfytl/ufgjg/nfgpg/iu#mE39x1S2vXd1o
https:/ohgudpayfmlfhcoyvgjhyqfbua/linrqhrhlaiixdbxonbmn/atrgtgdphcz/rr/dtdhuqshwxhewfn/fyuawfip/qugtmsmwxuywignctpbtabge/acijwctkdqawozgns/eipjsaiiurudzqrviveu/bijkdhwtmlneypz#EhkI5ylLokJNKaBsd
http://cjop.xhsqcbwtp.vrfzoaodga.nnkbwbmq.cfvgulvcfj/geuhnhetwsqjfuojmvaziemd/eodavsnwgauluaclpjqb/phmdaviaz#AlBK76vA
http:/ijnjyrzldk/jyapegxurikjmip/olhhrswcvepexhshr/whlsdorizwdovszxcuwnnbexfy/ohsfdqoryjotnqrzagziyg/ajxvofxromjwirayehuw/swubrfzbwtmtvomstbaumtvksghg#D
https://220.234.52.233/peiygqiuiwezsr/qnymfpaurkzifllbwtkzqgpkcdp/hbeschxipcpf/soakqi/bxbhzothilaxznoiprg/gaqsbgqobypjyzwdyvcmr/fszwjmnixfc/t/vlumvtpktjjkuzxix/nqqwnxwkyinkjngixkcgrobuwe#L7cwKfIxLBv
http://190.102.237.163/jfymqrdxatqxxosr/eodoflhmefpbqunvzkwkxfgxj/ife/bbijkiueazcfwodgsddft/xpegxlfbdzafenjaqgjbnqrsb/poizlwooajtnejxpycftrcsfjkruln?DEVzXYliuaVThP2db4oE32q#fXoCDA1BJyjOUBJwpMOOC36Q7o6n
https://prlmszykmotajvhfingpy:5gJpVNFdVUCBumKIV0ciYat@tyekbzfzyn.kirctezfig.gvefopbqlf.onykhnytqd.uofiltbvdv/jiqe/odskecdswmouqaunyfuerpefcusuxa/fkqdmaueh/vzkskyxrpqkfzzjgujqmkt/qfnzplmxvunhvjq/kskwzjeueepwokxguatetegnjzgu/pysxiyoyssbfiibuonhk/wmzxsguoqoeutnkaanqqd/pkpbwvoepeutjbedkdimko/vogpbm#fBzuGdIV22C
https://uqaqxbiszxuwfd:mIai0iqs9Ps3UEvpmu@qwnsormfld.uikzf.rajsatakhr:2634/pcervqbppzxjydwilqwoxa/byyvgqvnqjmqgvnjmbio/sifgcfwfhlxrnzpjlo/zhdejqnlcgmmknd/bpqtpqsxyrlvfohbkwavetd/lcsxvflqocclqvilbuvgcggupysof/wzuwqttblllpdjxxqzjnv/uqzxnhuobrldciwbnrfqmv/jpbashfkljtfciiqivtdpeqrfhz/hdjtjdgfyja
file://ngngiosyeynlnyegckpwp:QoW1iBFx@171.234.221.207/ltdgogjynxrrnjygsltmcfihfsqfvk/mixerqujwbektqyzimadzdx/urb/vrvjsofccprkaavyyp/sycatuazj/vlmmmvozycmvpicrpcipfxywp/zddjtiahb
https://58.187.10.250:8256/ialbromwxodapxebh/lwddbb/fghhkaztbruuibdfwjym/vrwkmqrnqumknb/kytsuocatyouppiec/wxdwpeudwfghhdwiagjrgllqhoaxhn/tnugkxbiimo/ydrzmbihqoibkcvm/rqyczmveyz/nefixtpefrkuxntolkwgiamp
ftp://hukiuvtpzvmwmnxgomsujflyk:b1MSVh7pUWPjK24nnJoOOwKIET36s@6.119.196.62:5869/cyhsyhjykv#NlE8g3hz1Ebta8kk7LUvTm
ftp://fhvvtgyuua.ogahfrqbvg.cughxcqaqu.nyfdeg.mzbkmrnfib:4544/vwqfmulbaoxczkm/clixvtifydkj/shrflpkrq/vi/sruymrqxodjrbwvhtbwzvmlsys/uv/ybywv#ADdXUBIIgy
http:/laxn/rugglbrcb/znzlrhyoxapkznmedipktxhqzeohlw/rfmg/uyntiipnzdwjlfy/fktcgxrgcsfkr/rbbcxzybieozevucqxpmeq/apqyszyxgpq/zbknrolqhmtwjshockr/kicrlzsbtx?VbJp1VLkYC#mYPZplrVnb7UHSatrpGAwi
https:/ztpluoa/jphvoweijirbvnmek/pbvimnscpb/catfuxpwqihpqbnrjvkhmbdagvqzsu/czjmvoa/btgpsmqroaxkqt/kcvpypw/eqbifrwpexhsvhmrdtfj/y/gqmjqiyqfkjatby#xDfmbp6mzuOS73yV
https://jqhvw:ssV@[4::a8:5ab]:7064/tto/xjdjuxhkqhuvmdbwn/kejaxevbfon/nxrvxlozfd/nefd/drhf/ya/meebpkpao/go/sv?XZtzUKrb4Qq19CsMmL
https:/nrmkjtzsirjeybbznmbxefn/tbunkcjyoksunhdiiec/iuguxifycwqd/cjaqmevkjkwf/lysgdnbidkjtulmtdsxuiw/ykmcmukxjjmzdutq/nndpaxzkknxawibpc/bsuqrecyypwqxsbbslv/hzfitcvz?zVwBAXzGU6
https://179.106.111.234:4602/kaojoxgqtrtqjqbxojhplkgo/sakwfopartajvd/jdjmzkjzxsutx/jvorvytygowpcugwcpdp/gf/skqbpbmaxznokzio/jmgdwytfu/zwronpnfltlqsdkm/bjkpnbqymcebiccdvdh/gelbqajbdysgljczflyocuxqehpvrn#iePJE2SwM2H2z7pGWE3MZQu79
https://sgcoeyexpydtvuvrlncfv:cCVO9XO6W6lY58itexKFMeputSs7@199.131.253.98/cxoyvdvmlofvxhlfdoosxyrzhei/dqnifd/kuweqsnj/wrcmglfaorwemv/oyotkyibrraabiwatl/mw/fmyxtdztnyqmciijifflmb/kyfprlhxhcemmr/ds/ubuqzto
ftp://226.47.189.219/uttpjalgzirumdxcqstmop/rsavfunauwrnzbrbccv/qvnzgkypemnulagkcnxgmhg/vdzboggzuttu/wimrcceehdaznqnvguhi/hcmbkir/vxcincavxbheiuuqoukjsnd/rnkr/repqv/cdncqpiqhrughnlhbu?04HBSdquIv5jRN5POmtHr#t8TxSWH16brGRC79JCiBCp8bEyF
http://lkjzakdejf.kwbbhfnwhj.cypikjr.wogqvpwhbz.dwyohxizdk:4775/iwnmuufehazvnzgsrqm/gdjpojnwrlwikzpoevnpnkvw/wrbctzxujufpuyeue/dlzajtkhkbuj/zptqonydlp/qatdpxbpwvndzwrmynkfrbrpyix/ehavmzuuptjcv/bbosue/xulpwugitisuaagcmlvwtfykvr/izafvzsb?dY4#eIfVkGptVdWsH8D
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile uri rfc3986 ""
run_all uri rfc3986
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile uri rfc3986 "-b"
run_all uri rfc3986
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile uri rfc3986 "--no-optimize-tags"
run_all uri rfc3986
@@ -1,4 +0,0 @@
. ../../__bench_utils.sh
verify uri rfc3986
@@ -1,178 +0,0 @@
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*!max:re2c*/
static const size_t SIZE = 4096;
typedef struct {
FILE *file;
char *buf;
char *lim;
char *cur;
char *mar;
char *tok;
/*!stags:re2c format = "char *@@;\n"; */
int eof;
} input_t;
static void init_input(input_t *in, const char *fname)
{
in->file = fopen(fname, "r");
in->buf = (char*) malloc(SIZE + YYMAXFILL);
in->lim = in->buf + SIZE;
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
/*!stags:re2c format = "in->@@ = 0;\n"; */
in->eof = 0;
}
static void free_input(input_t *in)
{
free(in->buf);
fclose(in->file);
}
static int fill(input_t *in, size_t need)
{
size_t free;
if (in->eof) return 1;
free = in->tok - in->buf;
if (free < need) return 2;
memmove(in->buf, in->tok, in->lim - in->tok);
in->lim -= free;
in->cur -= free;
in->mar -= free;
in->tok -= free;
/*!stags:re2c format = "if (in->@@) in->@@ -= free;\n"; */
in->lim += fread(in->lim, 1, free, in->file);
if (in->lim < in->buf + SIZE) {
in->eof = 1;
memset(in->lim, 0, YYMAXFILL);
in->lim += YYMAXFILL;
}
return 0;
}
static int lex(input_t *in, long *count, long *total)
{
const char
*s1, *u1, *h1, *h3, *h5, *r1, *p1, *p3, *q1, *f1,
*s2, *u2, *h2, *h4, *h6, *r2, *p2, *p4, *q2, *f2;
long c, t;
c = 0; t = 0;
loop:
in->tok = in->cur;
/*!re2c
re2c:define:YYCTYPE = char;
re2c:define:YYCURSOR = in->cur;
re2c:define:YYMARKER = in->mar;
re2c:define:YYLIMIT = in->lim;
re2c:define:YYFILL = "if (fill(in, @@) != 0) return 2;";
re2c:define:YYFILL:naked = 1;
re2c:flags:tags = 1;
re2c:tags:expression = "in->@@";
end = "\x00";
eol = "\n";
alpha = [a-zA-Z];
digit = [0-9];
hexdigit = [0-9a-fA-F];
unreserved = alpha | digit | [-._~];
pct_encoded = "%" hexdigit{2};
sub_delims = [!$&'()*+,;=];
pchar = unreserved | pct_encoded | sub_delims | [:@];
scheme = @s1 alpha (alpha | digit | [-+.])* @s2;
userinfo = @u1 (unreserved | pct_encoded | sub_delims | ":")* @u2;
dec_octet
= digit
| [\x31-\x39] digit
| "1" digit{2}
| "2" [\x30-\x34] digit
| "25" [\x30-\x35];
ipv4address = dec_octet "." dec_octet "." dec_octet "." dec_octet;
h16 = hexdigit{1,4};
ls32 = h16 ":" h16 | ipv4address;
ipv6address
= (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)? "::";
ipvfuture = "v" hexdigit+ "." (unreserved | sub_delims | ":" )+;
ip_literal = "[" ( ipv6address | ipvfuture ) "]";
reg_name = (unreserved | pct_encoded | sub_delims)*;
host
= @h1 ip_literal @h2
| @h3 ipv4address @h4
| @h5 reg_name @h6;
port = @r1 digit* @r2;
authority = (userinfo "@")? host (":" port)?;
path_abempty = ("/" pchar*)*;
path_absolute = "/" (pchar+ ("/" pchar*)*)?;
path_rootless = pchar+ ("/" pchar*)*;
path_empty = "";
hier_part
= "//" authority @p1 path_abempty @p2
| @p3 (path_absolute | path_rootless | path_empty) @p4;
query = @q1 (pchar | [/?])* @q2;
fragment = @f1 (pchar | [/?])* @f2;
uri = scheme ":" hier_part ("?" query)? ("#" fragment)?;
* { return 1; }
end { *count = c; *total = t; return 0; }
eol { goto loop; }
uri {
#ifndef VERIFY
c += 1;
t += (s2 - s1) + (u2 - u1) + (h2 - h1) + (h4 - h3)
+ (h6 - h5) + (r2 - r1) + (p2 - p1) + (p4 - p3)
+ (q2 - q1) + (f2 - f1);
#else
printf("%.*s:", (int)(s2 - s1), s1);
if (p1) printf("//");
if (u1) printf("%.*s@", (int)(u2 - u1), u1);
if (h1) printf("%.*s", (int)(h2 - h1), h1);
if (h3) printf("%.*s", (int)(h4 - h3), h3);
if (h5) printf("%.*s", (int)(h6 - h5), h5);
if (r1) printf(":%.*s", (int)(r2 - r1), r1);
if (p1) printf("%.*s", (int)(p2 - p1), p1);
if (p3) printf("%.*s", (int)(p4 - p3), p3);
if (q1) printf("?%.*s", (int)(q2 - q1), q1);
if (f1) printf("#%.*s", (int)(f2 - f1), f1);
printf("\n");
#endif
goto loop;
}
*/
}
int main(int argc, char **argv)
{
long count, total;
input_t in;
init_input(&in, argv[1]);
switch (lex(&in, &count, &total)) {
case 0: fprintf(stderr, "ok, parsed %ld URIs, peeked %ld chars\n", count, total); break;
case 1: fprintf(stderr, "syntax error\n"); break;
case 2: fprintf(stderr, "yyfill failed\n"); break;
default: fprintf(stderr, "panic!\n"); break;
}
free_input(&in);
return 0;
}
@@ -1,153 +0,0 @@
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*!max:re2c*/
static const size_t SIZE = 4096;
typedef struct {
FILE *file;
char *buf;
char *lim;
char *cur;
char *mar;
char *tok;
int eof;
} input_t;
static void init_input(input_t *in, const char *fname)
{
in->file = fopen(fname, "r");
in->buf = (char*) malloc(SIZE + YYMAXFILL);
in->lim = in->buf + SIZE;
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
in->eof = 0;
}
static void free_input(input_t *in)
{
free(in->buf);
fclose(in->file);
}
static int fill(input_t *in, size_t need)
{
size_t free;
if (in->eof) return 1;
free = in->tok - in->buf;
if (free < need) return 2;
memmove(in->buf, in->tok, in->lim - in->tok);
in->lim -= free;
in->cur -= free;
in->mar -= free;
in->tok -= free;
in->lim += fread(in->lim, 1, free, in->file);
if (in->lim < in->buf + SIZE) {
in->eof = 1;
memset(in->lim, 0, YYMAXFILL);
in->lim += YYMAXFILL;
}
return 0;
}
static int lex(input_t *in, long *count, long *total)
{
long c, t;
c = 0; t = 0;
loop:
in->tok = in->cur;
/*!re2c
re2c:define:YYCTYPE = char;
re2c:define:YYCURSOR = in->cur;
re2c:define:YYMARKER = in->mar;
re2c:define:YYLIMIT = in->lim;
re2c:define:YYFILL = "if (fill(in, @@) != 0) return 2;";
re2c:define:YYFILL:naked = 1;
end = "\x00";
eol = "\n";
alpha = [a-zA-Z];
digit = [0-9];
hexdigit = [0-9a-fA-F];
unreserved = alpha | digit | [-._~];
pct_encoded = "%" hexdigit{2};
sub_delims = [!$&'()*+,;=];
pchar = unreserved | pct_encoded | sub_delims | [:@];
scheme = alpha (alpha | digit | [-+.])*;
userinfo = (unreserved | pct_encoded | sub_delims | ":")*;
dec_octet
= digit
| [\x31-\x39] digit
| "1" digit{2}
| "2" [\x30-\x34] digit
| "25" [\x30-\x35];
ipv4address = dec_octet "." dec_octet "." dec_octet "." dec_octet;
h16 = hexdigit{1,4};
ls32 = h16 ":" h16 | ipv4address;
ipv6address
= (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)? "::";
ipvfuture = "v" hexdigit+ "." (unreserved | sub_delims | ":" )+;
ip_literal = "[" ( ipv6address | ipvfuture ) "]";
reg_name = (unreserved | pct_encoded | sub_delims)*;
host = ip_literal | ipv4address | reg_name;
port = digit*;
authority = (userinfo "@")? host (":" port)?;
path_abempty = ("/" pchar*)*;
path_absolute = "/" (pchar+ ("/" pchar*)*)?;
path_rootless = pchar+ ("/" pchar*)*;
path_empty = "";
hier_part
= "//" authority path_abempty
| (path_absolute | path_rootless | path_empty);
query = (pchar | [/?])*;
fragment = (pchar | [/?])*;
uri = scheme ":" hier_part ("?" query)? ("#" fragment)?;
* { return 1; }
end { *count = c; *total = t; return 0; }
eol { goto loop; }
uri {
#ifndef VERIFY
c += 1;
t += in->cur - in->tok;
#else
printf("%.*s\n", (int)(in->cur - in->tok), in->tok);
#endif
goto loop;
}
*/
}
int main(int argc, char **argv)
{
long count, total;
input_t in;
init_input(&in, argv[1]);
switch (lex(&in, &count, &total)) {
case 0: fprintf(stderr, "ok, parsed %ld URIs, peeked %ld chars\n", count, total); break;
case 1: fprintf(stderr, "syntax error\n"); break;
case 2: fprintf(stderr, "yyfill failed\n"); break;
default: fprintf(stderr, "panic!\n"); break;
}
free_input(&in);
return 0;
}
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile uri simple ""
run_all uri simple
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile uri simple "-b"
run_all uri simple
@@ -1,6 +0,0 @@
. ../../__bench_utils.sh
compile uri simple "--no-optimize-tags"
run_all uri simple
@@ -1,4 +0,0 @@
. ../../__bench_utils.sh
verify uri simple
@@ -1,134 +0,0 @@
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*!max:re2c*/
static const size_t SIZE = 4096;
typedef struct {
FILE *file;
char *buf;
char *lim;
char *cur;
char *mar;
char *tok;
/*!stags:re2c format = "char *@@;\n"; */
int eof;
} input_t;
static void init_input(input_t *in, const char *fname)
{
in->file = fopen(fname, "r");
in->buf = (char*) malloc(SIZE + YYMAXFILL);
in->lim = in->buf + SIZE;
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
/*!stags:re2c format = "in->@@ = 0;\n"; */
in->eof = 0;
}
static void free_input(input_t *in)
{
free(in->buf);
fclose(in->file);
}
static int fill(input_t *in, size_t need)
{
size_t free;
if (in->eof) return 1;
free = in->tok - in->buf;
if (free < need) return 2;
memmove(in->buf, in->tok, in->lim - in->tok);
in->lim -= free;
in->cur -= free;
in->mar -= free;
in->tok -= free;
/*!stags:re2c format = "if (in->@@) in->@@ -= free;\n"; */
in->lim += fread(in->lim, 1, free, in->file);
if (in->lim < in->buf + SIZE) {
in->eof = 1;
memset(in->lim, 0, YYMAXFILL);
in->lim += YYMAXFILL;
}
return 0;
}
static int lex(input_t *in, long *count, long *total)
{
const char
*s1, *u1, *h1, *r1, *p1, *q1, *f1,
*s2, *u2, *h2, *r2, *p2, *q2, *f2;
long c, t;
c = 0; t = 0;
loop:
in->tok = in->cur;
/*!re2c
re2c:define:YYCTYPE = char;
re2c:define:YYCURSOR = in->cur;
re2c:define:YYMARKER = in->mar;
re2c:define:YYLIMIT = in->lim;
re2c:define:YYFILL = "if (fill(in, @@) != 0) return 2;";
re2c:define:YYFILL:naked = 1;
re2c:flags:tags = 1;
re2c:tags:expression = "in->@@";
end = "\x00";
eol = "\n";
char = [-._~%!$&'()*+,;=a-zA-Z0-9];
scheme = @s1 [-+.a-zA-Z0-9]+ @s2;
userinfo = @u1 (char | [:])+ @u2;
host = @h1 (char | [:[\]])+ @h2;
port = @r1 [0-9]* @r2;
path = @p1 (char | [:@/])* @p2;
query = @q1 (char | [:@?/])* @q2;
fragment = @f1 (char | [:@?/])* @f2;
uri = scheme ":" ("//" (userinfo "@")? host (":" port)?)? path ("?" query)? ("#" fragment)?;
* { return 1; }
end { *count = c; *total = t; return 0; }
eol { goto loop; }
uri {
#ifndef VERIFY
c += 1;
t += (s2 - s1) + (u2 - u1) + (h2 - h1)
+ (r2 - r1) + (p2 - p1) + (q2 - q1) + (f2 - f1);
#else
printf("%.*s:", (int)(s2 - s1), s1);
if (h1) printf("//");
if (u1) printf("%.*s@", (int)(u2 - u1), u1);
if (h1) printf("%.*s", (int)(h2 - h1), h1);
if (r1) printf(":%.*s", (int)(r2 - r1), r1);
printf("%.*s", (int)(p2 - p1), p1);
if (q1) printf("?%.*s", (int)(q2 - q1), q1);
if (f1) printf("#%.*s", (int)(f2 - f1), f1);
printf("\n");
#endif
goto loop;
}
*/
}
int main(int argc, char **argv)
{
long count, total;
input_t in;
init_input(&in, argv[1]);
switch (lex(&in, &count, &total)) {
case 0: fprintf(stderr, "ok, parsed %ld URIs, peeked %ld chars\n", count, total); break;
case 1: fprintf(stderr, "syntax error\n"); break;
case 2: fprintf(stderr, "yyfill failed\n"); break;
default: fprintf(stderr, "panic!\n"); break;
}
free_input(&in);
return 0;
}
@@ -1,116 +0,0 @@
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*!max:re2c*/
static const size_t SIZE = 4096;
typedef struct {
FILE *file;
char *buf;
char *lim;
char *cur;
char *mar;
char *tok;
int eof;
} input_t;
static void init_input(input_t *in, const char *fname)
{
in->file = fopen(fname, "r");
in->buf = (char*) malloc(SIZE + YYMAXFILL);
in->lim = in->buf + SIZE;
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
in->eof = 0;
}
static void free_input(input_t *in)
{
free(in->buf);
fclose(in->file);
}
static int fill(input_t *in, size_t need)
{
size_t free;
if (in->eof) return 1;
free = in->tok - in->buf;
if (free < need) return 2;
memmove(in->buf, in->tok, in->lim - in->tok);
in->lim -= free;
in->cur -= free;
in->mar -= free;
in->tok -= free;
in->lim += fread(in->lim, 1, free, in->file);
if (in->lim < in->buf + SIZE) {
in->eof = 1;
memset(in->lim, 0, YYMAXFILL);
in->lim += YYMAXFILL;
}
return 0;
}
static int lex(input_t *in, long *count, long *total)
{
long c, t;
c = 0; t = 0;
loop:
in->tok = in->cur;
/*!re2c
re2c:define:YYCTYPE = char;
re2c:define:YYCURSOR = in->cur;
re2c:define:YYMARKER = in->mar;
re2c:define:YYLIMIT = in->lim;
re2c:define:YYFILL = "if (fill(in, @@) != 0) return 2;";
re2c:define:YYFILL:naked = 1;
end = "\x00";
eol = "\n";
char = [-._~%!$&'()*+,;=a-zA-Z0-9];
scheme = [-+.a-zA-Z0-9]+;
userinfo = (char | [:])+;
host = (char | [:[\]])+;
port = [0-9]*;
path = (char | [:@/])*;
query = (char | [:@?/])*;
fragment = (char | [:@?/])*;
uri = scheme ":" ("//" (userinfo "@")? host (":" port)?)? path ("?" query)? ("#" fragment)?;
* { return 1; }
end { *count = c; *total = t; return 0; }
eol { goto loop; }
uri {
#ifndef VERIFY
c += 1;
t += in->cur - in->tok;
#else
printf("%.*s\n", (int)(in->cur - in->tok), in->tok);
#endif
goto loop;
}
*/
}
int main(int argc, char **argv)
{
long count, total;
input_t in;
init_input(&in, argv[1]);
switch (lex(&in, &count, &total)) {
case 0: fprintf(stderr, "ok, parsed %ld URIs, peeked %ld chars\n", count, total); break;
case 1: fprintf(stderr, "syntax error\n"); break;
case 2: fprintf(stderr, "yyfill failed\n"); break;
default: fprintf(stderr, "panic!\n"); break;
}
free_input(&in);
return 0;
}
+38 -15
View File
@@ -125,8 +125,15 @@ foreach(bench ${BENCHMARKS})
endforeach()
# re2c
file(MAKE_DIRECTORY "${ENG_DIR}/re2c/")
file(MAKE_DIRECTORY "${GEN_DIR}/re2c/")
set(RE2C "${CMAKE_BINARY_DIR}/re2c")
set(RE2C3 "${ENG_DIR}/re2c/re2c3")
add_custom_command(
OUTPUT "${RE2C3}"
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/engines/re2c/getre2c3.sh"
WORKING_DIRECTORY "${ENG_DIR}/re2c/"
)
set(RE2C_FLAGS "--reusable" "--tags" "--no-generation-date" "--no-version")
set(COMMON_RE2C
"${SRC_DIR}/re2c/common.re"
@@ -135,28 +142,44 @@ set(COMMON_RE2C
"${SRC_DIR}/re2c/include-eof/fill.re"
"${SRC_DIR}/re2c/include-eof/fill_email.re"
)
# deprecated algorithms were removed after re2c-3.0
set(DEPRECATED_ALGS "tdfa0" "stadfa")
foreach(bench ${BENCHMARKS})
foreach(eof "" "-eof")
foreach(alg "tdfa1" "tdfa0" "stadfa")
set(src_file "${SRC_DIR}/re2c/${bench}.re")
set(gen_file "${GEN_DIR}/re2c/${bench}${eof}-${alg}.c")
set(pregen_file "${PREGEN_DIR}/re2c/${bench}${eof}-${alg}.c")
# always regenerate re2c benchmarks (regardless of 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}")
file(RELATIVE_PATH rel_inc_path "${CMAKE_CURRENT_BINARY_DIR}" "${SRC_DIR}/re2c/include${eof}")
set(re2c_flags ${RE2C_FLAGS} "-I" "${rel_inc_path}")
if("${alg}" STREQUAL "tdfa0")
set(re2c_flags ${re2c_flags} "--no-lookahead")
elseif("${alg}" STREQUAL "stadfa")
set(re2c_flags ${re2c_flags} "--stadfa")
# always regenerate re2c benchmarks, except for deprecated algorithms
if(RE2C_REGEN_BENCHMARKS OR NOT (alg IN_LIST DEPRECATED_ALGS))
# for deprecated algorithms use re2c-3.0
if(alg IN_LIST DEPRECATED_ALGS)
set(re2c_for_gen "${RE2C3}")
else()
set(re2c_for_gen "${RE2C}")
endif()
file(RELATIVE_PATH rel_src_file "${CMAKE_CURRENT_BINARY_DIR}" "${src_file}")
file(RELATIVE_PATH rel_gen_file "${CMAKE_CURRENT_BINARY_DIR}" "${gen_file}")
file(RELATIVE_PATH rel_inc_path "${CMAKE_CURRENT_BINARY_DIR}" "${SRC_DIR}/re2c/include${eof}")
set(re2c_flags ${RE2C_FLAGS} "-I" "${rel_inc_path}")
if("${alg}" STREQUAL "tdfa0")
set(re2c_flags ${re2c_flags} "--no-lookahead")
elseif("${alg}" STREQUAL "stadfa")
set(re2c_flags ${re2c_flags} "--stadfa")
endif()
add_custom_command(
OUTPUT "${gen_file}"
COMMAND "${re2c_for_gen}" ${re2c_flags} "${rel_src_file}" -o "${rel_gen_file}"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${gen_file}" "${pregen_file}"
DEPENDS "${src_file}" ${COMMON_RE2C} "${re2c_for_gen}"
)
else()
add_custom_command(
OUTPUT "${gen_file}"
COMMAND "${CMAKE_COMMAND}" -E copy "${pregen_file}" "${gen_file}"
DEPENDS "${pregen_file}"
)
endif()
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}" ${COMMON_RE2C} "${RE2C}"
)
list(APPEND GEN "${gen_file}")
endforeach()
endforeach()
+44 -35
View File
@@ -7,6 +7,7 @@ DAT_DIR = data
CFLAGS = -O3 -I $(SRC_DIR)
RAGEL = $(ENG_DIR)/ragel/ragel7
KLEENEX = $(ENG_DIR)/kleenex/kexc
RE2C3 = $(ENG_DIR)/re2c/re2c3
RE2C = $(top_builddir)/re2c
RE2C_FLAGS_COMMON = --reusable --tags --no-generation-date --no-version
RE2C_FLAGS = $(RE2C_FLAGS_COMMON) -I $(SRC_DIR)/re2c/include
@@ -60,21 +61,23 @@ BIN_RAGEL = $(patsubst $(GEN_DIR)%.c, $(BIN_DIR)%, $(GEN_RAGEL))
COMMON_RAGEL = $(COMMON_SRC) $(SRC_DIR)/ragel/common.c
GEN_RE2C_TDFA1 = $(patsubst %, $(GEN_DIR)/re2c/%-tdfa1.c, $(BENCHMARKS))
GEN_RE2C_TDFA0 = $(patsubst %, $(GEN_DIR)/re2c/%-tdfa0.c, $(BENCHMARKS))
GEN_RE2C_STADFA = $(patsubst %, $(GEN_DIR)/re2c/%-stadfa.c, $(BENCHMARKS))
GEN_RE2C_EOF_TDFA1 = $(patsubst %, $(GEN_DIR)/re2c/%-eof-tdfa1.c, $(BENCHMARKS))
GEN_RE2C_EOF_TDFA0 = $(patsubst %, $(GEN_DIR)/re2c/%-eof-tdfa0.c, $(BENCHMARKS))
GEN_RE2C_EOF_STADFA = $(patsubst %, $(GEN_DIR)/re2c/%-eof-stadfa.c, $(BENCHMARKS))
GEN_RE2C_TDFA1 = $(patsubst %, $(GEN_DIR)/re2c/%-tdfa1.c, $(BENCHMARKS))
GEN_RE2C_EOF_TDFA1 = $(patsubst %, $(GEN_DIR)/re2c/%-eof-tdfa1.c, $(BENCHMARKS))
GEN_RE2C = \
$(GEN_RE2C_TDFA1) \
$(GEN_RE2C_TDFA0) \
$(GEN_RE2C_STADFA) \
$(GEN_RE2C_EOF_TDFA1) \
$(GEN_RE2C_EOF_TDFA0) \
$(GEN_RE2C_EOF_STADFA)
$(GEN_RE2C_EOF_TDFA1)
BIN_RE2C = $(patsubst $(GEN_DIR)%.c, $(BIN_DIR)%, $(GEN_RE2C))
GEN_RE2C3_TDFA0 = $(patsubst %, $(GEN_DIR)/re2c/%-tdfa0.c, $(BENCHMARKS))
GEN_RE2C3_EOF_TDFA0 = $(patsubst %, $(GEN_DIR)/re2c/%-eof-tdfa0.c, $(BENCHMARKS))
GEN_RE2C3_STADFA = $(patsubst %, $(GEN_DIR)/re2c/%-stadfa.c, $(BENCHMARKS))
GEN_RE2C3_EOF_STADFA = $(patsubst %, $(GEN_DIR)/re2c/%-eof-stadfa.c, $(BENCHMARKS))
GEN_RE2C3 = \
$(GEN_RE2C_TDFA0) \
$(GEN_RE2C_EOF_TDFA0) \
$(GEN_RE2C3_STADFA) \
$(GEN_RE2C3_EOF_STADFA)
BIN_RE2C = $(patsubst $(GEN_DIR)%.c, $(BIN_DIR)%, $(GEN_RE2C) $(GEN_RE2C3))
COMMON_RE2C = \
$(COMMON_SRC) \
@@ -97,7 +100,7 @@ GEN_KLEENEX = $(patsubst %, $(GEN_DIR)/kleenex/%.c, \
BIN_KLEENEX = $(patsubst $(GEN_DIR)%.c, $(BIN_DIR)%, $(GEN_KLEENEX))
GEN = $(GEN_RAGEL) $(GEN_RE2C) $(GEN_KLEENEX)
GEN = $(GEN_RAGEL) $(GEN_RE2C) $(GEN_RE2C3) $(GEN_KLEENEX)
BIN_ = $(BIN_RAGEL) $(BIN_RE2C) $(BIN_KLEENEX)
BIN_GCC = $(patsubst %, %-gcc, $(BIN_))
@@ -113,7 +116,7 @@ DAT = $(patsubst %, $(DAT_DIR)/%/big, \
all-local: $(BIN) $(DAT)
# always regenerate re2c benchmarks
# always regenerate re2c benchmarks (except for deprecated algorithms)
$(GEN_RE2C_TDFA1): $(GEN_DIR)/%-tdfa1.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
@@ -125,29 +128,31 @@ $(GEN_RE2C_EOF_TDFA1): $(GEN_DIR)/%-eof-tdfa1.c: $(SRC_DIR)/%.re $(COMMON_RE2C)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS_EOF) $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RE2C_TDFA0): $(GEN_DIR)/%-tdfa0.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS) --no-lookahead $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
# optionally regenerate ragel, kleenex and re2c-3.0 benchmarks
# (TDFA(0) and staDFA algorithms were removed in re2c versions after 3.0)
$(GEN_RE2C_EOF_TDFA0): $(GEN_DIR)/%-eof-tdfa0.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS_EOF) --no-lookahead $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RE2C_STADFA): $(GEN_DIR)/%-stadfa.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS) --stadfa $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RE2C_EOF_STADFA): $(GEN_DIR)/%-eof-stadfa.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS_EOF) --stadfa $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
# optionally regenerate ragel and kleenex benchmarks
if REGEN_BENCHMARKS
$(GEN_RE2C3_TDFA0): $(GEN_DIR)/%-tdfa0.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C3)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C3) $(RE2C_FLAGS) --no-lookahead $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RE2C3_EOF_TDFA0): $(GEN_DIR)/%-eof-tdfa0.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C3)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C3) $(RE2C_FLAGS_EOF) --no-lookahead $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RE2C3_STADFA): $(GEN_DIR)/%-stadfa.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C3)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C3) $(RE2C_FLAGS) --stadfa $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RE2C3_EOF_STADFA): $(GEN_DIR)/%-eof-stadfa.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C3)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C3) $(RE2C_FLAGS_EOF) --stadfa $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RAGEL): $(GEN_DIR)/%.c: $(SRC_DIR)/%.rl $(COMMON_RAGEL) $(RAGEL)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RAGEL) -G2 $< -o $@
@@ -160,7 +165,7 @@ $(GEN_KLEENEX): $(GEN_DIR)/%.c: $(SRC_DIR)/%.kex $(KLEENEX)
else
$(GEN_RAGEL) $(GEN_KLEENEX): $(GEN_DIR)/%: $(PREGEN_DIR)/%
$(GEN_RAGEL) $(GEN_RE2C3) $(GEN_KLEENEX): $(GEN_DIR)/%: $(PREGEN_DIR)/%
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)cp -f $< $@
@@ -188,5 +193,9 @@ $(RAGEL):
$(AM_V_at)mkdir -p $(@D) && cp $(srcdir)/engines/ragel/getragel7.sh $(@D)
$(AM_V_GEN)( cd $(@D) && ./getragel7.sh )
$(RE2C3):
$(AM_V_at)mkdir -p $(@D) && cp $(srcdir)/engines/re2c/getre2c3.sh $(@D)
$(AM_V_GEN)( cd $(@D) && ./getre2c3.sh )
clean-local:
$(AM_V_at)rm -f $(GEN) $(OBJ) $(BIN) $(DAT)
@@ -1,11 +1,11 @@
set -e
set -ex
rm -rf kleenexlang
git clone --recursive https://github.com/diku-kmc/kleenexlang.git
cd kleenexlang
cabal v1-sandbox init && cabal v1-sandbox add-source regexps-syntax
cabal v1-install --dependencies-only
cabal v1-configure && cabal v1-build
mkdir "install"
cabal build
cabal install --install-method=copy --installdir="$(pwd)/install"
cd ..
rm -f kexc
ln -s kleenexlang/dist/build/kexc/kexc kexc
ln -s "kleenexlang/install/kexc" kexc
@@ -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 ..
+22
View File
@@ -0,0 +1,22 @@
set -ex
if [ -e re2c3 ] ; then
echo "re2c3 is already installed, quitting"
exit 0
fi
RE2C_DIR=re2c-3.0
wget https://github.com/skvadrik/re2c/releases/download/3.0/re2c-3.0.tar.xz \
&& tar xf re2c-3.0.tar.xz \
&& rm re2c-3.0.tar.xz \
&& cd "$RE2C_DIR" \
&& ./configure \
--disable-golang \
--disable-rust \
--prefix=$(pwd)/install \
&& make -j$(nproc) \
&& make install \
&& cd ..
ln -s "$RE2C_DIR"/install/bin/re2c re2c3
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
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
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
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
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,6 @@
/* Generated by re2c */
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#include <assert.h>
#include <stdlib.h>
#include "common.h"
@@ -24,7 +25,9 @@ typedef struct {
char *cur;
char *mar;
char *tok;
char *yyt1;
#line 30 "gen/re2c/04__apache_log-eof-tdfa1.c"
char *yyt1;
char *yyt10;
char *yyt11;
char *yyt12;
@@ -39,8 +42,12 @@ char *yyt6;
char *yyt7;
char *yyt8;
char *yyt9;
#line 34 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#line 49 "gen/re2c/04__apache_log-eof-tdfa1.c"
#line 35 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
taglistpool_t tlp;
int eof;
} input_t;
@@ -49,6 +56,9 @@ static inline void taglistpool_clear(taglistpool_t *tlp, input_t *in)
{
tlp->next = tlp->head;
#line 60 "gen/re2c/04__apache_log-eof-tdfa1.c"
#line 43 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
}
static inline void taglistpool_init(taglistpool_t *tlp)
@@ -86,6 +96,7 @@ static inline void taglist(taglist_t **ptl, const char *b, const char *t, taglis
*ptl = tl;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/include-eof/fill.re"
#line 6 "../../../benchmarks/submatch_dfa_aot/src/re2c/include-eof/fill.re"
@@ -102,7 +113,9 @@ static inline int fill(input_t *in)
in->cur -= free;
in->mar -= free;
in->tok -= free;
if (in->yyt1) in->yyt1 -= free;
#line 118 "gen/re2c/04__apache_log-eof-tdfa1.c"
if (in->yyt1) in->yyt1 -= free;
if (in->yyt10) in->yyt10 -= free;
if (in->yyt11) in->yyt11 -= free;
if (in->yyt12) in->yyt12 -= free;
@@ -117,6 +130,7 @@ if (in->yyt6) in->yyt6 -= free;
if (in->yyt7) in->yyt7 -= free;
if (in->yyt8) in->yyt8 -= free;
if (in->yyt9) in->yyt9 -= free;
#line 21 "../../../benchmarks/submatch_dfa_aot/src/re2c/include-eof/fill.re"
in->lim += fread(in->lim, 1, free, stdin);
@@ -136,7 +150,9 @@ static inline void init_input(input_t *in)
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
in->yyt1 = 0;
#line 155 "gen/re2c/04__apache_log-eof-tdfa1.c"
in->yyt1 = 0;
in->yyt10 = 0;
in->yyt11 = 0;
in->yyt12 = 0;
@@ -151,12 +167,17 @@ in->yyt6 = 0;
in->yyt7 = 0;
in->yyt8 = 0;
in->yyt9 = 0;
#line 40 "../../../benchmarks/submatch_dfa_aot/src/re2c/include-eof/fill.re"
#line 174 "gen/re2c/04__apache_log-eof-tdfa1.c"
#line 41 "../../../benchmarks/submatch_dfa_aot/src/re2c/include-eof/fill.re"
taglistpool_init(&in->tlp);
in->eof = 0;
fill(in);
}
#line 81 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
static inline void free_input(input_t *in)
@@ -190,6 +211,7 @@ int main(int argc, char **argv)
POST;
return 0;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
static int lex(input_t *in, Output *out)
@@ -201,477 +223,477 @@ static int lex(input_t *in, Output *out)
loop:
in->tok = in->cur;
#line 205 "gen/re2c/04__apache_log-eof-tdfa1.c"
#line 227 "gen/re2c/04__apache_log-eof-tdfa1.c"
{
char yych;
yyFillLabel3_0:
yyFillLabel0:
yych = *in->cur;
switch (yych) {
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt1 = in->cur;
goto yy4;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_0;
goto yy47;
}
goto yy2;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt1 = in->cur;
goto yy3;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel0;
goto yy32;
}
goto yy1;
}
yy2:
yy1:
++in->cur;
yy3:
yy2:
#line 33 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
{ return 1; }
#line 236 "gen/re2c/04__apache_log-eof-tdfa1.c"
yy4:
#line 258 "gen/re2c/04__apache_log-eof-tdfa1.c"
yy3:
in->mar = ++in->cur;
yyFillLabel3_1:
yyFillLabel1:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt2 = in->cur;
goto yy5;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy8;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_1;
}
goto yy3;
case '\t':
case ' ':
in->yyt2 = in->cur;
goto yy4;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy6;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel1;
}
goto yy2;
}
yy4:
++in->cur;
yyFillLabel2:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy4;
case '-': goto yy7;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel2;
}
goto yy5;
}
yy5:
in->cur = in->mar;
goto yy2;
yy6:
++in->cur;
yyFillLabel3_2:
yyFillLabel3:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy5;
case '-': goto yy10;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_2;
}
goto yy7;
case '\t':
case ' ':
in->yyt2 = in->cur;
goto yy4;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy6;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3;
}
goto yy5;
}
yy7:
in->cur = in->mar;
goto yy3;
yy8:
++in->cur;
yyFillLabel3_3:
yyFillLabel4:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt2 = in->cur;
goto yy5;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy8;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_3;
}
goto yy7;
case '\t':
case ' ':
in->yyt3 = in->cur;
goto yy8;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel4;
}
goto yy5;
}
yy8:
++in->cur;
yyFillLabel5:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy8;
case '-': goto yy9;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel5;
}
goto yy5;
}
yy9:
++in->cur;
yyFillLabel6:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt4 = in->cur;
goto yy10;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel6;
}
goto yy5;
}
yy10:
++in->cur;
yyFillLabel3_4:
yyFillLabel7:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt3 = in->cur;
goto yy11;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_4;
}
goto yy7;
case '\t':
case ' ': goto yy10;
case '[':
in->yyt5 = in->cur;
goto yy11;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel7;
}
goto yy5;
}
yy11:
++in->cur;
yyFillLabel3_5:
yyFillLabel8:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy11;
case '-': goto yy13;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_5;
}
goto yy7;
case 0x00:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel8;
goto yy5;
}
goto yy12;
case ']': goto yy5;
default: goto yy13;
}
yy13:
yy12:
++in->cur;
yyFillLabel3_6:
yyFillLabel9:
yych = *in->cur;
yy13:
switch (yych) {
case '\t':
case ' ':
in->yyt4 = in->cur;
goto yy14;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_6;
}
goto yy7;
case '\n': goto yy5;
case ']': goto yy14;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel9;
goto yy5;
}
goto yy12;
}
yy14:
++in->cur;
yyFillLabel3_7:
yyFillLabel10:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy14;
case '[':
in->yyt5 = in->cur;
goto yy16;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_7;
}
goto yy7;
case '\t':
case ' ':
in->yyt6 = in->cur;
goto yy15;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel10;
}
goto yy5;
}
yy15:
++in->cur;
yyFillLabel11:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy15;
case '"':
in->yyt7 = in->cur;
goto yy16;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel11;
}
goto yy5;
}
yy16:
++in->cur;
yyFillLabel3_8:
yyFillLabel12:
yych = *in->cur;
switch (yych) {
case 0x00:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_8;
goto yy7;
}
goto yy17;
case ']': goto yy7;
default: goto yy18;
case 0x00:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel12;
goto yy5;
}
goto yy17;
case '"': goto yy5;
default: goto yy18;
}
yy17:
++in->cur;
yyFillLabel3_9:
yyFillLabel13:
yych = *in->cur;
yy18:
switch (yych) {
case '\n': goto yy7;
case ']': goto yy19;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_9;
goto yy7;
}
goto yy17;
case '\n': goto yy5;
case '"': goto yy19;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel13;
goto yy5;
}
goto yy17;
}
yy19:
++in->cur;
yyFillLabel3_10:
yyFillLabel14:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt6 = in->cur;
goto yy20;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_10;
}
goto yy7;
case '\t':
case ' ':
in->yyt8 = in->cur;
goto yy20;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel14;
}
goto yy5;
}
yy20:
++in->cur;
yyFillLabel3_11:
yyFillLabel15:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy20;
case '"':
in->yyt7 = in->cur;
goto yy22;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_11;
}
goto yy7;
case '\t':
case ' ': goto yy20;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt9 = in->cur;
goto yy21;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel15;
}
goto yy5;
}
yy21:
++in->cur;
yyFillLabel16:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt10 = in->cur;
goto yy22;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy21;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel16;
}
goto yy5;
}
yy22:
++in->cur;
yyFillLabel3_12:
yyFillLabel17:
yych = *in->cur;
switch (yych) {
case 0x00:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_12;
goto yy7;
}
goto yy23;
case '"': goto yy7;
default: goto yy24;
case '\t':
case ' ': goto yy22;
case '-':
in->yyt11 = in->cur;
goto yy23;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt11 = in->cur;
goto yy24;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel17;
}
goto yy5;
}
yy23:
++in->cur;
yyFillLabel3_13:
yyFillLabel18:
yych = *in->cur;
yy24:
switch (yych) {
case '\n': goto yy7;
case '"': goto yy25;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_13;
goto yy7;
}
goto yy23;
case '\t':
case ' ':
in->yyt12 = in->cur;
goto yy25;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel18;
}
goto yy5;
}
yy24:
++in->cur;
yyFillLabel19:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt12 = in->cur;
goto yy25;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy24;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel19;
}
goto yy5;
}
yy25:
++in->cur;
yyFillLabel3_14:
yyFillLabel20:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt8 = in->cur;
goto yy26;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_14;
}
goto yy7;
case '\t':
case ' ': goto yy25;
case '"':
in->yyt13 = in->cur;
goto yy26;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel20;
}
goto yy5;
}
yy26:
++in->cur;
yyFillLabel3_15:
yyFillLabel21:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy26;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt9 = in->cur;
goto yy28;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_15;
}
goto yy7;
case '\n': goto yy5;
case '"': goto yy27;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel21;
goto yy5;
}
goto yy26;
}
yy27:
++in->cur;
yyFillLabel22:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt14 = in->cur;
goto yy28;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel22;
}
goto yy5;
}
yy28:
++in->cur;
yyFillLabel3_16:
yyFillLabel23:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt10 = in->cur;
goto yy30;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy28;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_16;
}
goto yy7;
case '\t':
case ' ': goto yy28;
case '"':
in->yyt15 = in->cur;
goto yy29;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel23;
}
goto yy5;
}
yy29:
++in->cur;
yyFillLabel24:
yych = *in->cur;
switch (yych) {
case '\n': goto yy5;
case '"': goto yy30;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel24;
goto yy5;
}
goto yy29;
}
yy30:
++in->cur;
yyFillLabel3_17:
yyFillLabel25:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy30;
case '-':
in->yyt11 = in->cur;
goto yy32;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt11 = in->cur;
goto yy33;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_17;
}
goto yy7;
case '\n': goto yy31;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel25;
}
goto yy5;
}
yy32:
++in->cur;
yyFillLabel3_18:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt12 = in->cur;
goto yy35;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_18;
}
goto yy7;
}
yy33:
++in->cur;
yyFillLabel3_19:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt12 = in->cur;
goto yy35;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy33;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_19;
}
goto yy7;
}
yy35:
++in->cur;
yyFillLabel3_20:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy35;
case '"':
in->yyt13 = in->cur;
goto yy37;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_20;
}
goto yy7;
}
yy37:
++in->cur;
yyFillLabel3_21:
yych = *in->cur;
switch (yych) {
case '\n': goto yy7;
case '"': goto yy39;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_21;
goto yy7;
}
goto yy37;
}
yy39:
++in->cur;
yyFillLabel3_22:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt14 = in->cur;
goto yy40;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_22;
}
goto yy7;
}
yy40:
++in->cur;
yyFillLabel3_23:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy40;
case '"':
in->yyt15 = in->cur;
goto yy42;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_23;
}
goto yy7;
}
yy42:
++in->cur;
yyFillLabel3_24:
yych = *in->cur;
switch (yych) {
case '\n': goto yy7;
case '"': goto yy44;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_24;
goto yy7;
}
goto yy42;
}
yy44:
++in->cur;
yyFillLabel3_25:
yych = *in->cur;
switch (yych) {
case '\n': goto yy45;
default:
if (in->lim <= in->cur) {
if (fill(in) == 0) goto yyFillLabel3_25;
}
goto yy7;
}
yy45:
yy31:
++in->cur;
h1 = in->yyt1;
h2 = in->yyt2;
@@ -705,11 +727,11 @@ yy45:
outc(out, '\n');
goto loop;
}
#line 709 "gen/re2c/04__apache_log-eof-tdfa1.c"
yy47:
#line 731 "gen/re2c/04__apache_log-eof-tdfa1.c"
yy32:
#line 5 "../../../benchmarks/submatch_dfa_aot/src/re2c/include-eof/fill.re"
{ return 0; }
#line 713 "gen/re2c/04__apache_log-eof-tdfa1.c"
#line 735 "gen/re2c/04__apache_log-eof-tdfa1.c"
}
#line 47 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
@@ -1,5 +1,6 @@
/* Generated by re2c */
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#include <assert.h>
#include <stdlib.h>
#include "common.h"
@@ -24,7 +25,9 @@ typedef struct {
char *cur;
char *mar;
char *tok;
char *yyt1;
#line 30 "gen/re2c/04__apache_log-stadfa.c"
char *yyt1;
char *yyt10;
char *yyt11;
char *yyt12;
@@ -39,8 +42,12 @@ char *yyt6;
char *yyt7;
char *yyt8;
char *yyt9;
#line 34 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#line 49 "gen/re2c/04__apache_log-stadfa.c"
#line 35 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
taglistpool_t tlp;
int eof;
} input_t;
@@ -49,6 +56,9 @@ static inline void taglistpool_clear(taglistpool_t *tlp, input_t *in)
{
tlp->next = tlp->head;
#line 60 "gen/re2c/04__apache_log-stadfa.c"
#line 43 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
}
static inline void taglistpool_init(taglistpool_t *tlp)
@@ -86,10 +96,13 @@ static inline void taglist(taglist_t **ptl, const char *b, const char *t, taglis
*ptl = tl;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 4 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 104 "gen/re2c/04__apache_log-stadfa.c"
#define YYMAXFILL 12
#line 6 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
static inline int fill(input_t *in, size_t need)
@@ -105,7 +118,9 @@ static inline int fill(input_t *in, size_t need)
in->cur -= free;
in->mar -= free;
in->tok -= free;
if (in->yyt1) in->yyt1 -= free;
#line 123 "gen/re2c/04__apache_log-stadfa.c"
if (in->yyt1) in->yyt1 -= free;
if (in->yyt10) in->yyt10 -= free;
if (in->yyt11) in->yyt11 -= free;
if (in->yyt12) in->yyt12 -= free;
@@ -120,6 +135,7 @@ if (in->yyt6) in->yyt6 -= free;
if (in->yyt7) in->yyt7 -= free;
if (in->yyt8) in->yyt8 -= free;
if (in->yyt9) in->yyt9 -= free;
#line 21 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
in->lim += fread(in->lim, 1, free, stdin);
@@ -140,7 +156,9 @@ static inline void init_input(input_t *in)
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
in->yyt1 = 0;
#line 161 "gen/re2c/04__apache_log-stadfa.c"
in->yyt1 = 0;
in->yyt10 = 0;
in->yyt11 = 0;
in->yyt12 = 0;
@@ -155,11 +173,16 @@ in->yyt6 = 0;
in->yyt7 = 0;
in->yyt8 = 0;
in->yyt9 = 0;
#line 41 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 180 "gen/re2c/04__apache_log-stadfa.c"
#line 42 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
taglistpool_init(&in->tlp);
in->eof = 0;
}
#line 81 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
static inline void free_input(input_t *in)
@@ -193,6 +216,7 @@ int main(int argc, char **argv)
POST;
return 0;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
static int lex(input_t *in, Output *out)
@@ -204,461 +228,461 @@ static int lex(input_t *in, Output *out)
loop:
in->tok = in->cur;
#line 208 "gen/re2c/04__apache_log-stadfa.c"
#line 232 "gen/re2c/04__apache_log-stadfa.c"
{
char yych;
if ((in->lim - in->cur) < 8) if (fill(in, 8) != 0) return 1;
yych = *in->cur;
switch (yych) {
case 0x00: goto yy2;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy6;
default: goto yy4;
case 0x00: goto yy1;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy4;
default: goto yy2;
}
yy2:
yy1:
++in->cur;
#line 3 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
{ return 0; }
#line 232 "gen/re2c/04__apache_log-stadfa.c"
yy4:
#line 256 "gen/re2c/04__apache_log-stadfa.c"
yy2:
++in->cur;
yy5:
yy3:
#line 33 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
{ return 1; }
#line 238 "gen/re2c/04__apache_log-stadfa.c"
yy6:
#line 262 "gen/re2c/04__apache_log-stadfa.c"
yy4:
yych = *(in->mar = ++in->cur);
in->yyt1 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy7;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy9;
default: goto yy5;
case '\t':
case ' ': goto yy5;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy7;
default: goto yy3;
}
yy7:
yy5:
yych = *++in->cur;
in->yyt2 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy11;
case '-': goto yy13;
default: goto yy8;
case '\t':
case ' ': goto yy8;
case '-': goto yy9;
default: goto yy6;
}
yy8:
yy6:
in->cur = in->mar;
goto yy5;
yy9:
goto yy3;
yy7:
++in->cur;
if ((in->lim - in->cur) < 7) if (fill(in, 7) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy7;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy9;
default: goto yy8;
case '\t':
case ' ': goto yy5;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy7;
default: goto yy6;
}
yy11:
yy8:
++in->cur;
if ((in->lim - in->cur) < 6) if (fill(in, 6) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy11;
case '-': goto yy13;
default: goto yy8;
case '\t':
case ' ': goto yy8;
case '-': goto yy9;
default: goto yy6;
}
yy13:
yy9:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ': goto yy14;
default: goto yy8;
case '\t':
case ' ': goto yy10;
default: goto yy6;
}
yy14:
yy10:
yych = *++in->cur;
in->yyt3 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy15;
case '-': goto yy17;
default: goto yy8;
case '\t':
case ' ': goto yy11;
case '-': goto yy12;
default: goto yy6;
}
yy15:
yy11:
++in->cur;
if ((in->lim - in->cur) < 4) if (fill(in, 4) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy15;
case '-': goto yy17;
default: goto yy8;
case '\t':
case ' ': goto yy11;
case '-': goto yy12;
default: goto yy6;
}
yy12:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ': goto yy13;
default: goto yy6;
}
yy13:
yych = *++in->cur;
in->yyt4 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy14;
case '[': goto yy15;
default: goto yy6;
}
yy14:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy14;
case '[': goto yy15;
default: goto yy6;
}
yy15:
yych = *++in->cur;
in->yyt5 = in->cur - 1;
switch (yych) {
case '\n':
case ']': goto yy6;
default: goto yy16;
}
yy16:
++in->cur;
if ((in->lim - in->cur) < 4) if (fill(in, 4) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n': goto yy6;
case ']': goto yy17;
default: goto yy16;
}
yy17:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ': goto yy18;
default: goto yy8;
case '\t':
case ' ': goto yy18;
default: goto yy6;
}
yy18:
yych = *++in->cur;
in->yyt4 = in->cur - 1;
in->yyt6 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy19;
case '[': goto yy21;
default: goto yy8;
case '\t':
case ' ': goto yy19;
case '"': goto yy20;
default: goto yy6;
}
yy19:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy19;
case '[': goto yy21;
default: goto yy8;
case '\t':
case ' ': goto yy19;
case '"': goto yy20;
default: goto yy6;
}
yy21:
yych = *++in->cur;
in->yyt5 = in->cur - 1;
switch (yych) {
case '\n':
case ']': goto yy8;
default: goto yy22;
}
yy22:
++in->cur;
if ((in->lim - in->cur) < 4) if (fill(in, 4) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n': goto yy8;
case ']': goto yy24;
default: goto yy22;
}
yy24:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ': goto yy25;
default: goto yy8;
}
yy25:
yych = *++in->cur;
in->yyt6 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy26;
case '"': goto yy28;
default: goto yy8;
}
yy26:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy26;
case '"': goto yy28;
default: goto yy8;
}
yy28:
yy20:
yych = *++in->cur;
in->yyt7 = in->cur - 1;
switch (yych) {
case '\n':
case '"': goto yy8;
default: goto yy29;
case '\n':
case '"': goto yy6;
default: goto yy21;
}
yy29:
yy21:
++in->cur;
if ((in->lim - in->cur) < 12) if (fill(in, 12) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n': goto yy8;
case '"': goto yy31;
default: goto yy29;
case '\n': goto yy6;
case '"': goto yy22;
default: goto yy21;
}
yy31:
yy22:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ': goto yy32;
default: goto yy8;
case '\t':
case ' ': goto yy23;
default: goto yy6;
}
yy32:
yy23:
yych = *++in->cur;
in->yyt8 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy33;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy35;
default: goto yy8;
case '\t':
case ' ': goto yy24;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy25;
default: goto yy6;
}
yy33:
yy24:
++in->cur;
if ((in->lim - in->cur) < 10) if (fill(in, 10) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy33;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy35;
default: goto yy8;
case '\t':
case ' ': goto yy24;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy25;
default: goto yy6;
}
yy35:
yy25:
yych = *++in->cur;
in->yyt9 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy36;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy37;
default: goto yy8;
case '\t':
case ' ': goto yy26;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy27;
default: goto yy6;
}
yy36:
yy26:
yych = *++in->cur;
in->yyt10 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy39;
case '-': goto yy41;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy42;
default: goto yy8;
case '\t':
case ' ': goto yy28;
case '-': goto yy29;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy30;
default: goto yy6;
}
yy37:
yy27:
++in->cur;
if ((in->lim - in->cur) < 9) if (fill(in, 9) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy36;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy37;
default: goto yy8;
case '\t':
case ' ': goto yy26;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy27;
default: goto yy6;
}
yy39:
yy28:
++in->cur;
if ((in->lim - in->cur) < 8) if (fill(in, 8) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy39;
case '-': goto yy41;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy42;
default: goto yy8;
case '\t':
case ' ': goto yy28;
case '-': goto yy29;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy30;
default: goto yy6;
}
yy41:
yy29:
yych = *++in->cur;
in->yyt11 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy43;
default: goto yy8;
case '\t':
case ' ': goto yy31;
default: goto yy6;
}
yy42:
yy30:
yych = *++in->cur;
in->yyt11 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy43;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy44;
default: goto yy8;
case '\t':
case ' ': goto yy31;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy32;
default: goto yy6;
}
yy43:
yy31:
yych = *++in->cur;
in->yyt12 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy46;
case '"': goto yy48;
default: goto yy8;
case '\t':
case ' ': goto yy33;
case '"': goto yy34;
default: goto yy6;
}
yy44:
yy32:
++in->cur;
if ((in->lim - in->cur) < 7) if (fill(in, 7) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy43;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy44;
default: goto yy8;
case '\t':
case ' ': goto yy31;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy32;
default: goto yy6;
}
yy46:
yy33:
++in->cur;
if ((in->lim - in->cur) < 6) if (fill(in, 6) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy46;
case '"': goto yy48;
default: goto yy8;
case '\t':
case ' ': goto yy33;
case '"': goto yy34;
default: goto yy6;
}
yy48:
yy34:
yych = *++in->cur;
in->yyt13 = in->cur - 1;
switch (yych) {
case '\n': goto yy8;
case '"': goto yy51;
default: goto yy49;
case '\n': goto yy6;
case '"': goto yy36;
default: goto yy35;
}
yy49:
yy35:
++in->cur;
if ((in->lim - in->cur) < 5) if (fill(in, 5) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n': goto yy8;
case '"': goto yy51;
default: goto yy49;
case '\n': goto yy6;
case '"': goto yy36;
default: goto yy35;
}
yy51:
yy36:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ': goto yy52;
default: goto yy8;
case '\t':
case ' ': goto yy37;
default: goto yy6;
}
yy52:
yy37:
yych = *++in->cur;
in->yyt14 = in->cur - 1;
switch (yych) {
case '\t':
case ' ': goto yy53;
case '"': goto yy55;
default: goto yy8;
case '\t':
case ' ': goto yy38;
case '"': goto yy39;
default: goto yy6;
}
yy53:
yy38:
++in->cur;
if ((in->lim - in->cur) < 3) if (fill(in, 3) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy53;
case '"': goto yy55;
default: goto yy8;
case '\t':
case ' ': goto yy38;
case '"': goto yy39;
default: goto yy6;
}
yy55:
yy39:
yych = *++in->cur;
in->yyt15 = in->cur - 1;
switch (yych) {
case '\n': goto yy8;
case '"': goto yy58;
default: goto yy56;
case '\n': goto yy6;
case '"': goto yy41;
default: goto yy40;
}
yy56:
yy40:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n': goto yy8;
case '"': goto yy58;
default: goto yy56;
case '\n': goto yy6;
case '"': goto yy41;
default: goto yy40;
}
yy58:
yy41:
yych = *++in->cur;
switch (yych) {
case '\n': goto yy59;
default: goto yy8;
case '\n': goto yy42;
default: goto yy6;
}
yy59:
yy42:
++in->cur;
h1 = in->yyt1;
h2 = in->yyt2;
@@ -692,7 +716,7 @@ yy59:
outc(out, '\n');
goto loop;
}
#line 696 "gen/re2c/04__apache_log-stadfa.c"
#line 720 "gen/re2c/04__apache_log-stadfa.c"
}
#line 47 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
@@ -1,5 +1,6 @@
/* Generated by re2c */
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#include <assert.h>
#include <stdlib.h>
#include "common.h"
@@ -24,7 +25,9 @@ typedef struct {
char *cur;
char *mar;
char *tok;
char *yyt1;
#line 30 "gen/re2c/04__apache_log-tdfa0.c"
char *yyt1;
char *yyt10;
char *yyt11;
char *yyt12;
@@ -39,8 +42,12 @@ char *yyt6;
char *yyt7;
char *yyt8;
char *yyt9;
#line 34 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#line 49 "gen/re2c/04__apache_log-tdfa0.c"
#line 35 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
taglistpool_t tlp;
int eof;
} input_t;
@@ -49,6 +56,9 @@ static inline void taglistpool_clear(taglistpool_t *tlp, input_t *in)
{
tlp->next = tlp->head;
#line 60 "gen/re2c/04__apache_log-tdfa0.c"
#line 43 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
}
static inline void taglistpool_init(taglistpool_t *tlp)
@@ -86,10 +96,13 @@ static inline void taglist(taglist_t **ptl, const char *b, const char *t, taglis
*ptl = tl;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 4 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 104 "gen/re2c/04__apache_log-tdfa0.c"
#define YYMAXFILL 2
#line 6 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
static inline int fill(input_t *in, size_t need)
@@ -105,7 +118,9 @@ static inline int fill(input_t *in, size_t need)
in->cur -= free;
in->mar -= free;
in->tok -= free;
if (in->yyt1) in->yyt1 -= free;
#line 123 "gen/re2c/04__apache_log-tdfa0.c"
if (in->yyt1) in->yyt1 -= free;
if (in->yyt10) in->yyt10 -= free;
if (in->yyt11) in->yyt11 -= free;
if (in->yyt12) in->yyt12 -= free;
@@ -120,6 +135,7 @@ if (in->yyt6) in->yyt6 -= free;
if (in->yyt7) in->yyt7 -= free;
if (in->yyt8) in->yyt8 -= free;
if (in->yyt9) in->yyt9 -= free;
#line 21 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
in->lim += fread(in->lim, 1, free, stdin);
@@ -140,7 +156,9 @@ static inline void init_input(input_t *in)
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
in->yyt1 = 0;
#line 161 "gen/re2c/04__apache_log-tdfa0.c"
in->yyt1 = 0;
in->yyt10 = 0;
in->yyt11 = 0;
in->yyt12 = 0;
@@ -155,11 +173,16 @@ in->yyt6 = 0;
in->yyt7 = 0;
in->yyt8 = 0;
in->yyt9 = 0;
#line 41 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 180 "gen/re2c/04__apache_log-tdfa0.c"
#line 42 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
taglistpool_init(&in->tlp);
in->eof = 0;
}
#line 81 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
static inline void free_input(input_t *in)
@@ -193,6 +216,7 @@ int main(int argc, char **argv)
POST;
return 0;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
static int lex(input_t *in, Output *out)
@@ -204,397 +228,397 @@ static int lex(input_t *in, Output *out)
loop:
in->tok = in->cur;
#line 208 "gen/re2c/04__apache_log-tdfa0.c"
#line 232 "gen/re2c/04__apache_log-tdfa0.c"
{
char yych;
in->yyt1 = in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur++;
switch (yych) {
case 0x00: goto yy2;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt15 = in->cur;
goto yy6;
default: goto yy4;
case 0x00: goto yy1;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt15 = in->cur;
goto yy4;
default: goto yy2;
}
yy2:
yy1:
#line 3 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
{ return 0; }
#line 234 "gen/re2c/04__apache_log-tdfa0.c"
yy4:
yy5:
#line 258 "gen/re2c/04__apache_log-tdfa0.c"
yy2:
yy3:
#line 33 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
{ return 1; }
#line 239 "gen/re2c/04__apache_log-tdfa0.c"
yy6:
#line 263 "gen/re2c/04__apache_log-tdfa0.c"
yy4:
yych = *(in->mar = in->cur);
switch (yych) {
case '\t':
case ' ':
++in->cur;
goto yy7;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt15 = in->cur;
goto yy10;
default: goto yy5;
case '\t':
case ' ':
++in->cur;
goto yy5;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt15 = in->cur;
goto yy7;
default: goto yy3;
}
yy7:
yy5:
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
++in->cur;
goto yy7;
case '-':
++in->cur;
in->yyt2 = in->cur;
goto yy12;
default: goto yy9;
case '\t':
case ' ':
++in->cur;
goto yy5;
case '-':
++in->cur;
in->yyt2 = in->cur;
goto yy8;
default: goto yy6;
}
yy6:
in->cur = in->mar;
goto yy3;
yy7:
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
++in->cur;
goto yy5;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt15 = in->cur;
goto yy7;
default: goto yy6;
}
yy8:
yych = *in->cur;
switch (yych) {
case '-': goto yy6;
default: goto yy10;
}
yy9:
in->cur = in->mar;
goto yy5;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
yy10:
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
switch (yych) {
case '\t':
case ' ':
++in->cur;
goto yy9;
case '-':
++in->cur;
in->yyt3 = in->cur;
goto yy11;
default: goto yy6;
}
yy11:
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
++in->cur;
goto yy7;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt15 = in->cur;
goto yy10;
default: goto yy9;
case '[': goto yy6;
default: goto yy13;
}
yy12:
yych = *in->cur;
switch (yych) {
case '-': goto yy9;
default: goto yy14;
}
yy13:
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
yy14:
yy13:
switch (yych) {
case '\t':
case ' ':
++in->cur;
goto yy13;
case '-':
++in->cur;
in->yyt3 = in->cur;
goto yy15;
default: goto yy9;
case '\t':
case ' ':
++in->cur;
in->yyt4 = in->cur;
goto yy12;
case '[':
++in->cur;
goto yy14;
default: goto yy6;
}
yy14:
yych = *in->cur;
switch (yych) {
case ']': goto yy6;
default: goto yy16;
}
yy15:
yych = *in->cur;
switch (yych) {
case '[': goto yy9;
default: goto yy17;
}
yy16:
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
yy17:
yy16:
switch (yych) {
case '\t':
case ' ':
++in->cur;
in->yyt4 = in->cur;
goto yy16;
case '[':
++in->cur;
goto yy18;
default: goto yy9;
case '\n': goto yy6;
case ']':
++in->cur;
in->yyt5 = in->cur;
goto yy17;
default:
++in->cur;
goto yy15;
}
yy17:
yych = *in->cur;
switch (yych) {
case '"': goto yy6;
default: goto yy19;
}
yy18:
yych = *in->cur;
switch (yych) {
case ']': goto yy9;
default: goto yy20;
}
yy19:
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
yy20:
yy19:
switch (yych) {
case '\n': goto yy9;
case ']':
++in->cur;
in->yyt5 = in->cur;
goto yy21;
default:
++in->cur;
goto yy19;
case '\t':
case ' ':
++in->cur;
in->yyt6 = in->cur;
goto yy18;
case '"':
++in->cur;
goto yy20;
default: goto yy6;
}
yy20:
yych = *in->cur;
switch (yych) {
case '"': goto yy6;
default: goto yy22;
}
yy21:
yych = *in->cur;
switch (yych) {
case '"': goto yy9;
default: goto yy23;
}
yy22:
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
yy23:
yy22:
switch (yych) {
case '\t':
case ' ':
++in->cur;
in->yyt6 = in->cur;
goto yy22;
case '"':
++in->cur;
goto yy24;
default: goto yy9;
case '\n': goto yy6;
case '"':
++in->cur;
in->yyt7 = in->cur;
goto yy23;
default:
++in->cur;
goto yy21;
}
yy23:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy6;
default: goto yy25;
}
yy24:
yych = *in->cur;
switch (yych) {
case '"': goto yy9;
default: goto yy26;
}
yy25:
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
yy26:
switch (yych) {
case '\n': goto yy9;
case '"':
++in->cur;
in->yyt7 = in->cur;
goto yy27;
default:
++in->cur;
goto yy25;
}
yy27:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy9;
default: goto yy29;
}
yy28:
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
yy29:
yy25:
switch (yych) {
case '\t':
case ' ':
++in->cur;
in->yyt8 = in->cur;
goto yy28;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt9 = in->cur;
goto yy30;
default: goto yy9;
case '\t':
case ' ':
++in->cur;
in->yyt8 = in->cur;
goto yy24;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt9 = in->cur;
goto yy26;
default: goto yy6;
}
yy26:
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
++in->cur;
in->yyt10 = in->cur;
goto yy27;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt9 = in->cur;
goto yy26;
default: goto yy6;
}
yy27:
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
++in->cur;
in->yyt10 = in->cur;
goto yy27;
case '-':
++in->cur;
in->yyt11 = in->cur;
goto yy28;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt11 = in->cur;
goto yy29;
default: goto yy6;
}
yy28:
yych = *in->cur;
switch (yych) {
case '"': goto yy6;
default: goto yy31;
}
yy29:
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
++in->cur;
in->yyt12 = in->cur;
goto yy30;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt11 = in->cur;
goto yy29;
default: goto yy6;
}
yy30:
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
yy31:
switch (yych) {
case '\t':
case ' ':
++in->cur;
in->yyt10 = in->cur;
goto yy32;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt9 = in->cur;
goto yy30;
default: goto yy9;
case '\t':
case ' ':
++in->cur;
in->yyt12 = in->cur;
goto yy30;
case '"':
++in->cur;
goto yy32;
default: goto yy6;
}
yy32:
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
++in->cur;
in->yyt10 = in->cur;
goto yy32;
case '-':
++in->cur;
in->yyt11 = in->cur;
goto yy34;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt11 = in->cur;
goto yy35;
default: goto yy9;
case '\n': goto yy6;
case '"':
++in->cur;
in->yyt13 = in->cur;
goto yy33;
default:
++in->cur;
goto yy32;
}
yy33:
yych = *in->cur;
switch (yych) {
case '"': goto yy6;
default: goto yy35;
}
yy34:
yych = *in->cur;
switch (yych) {
case '"': goto yy9;
default: goto yy38;
}
yy35:
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
yy35:
switch (yych) {
case '\t':
case ' ':
++in->cur;
in->yyt12 = in->cur;
goto yy37;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt11 = in->cur;
goto yy35;
default: goto yy9;
case '\t':
case ' ':
++in->cur;
in->yyt14 = in->cur;
goto yy34;
case '"':
++in->cur;
goto yy36;
default: goto yy6;
}
yy36:
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n': goto yy6;
case '"':
++in->cur;
goto yy37;
default:
++in->cur;
goto yy36;
}
yy37:
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n':
++in->cur;
goto yy38;
default: goto yy6;
}
yy38:
switch (yych) {
case '\t':
case ' ':
++in->cur;
in->yyt12 = in->cur;
goto yy37;
case '"':
++in->cur;
goto yy39;
default: goto yy9;
}
yy39:
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n': goto yy9;
case '"':
++in->cur;
in->yyt13 = in->cur;
goto yy41;
default:
++in->cur;
goto yy39;
}
yy41:
yych = *in->cur;
switch (yych) {
case '"': goto yy9;
default: goto yy43;
}
yy42:
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
yy43:
switch (yych) {
case '\t':
case ' ':
++in->cur;
in->yyt14 = in->cur;
goto yy42;
case '"':
++in->cur;
goto yy44;
default: goto yy9;
}
yy44:
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n': goto yy9;
case '"':
++in->cur;
goto yy46;
default:
++in->cur;
goto yy44;
}
yy46:
yych = *in->cur;
switch (yych) {
case '\n':
++in->cur;
goto yy47;
default: goto yy9;
}
yy47:
h1 = in->yyt1;
h2 = in->yyt15;
i2 = in->yyt2;
@@ -627,7 +651,7 @@ yy47:
outc(out, '\n');
goto loop;
}
#line 631 "gen/re2c/04__apache_log-tdfa0.c"
#line 655 "gen/re2c/04__apache_log-tdfa0.c"
}
#line 47 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
@@ -1,5 +1,6 @@
/* Generated by re2c */
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#include <assert.h>
#include <stdlib.h>
#include "common.h"
@@ -24,7 +25,9 @@ typedef struct {
char *cur;
char *mar;
char *tok;
char *yyt1;
#line 30 "gen/re2c/04__apache_log-tdfa1.c"
char *yyt1;
char *yyt10;
char *yyt11;
char *yyt12;
@@ -39,8 +42,12 @@ char *yyt6;
char *yyt7;
char *yyt8;
char *yyt9;
#line 34 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#line 49 "gen/re2c/04__apache_log-tdfa1.c"
#line 35 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
taglistpool_t tlp;
int eof;
} input_t;
@@ -49,6 +56,9 @@ static inline void taglistpool_clear(taglistpool_t *tlp, input_t *in)
{
tlp->next = tlp->head;
#line 60 "gen/re2c/04__apache_log-tdfa1.c"
#line 43 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
}
static inline void taglistpool_init(taglistpool_t *tlp)
@@ -86,10 +96,13 @@ static inline void taglist(taglist_t **ptl, const char *b, const char *t, taglis
*ptl = tl;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 4 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 104 "gen/re2c/04__apache_log-tdfa1.c"
#define YYMAXFILL 2
#line 6 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
static inline int fill(input_t *in, size_t need)
@@ -105,7 +118,9 @@ static inline int fill(input_t *in, size_t need)
in->cur -= free;
in->mar -= free;
in->tok -= free;
if (in->yyt1) in->yyt1 -= free;
#line 123 "gen/re2c/04__apache_log-tdfa1.c"
if (in->yyt1) in->yyt1 -= free;
if (in->yyt10) in->yyt10 -= free;
if (in->yyt11) in->yyt11 -= free;
if (in->yyt12) in->yyt12 -= free;
@@ -120,6 +135,7 @@ if (in->yyt6) in->yyt6 -= free;
if (in->yyt7) in->yyt7 -= free;
if (in->yyt8) in->yyt8 -= free;
if (in->yyt9) in->yyt9 -= free;
#line 21 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
in->lim += fread(in->lim, 1, free, stdin);
@@ -140,7 +156,9 @@ static inline void init_input(input_t *in)
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
in->yyt1 = 0;
#line 161 "gen/re2c/04__apache_log-tdfa1.c"
in->yyt1 = 0;
in->yyt10 = 0;
in->yyt11 = 0;
in->yyt12 = 0;
@@ -155,11 +173,16 @@ in->yyt6 = 0;
in->yyt7 = 0;
in->yyt8 = 0;
in->yyt9 = 0;
#line 41 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 180 "gen/re2c/04__apache_log-tdfa1.c"
#line 42 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
taglistpool_init(&in->tlp);
in->eof = 0;
}
#line 81 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
static inline void free_input(input_t *in)
@@ -193,6 +216,7 @@ int main(int argc, char **argv)
POST;
return 0;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
static int lex(input_t *in, Output *out)
@@ -204,350 +228,350 @@ static int lex(input_t *in, Output *out)
loop:
in->tok = in->cur;
#line 208 "gen/re2c/04__apache_log-tdfa1.c"
#line 232 "gen/re2c/04__apache_log-tdfa1.c"
{
char yych;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case 0x00: goto yy2;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt1 = in->cur;
goto yy6;
default: goto yy4;
case 0x00: goto yy1;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt1 = in->cur;
goto yy4;
default: goto yy2;
}
yy2:
yy1:
++in->cur;
#line 3 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
{ return 0; }
#line 234 "gen/re2c/04__apache_log-tdfa1.c"
yy4:
#line 258 "gen/re2c/04__apache_log-tdfa1.c"
yy2:
++in->cur;
yy5:
yy3:
#line 33 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
{ return 1; }
#line 240 "gen/re2c/04__apache_log-tdfa1.c"
yy6:
#line 264 "gen/re2c/04__apache_log-tdfa1.c"
yy4:
yych = *(in->mar = ++in->cur);
switch (yych) {
case '\t':
case ' ':
in->yyt2 = in->cur;
goto yy7;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy10;
default: goto yy5;
case '\t':
case ' ':
in->yyt2 = in->cur;
goto yy5;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy7;
default: goto yy3;
}
yy7:
yy5:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy7;
case '-': goto yy12;
default: goto yy9;
case '\t':
case ' ': goto yy5;
case '-': goto yy8;
default: goto yy6;
}
yy9:
yy6:
in->cur = in->mar;
goto yy5;
yy10:
goto yy3;
yy7:
++in->cur;
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt2 = in->cur;
goto yy7;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy10;
default: goto yy9;
case '\t':
case ' ':
in->yyt2 = in->cur;
goto yy5;
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy7;
default: goto yy6;
}
yy8:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt3 = in->cur;
goto yy9;
default: goto yy6;
}
yy9:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy9;
case '-': goto yy10;
default: goto yy6;
}
yy10:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt4 = in->cur;
goto yy11;
default: goto yy6;
}
yy11:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy11;
case '[':
in->yyt5 = in->cur;
goto yy12;
default: goto yy6;
}
yy12:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt3 = in->cur;
goto yy13;
default: goto yy9;
case ']': goto yy6;
default: goto yy14;
}
yy13:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
yy14:
switch (yych) {
case '\t':
case ' ': goto yy13;
case '-': goto yy15;
default: goto yy9;
case '\n': goto yy6;
case ']': goto yy15;
default: goto yy13;
}
yy15:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt4 = in->cur;
goto yy16;
default: goto yy9;
case '\t':
case ' ':
in->yyt6 = in->cur;
goto yy16;
default: goto yy6;
}
yy16:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy16;
case '[':
in->yyt5 = in->cur;
goto yy18;
default: goto yy9;
case '\t':
case ' ': goto yy16;
case '"':
in->yyt7 = in->cur;
goto yy17;
default: goto yy6;
}
yy18:
yy17:
yych = *++in->cur;
switch (yych) {
case ']': goto yy9;
default: goto yy20;
case '"': goto yy6;
default: goto yy19;
}
yy19:
yy18:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
yy20:
yy19:
switch (yych) {
case '\n': goto yy9;
case ']': goto yy21;
default: goto yy19;
case '\n': goto yy6;
case '"': goto yy20;
default: goto yy18;
}
yy21:
yy20:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt6 = in->cur;
goto yy22;
default: goto yy9;
case '\t':
case ' ':
in->yyt8 = in->cur;
goto yy21;
default: goto yy6;
}
yy21:
++in->cur;
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy21;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt9 = in->cur;
goto yy22;
default: goto yy6;
}
yy22:
++in->cur;
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt10 = in->cur;
goto yy23;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy22;
default: goto yy6;
}
yy23:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy22;
case '"':
in->yyt7 = in->cur;
goto yy24;
default: goto yy9;
case '\t':
case ' ': goto yy23;
case '-':
in->yyt11 = in->cur;
goto yy24;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt11 = in->cur;
goto yy25;
default: goto yy6;
}
yy24:
yych = *++in->cur;
switch (yych) {
case '"': goto yy9;
default: goto yy26;
case '\t':
case ' ':
in->yyt12 = in->cur;
goto yy26;
default: goto yy6;
}
yy25:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt12 = in->cur;
goto yy26;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy25;
default: goto yy6;
}
yy26:
switch (yych) {
case '\n': goto yy9;
case '"': goto yy27;
default: goto yy25;
}
yy27:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt8 = in->cur;
goto yy28;
default: goto yy9;
}
yy28:
++in->cur;
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy28;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt9 = in->cur;
goto yy30;
default: goto yy9;
case '\t':
case ' ': goto yy26;
case '"':
in->yyt13 = in->cur;
goto yy27;
default: goto yy6;
}
yy27:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n': goto yy6;
case '"': goto yy28;
default: goto yy27;
}
yy28:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt14 = in->cur;
goto yy29;
default: goto yy6;
}
yy29:
++in->cur;
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy29;
case '"':
in->yyt15 = in->cur;
goto yy30;
default: goto yy6;
}
yy30:
++in->cur;
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt10 = in->cur;
goto yy32;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy30;
default: goto yy9;
case '\n': goto yy6;
case '"': goto yy31;
default: goto yy30;
}
yy31:
yych = *++in->cur;
switch (yych) {
case '\n': goto yy32;
default: goto yy6;
}
yy32:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy32;
case '-':
in->yyt11 = in->cur;
goto yy34;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt11 = in->cur;
goto yy35;
default: goto yy9;
}
yy34:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt12 = in->cur;
goto yy37;
default: goto yy9;
}
yy35:
++in->cur;
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt12 = in->cur;
goto yy37;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy35;
default: goto yy9;
}
yy37:
++in->cur;
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy37;
case '"':
in->yyt13 = in->cur;
goto yy39;
default: goto yy9;
}
yy39:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n': goto yy9;
case '"': goto yy41;
default: goto yy39;
}
yy41:
yych = *++in->cur;
switch (yych) {
case '\t':
case ' ':
in->yyt14 = in->cur;
goto yy42;
default: goto yy9;
}
yy42:
++in->cur;
if (in->lim <= in->cur) if (fill(in, 1) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\t':
case ' ': goto yy42;
case '"':
in->yyt15 = in->cur;
goto yy44;
default: goto yy9;
}
yy44:
++in->cur;
if ((in->lim - in->cur) < 2) if (fill(in, 2) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '\n': goto yy9;
case '"': goto yy46;
default: goto yy44;
}
yy46:
yych = *++in->cur;
switch (yych) {
case '\n': goto yy47;
default: goto yy9;
}
yy47:
++in->cur;
h1 = in->yyt1;
h2 = in->yyt2;
@@ -581,7 +605,7 @@ yy47:
outc(out, '\n');
goto loop;
}
#line 585 "gen/re2c/04__apache_log-tdfa1.c"
#line 609 "gen/re2c/04__apache_log-tdfa1.c"
}
#line 47 "../../../benchmarks/submatch_dfa_aot/src/re2c/04__apache_log.re"
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
@@ -1,5 +1,6 @@
/* Generated by re2c */
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#include <assert.h>
#include <stdlib.h>
#include "common.h"
@@ -24,12 +25,18 @@ typedef struct {
char *cur;
char *mar;
char *tok;
char *yyt1;
#line 30 "gen/re2c/05__datetime-stadfa.c"
char *yyt1;
char *yyt2;
char *yyt3;
char *yyt4;
#line 34 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#line 38 "gen/re2c/05__datetime-stadfa.c"
#line 35 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
taglistpool_t tlp;
int eof;
} input_t;
@@ -38,6 +45,9 @@ static inline void taglistpool_clear(taglistpool_t *tlp, input_t *in)
{
tlp->next = tlp->head;
#line 49 "gen/re2c/05__datetime-stadfa.c"
#line 43 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
}
static inline void taglistpool_init(taglistpool_t *tlp)
@@ -75,10 +85,13 @@ static inline void taglist(taglist_t **ptl, const char *b, const char *t, taglis
*ptl = tl;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 4 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 93 "gen/re2c/05__datetime-stadfa.c"
#define YYMAXFILL 26
#line 6 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
static inline int fill(input_t *in, size_t need)
@@ -94,10 +107,13 @@ static inline int fill(input_t *in, size_t need)
in->cur -= free;
in->mar -= free;
in->tok -= free;
if (in->yyt1) in->yyt1 -= free;
#line 112 "gen/re2c/05__datetime-stadfa.c"
if (in->yyt1) in->yyt1 -= free;
if (in->yyt2) in->yyt2 -= free;
if (in->yyt3) in->yyt3 -= free;
if (in->yyt4) in->yyt4 -= free;
#line 21 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
in->lim += fread(in->lim, 1, free, stdin);
@@ -118,15 +134,22 @@ static inline void init_input(input_t *in)
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
in->yyt1 = 0;
#line 139 "gen/re2c/05__datetime-stadfa.c"
in->yyt1 = 0;
in->yyt2 = 0;
in->yyt3 = 0;
in->yyt4 = 0;
#line 41 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 147 "gen/re2c/05__datetime-stadfa.c"
#line 42 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
taglistpool_init(&in->tlp);
in->eof = 0;
}
#line 81 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
static inline void free_input(input_t *in)
@@ -160,6 +183,7 @@ int main(int argc, char **argv)
POST;
return 0;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
static int lex(input_t *in, Output *out)
@@ -170,144 +194,144 @@ static int lex(input_t *in, Output *out)
loop:
in->tok = in->cur;
#line 174 "gen/re2c/05__datetime-stadfa.c"
#line 198 "gen/re2c/05__datetime-stadfa.c"
{
char yych;
if ((in->lim - in->cur) < 26) if (fill(in, 26) != 0) return 1;
yych = *in->cur;
switch (yych) {
case 0x00: goto yy2;
case '0': goto yy6;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy7;
default: goto yy4;
case 0x00: goto yy1;
case '0': goto yy4;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy5;
default: goto yy2;
}
yy2:
yy1:
++in->cur;
#line 3 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
{ return 0; }
#line 197 "gen/re2c/05__datetime-stadfa.c"
yy4:
#line 221 "gen/re2c/05__datetime-stadfa.c"
yy2:
++in->cur;
yy5:
yy3:
#line 20 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
{ return 1; }
#line 203 "gen/re2c/05__datetime-stadfa.c"
yy6:
#line 227 "gen/re2c/05__datetime-stadfa.c"
yy4:
yych = *(in->mar = ++in->cur);
in->yyt2 = in->cur - 1;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy8;
default: goto yy5;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy6;
default: goto yy3;
}
yy5:
yych = *(in->mar = ++in->cur);
in->yyt2 = in->cur - 1;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy8;
default: goto yy3;
}
yy6:
yych = *++in->cur;
in->yyt3 = in->yyt2;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy9;
default: goto yy7;
}
yy7:
yych = *(in->mar = ++in->cur);
in->yyt2 = in->cur - 1;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy10;
default: goto yy5;
}
in->cur = in->mar;
goto yy3;
yy8:
yych = *++in->cur;
in->yyt3 = in->yyt2;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy11;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy10;
default: goto yy7;
}
yy9:
in->cur = in->mar;
goto yy5;
yych = *++in->cur;
in->yyt4 = in->yyt3;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy11;
default: goto yy7;
}
yy10:
yych = *++in->cur;
in->yyt4 = in->yyt3;
in->yyt3 = in->yyt2;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy12;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy12;
default: goto yy7;
}
yy11:
yych = *++in->cur;
in->yyt4 = in->yyt3;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy13;
default: goto yy9;
}
yy12:
yych = *++in->cur;
in->yyt4 = in->yyt3;
in->yyt3 = in->yyt2;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy14;
default: goto yy9;
}
yy13:
yych = *++in->cur;
in->yyt1 = in->yyt4;
switch (yych) {
case '-': goto yy16;
default: goto yy9;
case '-': goto yy13;
default: goto yy7;
}
yy14:
yy12:
++in->cur;
if ((in->lim - in->cur) < 22) if (fill(in, 22) != 0) return 1;
yych = *in->cur;
@@ -315,250 +339,250 @@ yy14:
in->yyt4 = in->yyt3;
in->yyt3 = in->yyt2;
switch (yych) {
case '-': goto yy16;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy14;
default: goto yy9;
case '-': goto yy13;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy12;
default: goto yy7;
}
yy13:
yych = *++in->cur;
switch (yych) {
case '0': goto yy14;
case '1': goto yy15;
default: goto yy7;
}
yy14:
yych = *++in->cur;
switch (yych) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy16;
default: goto yy7;
}
yy15:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2': goto yy16;
default: goto yy7;
}
yy16:
yych = *++in->cur;
switch (yych) {
case '0': goto yy17;
case '1': goto yy18;
default: goto yy9;
case '-': goto yy17;
default: goto yy7;
}
yy17:
yych = *++in->cur;
switch (yych) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy19;
default: goto yy9;
case '0': goto yy18;
case '1':
case '2': goto yy19;
case '3': goto yy20;
default: goto yy7;
}
yy18:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2': goto yy19;
default: goto yy9;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy21;
default: goto yy7;
}
yy19:
yych = *++in->cur;
switch (yych) {
case '-': goto yy20;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy21;
default: goto yy7;
}
yy20:
yych = *++in->cur;
switch (yych) {
case '0': goto yy21;
case '1':
case '2': goto yy22;
case '3': goto yy23;
default: goto yy9;
case '0':
case '1': goto yy21;
default: goto yy7;
}
yy21:
yych = *++in->cur;
switch (yych) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy24;
default: goto yy9;
case 'T': goto yy22;
default: goto yy7;
}
yy22:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy24;
default: goto yy9;
case '0':
case '1': goto yy23;
case '2': goto yy24;
default: goto yy7;
}
yy23:
yych = *++in->cur;
switch (yych) {
case '0':
case '1': goto yy24;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy25;
default: goto yy7;
}
yy24:
yych = *++in->cur;
switch (yych) {
case 'T': goto yy25;
default: goto yy9;
case '0':
case '1':
case '2':
case '3': goto yy25;
default: goto yy7;
}
yy25:
yych = *++in->cur;
switch (yych) {
case '0':
case '1': goto yy26;
case '2': goto yy27;
default: goto yy9;
case ':': goto yy26;
default: goto yy7;
}
yy26:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy28;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy27;
default: goto yy7;
}
yy27:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3': goto yy28;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy28;
default: goto yy7;
}
yy28:
yych = *++in->cur;
switch (yych) {
case ':': goto yy29;
default: goto yy9;
case ':': goto yy29;
default: goto yy7;
}
yy29:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy30;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy30;
default: goto yy7;
}
yy30:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy31;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy31;
default: goto yy7;
}
yy31:
yych = *++in->cur;
switch (yych) {
case ':': goto yy32;
default: goto yy9;
case '+':
case '-': goto yy32;
case 'Z': goto yy33;
default: goto yy7;
}
yy32:
yych = *++in->cur;
in->yyt2 = in->cur - 1;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy33;
default: goto yy9;
case '0':
case '1': goto yy34;
case '2': goto yy35;
default: goto yy7;
}
yy33:
yych = *++in->cur;
in->yyt2 = in->cur - 1;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy34;
default: goto yy9;
case '\n': goto yy36;
default: goto yy7;
}
yy34:
yych = *++in->cur;
switch (yych) {
case '+':
case '-': goto yy35;
case 'Z': goto yy36;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy37;
default: goto yy7;
}
yy35:
yych = *++in->cur;
in->yyt2 = in->cur - 1;
switch (yych) {
case '0':
case '1': goto yy37;
case '2': goto yy38;
default: goto yy9;
case '0':
case '1':
case '2':
case '3': goto yy37;
default: goto yy7;
}
yy36:
yych = *++in->cur;
in->yyt2 = in->cur - 1;
switch (yych) {
case '\n': goto yy39;
default: goto yy9;
}
yy37:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy41;
default: goto yy9;
}
yy38:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3': goto yy41;
default: goto yy9;
}
yy39:
++in->cur;
y1 = in->yyt1;
z1 = in->yyt2;
@@ -586,44 +610,44 @@ yy39:
outc(out, '\n');
goto loop;
}
#line 590 "gen/re2c/05__datetime-stadfa.c"
yy41:
#line 614 "gen/re2c/05__datetime-stadfa.c"
yy37:
yych = *++in->cur;
switch (yych) {
case ':': goto yy42;
default: goto yy9;
case ':': goto yy38;
default: goto yy7;
}
yy42:
yy38:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy43;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy39;
default: goto yy7;
}
yy43:
yy39:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy44;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy40;
default: goto yy7;
}
yy44:
yy40:
yych = *++in->cur;
switch (yych) {
case '\n': goto yy39;
default: goto yy9;
case '\n': goto yy36;
default: goto yy7;
}
}
#line 32 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
@@ -1,5 +1,6 @@
/* Generated by re2c */
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#include <assert.h>
#include <stdlib.h>
#include "common.h"
@@ -24,10 +25,16 @@ typedef struct {
char *cur;
char *mar;
char *tok;
char *yyt1;
#line 30 "gen/re2c/05__datetime-tdfa0.c"
char *yyt1;
char *yyt2;
#line 34 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#line 36 "gen/re2c/05__datetime-tdfa0.c"
#line 35 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
taglistpool_t tlp;
int eof;
} input_t;
@@ -36,6 +43,9 @@ static inline void taglistpool_clear(taglistpool_t *tlp, input_t *in)
{
tlp->next = tlp->head;
#line 47 "gen/re2c/05__datetime-tdfa0.c"
#line 43 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
}
static inline void taglistpool_init(taglistpool_t *tlp)
@@ -73,10 +83,13 @@ static inline void taglist(taglist_t **ptl, const char *b, const char *t, taglis
*ptl = tl;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 4 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 91 "gen/re2c/05__datetime-tdfa0.c"
#define YYMAXFILL 26
#line 6 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
static inline int fill(input_t *in, size_t need)
@@ -92,8 +105,11 @@ static inline int fill(input_t *in, size_t need)
in->cur -= free;
in->mar -= free;
in->tok -= free;
if (in->yyt1) in->yyt1 -= free;
#line 110 "gen/re2c/05__datetime-tdfa0.c"
if (in->yyt1) in->yyt1 -= free;
if (in->yyt2) in->yyt2 -= free;
#line 21 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
in->lim += fread(in->lim, 1, free, stdin);
@@ -114,13 +130,20 @@ static inline void init_input(input_t *in)
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
in->yyt1 = 0;
#line 135 "gen/re2c/05__datetime-tdfa0.c"
in->yyt1 = 0;
in->yyt2 = 0;
#line 41 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 141 "gen/re2c/05__datetime-tdfa0.c"
#line 42 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
taglistpool_init(&in->tlp);
in->eof = 0;
}
#line 81 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
static inline void free_input(input_t *in)
@@ -154,6 +177,7 @@ int main(int argc, char **argv)
POST;
return 0;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
static int lex(input_t *in, Output *out)
@@ -164,457 +188,457 @@ static int lex(input_t *in, Output *out)
loop:
in->tok = in->cur;
#line 168 "gen/re2c/05__datetime-tdfa0.c"
#line 192 "gen/re2c/05__datetime-tdfa0.c"
{
char yych;
in->yyt1 = in->cur;
if ((in->lim - in->cur) < 26) if (fill(in, 26) != 0) return 1;
yych = *in->cur++;
switch (yych) {
case 0x00: goto yy2;
case '0': goto yy6;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy7;
default: goto yy4;
case 0x00: goto yy1;
case '0': goto yy4;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy5;
default: goto yy2;
}
yy2:
yy1:
#line 3 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
{ return 0; }
#line 191 "gen/re2c/05__datetime-tdfa0.c"
yy4:
yy5:
#line 215 "gen/re2c/05__datetime-tdfa0.c"
yy2:
yy3:
#line 20 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
{ return 1; }
#line 196 "gen/re2c/05__datetime-tdfa0.c"
yy6:
#line 220 "gen/re2c/05__datetime-tdfa0.c"
yy4:
yych = *(in->mar = in->cur);
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy8;
default: goto yy5;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy6;
default: goto yy3;
}
yy5:
yych = *(in->mar = in->cur);
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy8;
default: goto yy3;
}
yy6:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy9;
default: goto yy7;
}
yy7:
yych = *(in->mar = in->cur);
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy10;
default: goto yy5;
}
in->cur = in->mar;
goto yy3;
yy8:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy11;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy10;
default: goto yy7;
}
yy9:
in->cur = in->mar;
goto yy5;
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy11;
default: goto yy7;
}
yy10:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy12;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy12;
default: goto yy7;
}
yy11:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy13;
default: goto yy9;
case '-':
++in->cur;
goto yy13;
default: goto yy7;
}
yy12:
if ((in->lim - in->cur) < 22) if (fill(in, 22) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy14;
default: goto yy9;
case '-':
++in->cur;
goto yy13;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy12;
default: goto yy7;
}
yy13:
yych = *in->cur;
switch (yych) {
case '-':
++in->cur;
goto yy16;
default: goto yy9;
case '0':
++in->cur;
goto yy14;
case '1':
++in->cur;
goto yy15;
default: goto yy7;
}
yy14:
if ((in->lim - in->cur) < 22) if (fill(in, 22) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '-':
++in->cur;
goto yy16;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy14;
default: goto yy9;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy16;
default: goto yy7;
}
yy15:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
++in->cur;
goto yy16;
default: goto yy7;
}
yy16:
yych = *in->cur;
switch (yych) {
case '0':
++in->cur;
goto yy17;
case '1':
++in->cur;
goto yy18;
default: goto yy9;
case '-':
++in->cur;
goto yy17;
default: goto yy7;
}
yy17:
yych = *in->cur;
switch (yych) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy19;
default: goto yy9;
case '0':
++in->cur;
goto yy18;
case '1':
case '2':
++in->cur;
goto yy19;
case '3':
++in->cur;
goto yy20;
default: goto yy7;
}
yy18:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
++in->cur;
goto yy19;
default: goto yy9;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy21;
default: goto yy7;
}
yy19:
yych = *in->cur;
switch (yych) {
case '-':
++in->cur;
goto yy20;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy21;
default: goto yy7;
}
yy20:
yych = *in->cur;
switch (yych) {
case '0':
++in->cur;
goto yy21;
case '1':
case '2':
++in->cur;
goto yy22;
case '3':
++in->cur;
goto yy23;
default: goto yy9;
case '0':
case '1':
++in->cur;
goto yy21;
default: goto yy7;
}
yy21:
yych = *in->cur;
switch (yych) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy24;
default: goto yy9;
case 'T':
++in->cur;
goto yy22;
default: goto yy7;
}
yy22:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy24;
default: goto yy9;
case '0':
case '1':
++in->cur;
goto yy23;
case '2':
++in->cur;
goto yy24;
default: goto yy7;
}
yy23:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
++in->cur;
goto yy24;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy25;
default: goto yy7;
}
yy24:
yych = *in->cur;
switch (yych) {
case 'T':
++in->cur;
goto yy25;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
++in->cur;
goto yy25;
default: goto yy7;
}
yy25:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
++in->cur;
goto yy26;
case '2':
++in->cur;
goto yy27;
default: goto yy9;
case ':':
++in->cur;
goto yy26;
default: goto yy7;
}
yy26:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy28;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
++in->cur;
goto yy27;
default: goto yy7;
}
yy27:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
++in->cur;
goto yy28;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy28;
default: goto yy7;
}
yy28:
yych = *in->cur;
switch (yych) {
case ':':
++in->cur;
goto yy29;
default: goto yy9;
case ':':
++in->cur;
goto yy29;
default: goto yy7;
}
yy29:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
++in->cur;
goto yy30;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
++in->cur;
goto yy30;
default: goto yy7;
}
yy30:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy31;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt2 = in->cur;
goto yy31;
default: goto yy7;
}
yy31:
yych = *in->cur;
switch (yych) {
case ':':
++in->cur;
goto yy32;
default: goto yy9;
case '+':
case '-':
++in->cur;
goto yy32;
case 'Z':
++in->cur;
goto yy33;
default: goto yy7;
}
yy32:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
++in->cur;
goto yy33;
default: goto yy9;
case '0':
case '1':
++in->cur;
goto yy34;
case '2':
++in->cur;
goto yy35;
default: goto yy7;
}
yy33:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
in->yyt2 = in->cur;
goto yy34;
default: goto yy9;
case '\n':
++in->cur;
goto yy36;
default: goto yy7;
}
yy34:
yych = *in->cur;
switch (yych) {
case '+':
case '-':
++in->cur;
goto yy35;
case 'Z':
++in->cur;
goto yy36;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy37;
default: goto yy7;
}
yy35:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
++in->cur;
goto yy37;
case '2':
++in->cur;
goto yy38;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
++in->cur;
goto yy37;
default: goto yy7;
}
yy36:
yych = *in->cur;
switch (yych) {
case '\n':
++in->cur;
goto yy39;
default: goto yy9;
}
yy37:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy41;
default: goto yy9;
}
yy38:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
++in->cur;
goto yy41;
default: goto yy9;
}
yy39:
y1 = in->yyt1;
z1 = in->yyt2;
y2 = in->yyt2 - 15;
@@ -641,44 +665,44 @@ yy39:
outc(out, '\n');
goto loop;
}
#line 645 "gen/re2c/05__datetime-tdfa0.c"
yy41:
#line 669 "gen/re2c/05__datetime-tdfa0.c"
yy37:
yych = *in->cur;
switch (yych) {
case ':':
++in->cur;
goto yy42;
default: goto yy9;
case ':':
++in->cur;
goto yy38;
default: goto yy7;
}
yy42:
yy38:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
++in->cur;
goto yy43;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
++in->cur;
goto yy39;
default: goto yy7;
}
yy43:
yy39:
yych = *in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy36;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
++in->cur;
goto yy33;
default: goto yy7;
}
}
#line 32 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
@@ -1,5 +1,6 @@
/* Generated by re2c */
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#include <assert.h>
#include <stdlib.h>
#include "common.h"
@@ -24,10 +25,16 @@ typedef struct {
char *cur;
char *mar;
char *tok;
char *yyt1;
#line 30 "gen/re2c/05__datetime-tdfa1.c"
char *yyt1;
char *yyt2;
#line 34 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
#line 36 "gen/re2c/05__datetime-tdfa1.c"
#line 35 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
taglistpool_t tlp;
int eof;
} input_t;
@@ -36,6 +43,9 @@ static inline void taglistpool_clear(taglistpool_t *tlp, input_t *in)
{
tlp->next = tlp->head;
#line 47 "gen/re2c/05__datetime-tdfa1.c"
#line 43 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
}
static inline void taglistpool_init(taglistpool_t *tlp)
@@ -73,10 +83,13 @@ static inline void taglist(taglist_t **ptl, const char *b, const char *t, taglis
*ptl = tl;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 4 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 91 "gen/re2c/05__datetime-tdfa1.c"
#define YYMAXFILL 26
#line 6 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
static inline int fill(input_t *in, size_t need)
@@ -92,8 +105,11 @@ static inline int fill(input_t *in, size_t need)
in->cur -= free;
in->mar -= free;
in->tok -= free;
if (in->yyt1) in->yyt1 -= free;
#line 110 "gen/re2c/05__datetime-tdfa1.c"
if (in->yyt1) in->yyt1 -= free;
if (in->yyt2) in->yyt2 -= free;
#line 21 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
in->lim += fread(in->lim, 1, free, stdin);
@@ -114,13 +130,20 @@ static inline void init_input(input_t *in)
in->cur = in->lim;
in->mar = in->lim;
in->tok = in->lim;
in->yyt1 = 0;
#line 135 "gen/re2c/05__datetime-tdfa1.c"
in->yyt1 = 0;
in->yyt2 = 0;
#line 41 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
#line 141 "gen/re2c/05__datetime-tdfa1.c"
#line 42 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
taglistpool_init(&in->tlp);
in->eof = 0;
}
#line 81 "../../../benchmarks/submatch_dfa_aot/src/re2c/common.re"
static inline void free_input(input_t *in)
@@ -154,6 +177,7 @@ int main(int argc, char **argv)
POST;
return 0;
}
#line 1 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
static int lex(input_t *in, Output *out)
@@ -164,390 +188,390 @@ static int lex(input_t *in, Output *out)
loop:
in->tok = in->cur;
#line 168 "gen/re2c/05__datetime-tdfa1.c"
#line 192 "gen/re2c/05__datetime-tdfa1.c"
{
char yych;
if ((in->lim - in->cur) < 26) if (fill(in, 26) != 0) return 1;
yych = *in->cur;
switch (yych) {
case 0x00: goto yy2;
case '0':
in->yyt1 = in->cur;
goto yy6;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt1 = in->cur;
goto yy7;
default: goto yy4;
case 0x00: goto yy1;
case '0':
in->yyt1 = in->cur;
goto yy4;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
in->yyt1 = in->cur;
goto yy5;
default: goto yy2;
}
yy2:
yy1:
++in->cur;
#line 3 "../../../benchmarks/submatch_dfa_aot/src/re2c/include/fill.re"
{ return 0; }
#line 195 "gen/re2c/05__datetime-tdfa1.c"
yy4:
#line 219 "gen/re2c/05__datetime-tdfa1.c"
yy2:
++in->cur;
yy5:
yy3:
#line 20 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
{ return 1; }
#line 201 "gen/re2c/05__datetime-tdfa1.c"
yy6:
#line 225 "gen/re2c/05__datetime-tdfa1.c"
yy4:
yych = *(in->mar = ++in->cur);
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy8;
default: goto yy5;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy6;
default: goto yy3;
}
yy5:
yych = *(in->mar = ++in->cur);
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy8;
default: goto yy3;
}
yy6:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy9;
default: goto yy7;
}
yy7:
yych = *(in->mar = ++in->cur);
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy10;
default: goto yy5;
}
in->cur = in->mar;
goto yy3;
yy8:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy11;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy10;
default: goto yy7;
}
yy9:
in->cur = in->mar;
goto yy5;
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy11;
default: goto yy7;
}
yy10:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy12;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy12;
default: goto yy7;
}
yy11:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy13;
default: goto yy9;
case '-': goto yy13;
default: goto yy7;
}
yy12:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy14;
default: goto yy9;
}
yy13:
yych = *++in->cur;
switch (yych) {
case '-': goto yy16;
default: goto yy9;
}
yy14:
++in->cur;
if ((in->lim - in->cur) < 22) if (fill(in, 22) != 0) return 1;
yych = *in->cur;
switch (yych) {
case '-': goto yy16;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy14;
default: goto yy9;
case '-': goto yy13;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy12;
default: goto yy7;
}
yy13:
yych = *++in->cur;
switch (yych) {
case '0': goto yy14;
case '1': goto yy15;
default: goto yy7;
}
yy14:
yych = *++in->cur;
switch (yych) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy16;
default: goto yy7;
}
yy15:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2': goto yy16;
default: goto yy7;
}
yy16:
yych = *++in->cur;
switch (yych) {
case '0': goto yy17;
case '1': goto yy18;
default: goto yy9;
case '-': goto yy17;
default: goto yy7;
}
yy17:
yych = *++in->cur;
switch (yych) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy19;
default: goto yy9;
case '0': goto yy18;
case '1':
case '2': goto yy19;
case '3': goto yy20;
default: goto yy7;
}
yy18:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2': goto yy19;
default: goto yy9;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy21;
default: goto yy7;
}
yy19:
yych = *++in->cur;
switch (yych) {
case '-': goto yy20;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy21;
default: goto yy7;
}
yy20:
yych = *++in->cur;
switch (yych) {
case '0': goto yy21;
case '1':
case '2': goto yy22;
case '3': goto yy23;
default: goto yy9;
case '0':
case '1': goto yy21;
default: goto yy7;
}
yy21:
yych = *++in->cur;
switch (yych) {
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy24;
default: goto yy9;
case 'T': goto yy22;
default: goto yy7;
}
yy22:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy24;
default: goto yy9;
case '0':
case '1': goto yy23;
case '2': goto yy24;
default: goto yy7;
}
yy23:
yych = *++in->cur;
switch (yych) {
case '0':
case '1': goto yy24;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy25;
default: goto yy7;
}
yy24:
yych = *++in->cur;
switch (yych) {
case 'T': goto yy25;
default: goto yy9;
case '0':
case '1':
case '2':
case '3': goto yy25;
default: goto yy7;
}
yy25:
yych = *++in->cur;
switch (yych) {
case '0':
case '1': goto yy26;
case '2': goto yy27;
default: goto yy9;
case ':': goto yy26;
default: goto yy7;
}
yy26:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy28;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy27;
default: goto yy7;
}
yy27:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3': goto yy28;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy28;
default: goto yy7;
}
yy28:
yych = *++in->cur;
switch (yych) {
case ':': goto yy29;
default: goto yy9;
case ':': goto yy29;
default: goto yy7;
}
yy29:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy30;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy30;
default: goto yy7;
}
yy30:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy31;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy31;
default: goto yy7;
}
yy31:
yych = *++in->cur;
switch (yych) {
case ':': goto yy32;
default: goto yy9;
case '+':
case '-':
in->yyt2 = in->cur;
goto yy32;
case 'Z':
in->yyt2 = in->cur;
goto yy33;
default: goto yy7;
}
yy32:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy33;
default: goto yy9;
case '0':
case '1': goto yy34;
case '2': goto yy35;
default: goto yy7;
}
yy33:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy34;
default: goto yy9;
case '\n': goto yy36;
default: goto yy7;
}
yy34:
yych = *++in->cur;
switch (yych) {
case '+':
case '-':
in->yyt2 = in->cur;
goto yy35;
case 'Z':
in->yyt2 = in->cur;
goto yy36;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy37;
default: goto yy7;
}
yy35:
yych = *++in->cur;
switch (yych) {
case '0':
case '1': goto yy37;
case '2': goto yy38;
default: goto yy9;
case '0':
case '1':
case '2':
case '3': goto yy37;
default: goto yy7;
}
yy36:
yych = *++in->cur;
switch (yych) {
case '\n': goto yy39;
default: goto yy9;
}
yy37:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy41;
default: goto yy9;
}
yy38:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3': goto yy41;
default: goto yy9;
}
yy39:
++in->cur;
y1 = in->yyt1;
z1 = in->yyt2;
@@ -575,38 +599,38 @@ yy39:
outc(out, '\n');
goto loop;
}
#line 579 "gen/re2c/05__datetime-tdfa1.c"
yy41:
#line 603 "gen/re2c/05__datetime-tdfa1.c"
yy37:
yych = *++in->cur;
switch (yych) {
case ':': goto yy42;
default: goto yy9;
case ':': goto yy38;
default: goto yy7;
}
yy42:
yy38:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy43;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5': goto yy39;
default: goto yy7;
}
yy43:
yy39:
yych = *++in->cur;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy36;
default: goto yy9;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy33;
default: goto yy7;
}
}
#line 32 "../../../benchmarks/submatch_dfa_aot/src/re2c/05__datetime.re"
File diff suppressed because it is too large Load Diff

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