Compare commits

...
27 Commits
ci ... 3.1
Author SHA1 Message Date
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
80 changed files with 6161 additions and 4450 deletions
+1
View File
@@ -11,6 +11,7 @@
/m4
/test_*
/.build*
/bazel-*
# Ignore user defined CMake presets
CMakeUserPresets.json
+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"],
)
+12 -8
View File
@@ -52,9 +52,13 @@ The configure script has many options (to see them all, run
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 Python 3 Docutils).
@@ -152,13 +156,13 @@ specific to re2c:
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 `parser.cc` and `parser.h` files (as opposed to
using bootstrap files). This requires an available Bison parser generator.
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 Python 3 Docutils).
+98
View File
@@ -6,6 +6,104 @@ 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)
~~~~~~~~~~~~~~~~
+4 -3
View File
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.12)
project(re2c VERSION 3.0 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")
@@ -49,9 +49,10 @@ if(RE2C_REBUILD_DOCS)
endif()
endif()
# checks for C++ compiler flags
# 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_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON) # make sure object libraries work with shared libraries
# needed for POSIX file API
-1
View File
@@ -38,7 +38,6 @@ libre2c_la_HDR = \
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 \
+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()
+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
+35 -7
View File
@@ -438,10 +438,18 @@ sequence of code units is a sequence of standalone 1\-byte characters.
With \fButf8\fP re2c handles input as UTF8\-encoded and recognizes multibyte
characters.
.TP
.B \fB\-\-invert\-captures\fP
Invert the meaning of capturing and non\-capturing groups. By default
\fB(...)\fP is capturing and \fB(! ...)\fP is non\-capturing. With this option
\fB(! ...)\fP is capturing and \fB(...)\fP is non\-capturing.
.TP
.B \fB\-\-lang <c | go | rust>\fP
Specify the output language. Supported languages are C, Go and Rust.
The default is C for re2c, Go for re2go and Rust for re2rust.
.TP
.B \fB\-\-leftmost\-captures\fP
Enable submatch extraction with leftmost greedy capturing groups.
.TP
.B \fB\-\-location\-format <gnu | msvc>\fP
Specify location format in messages.
With \fBgnu\fP locations are printed as \(aqfilename:line:column: ...\(aq.
@@ -1343,6 +1351,10 @@ To disable indentation entirely, set this configuration to an empty string.
Specifies the minimum amount of indentation to use. The default value is
zero. The value should be a non\-negative integer number.
.TP
.B \fBre2c:invert\-captures\fP
Same as the \fB\-\-invert\-captures\fP option, but can be configured on per\-block
basis.
.TP
.B \fBre2c:label:prefix\fP, \fBre2c:labelprefix\fP
Specifies the prefix used for DFA state labels. The default is \fByy\fP\&.
.TP
@@ -1367,6 +1379,10 @@ Specifies the name of the optional label that follows \fBYYGETSTATE\fP switch
in storable state mode (enabled with \fBre2c:state:nextlabel\fP). The default
is \fByyNext\fP\&.
.TP
.B \fBre2c:leftmost\-captures\fP
Same as the \fB\-\-leftmost\-captures\fP option, but can be configured on
per\-block basis.
.TP
.B \fBre2c:lookahead\fP, \fBre2c:flags:lookahead\fP
Deprecated (see the deprecated \fB\-\-no\-lookahead\fP option).
.TP
@@ -1507,7 +1523,13 @@ re2c uses the following syntax for regular expressions:
.IP \(bu 2
\fBR{n,m}\fP repetition of \fBR\fP from \fBn\fP to \fBm\fP times
.IP \(bu 2
\fB(R)\fP just \fBR\fP; parentheses are used to override precedence or for POSIX\-style submatch
\fB(R)\fP just \fBR\fP; parentheses are used to override precedence.
If submatch extraction is enabled, \fB(R)\fP is a capturing or a
non\-capturing group depending on \fB\-\-invert\-captures\fP option.
.IP \(bu 2
\fB(!R)\fP
If submatch extraction is enabled, \fB(!R)\fP is a non\-capturing or a
capturing group depending on \fB\-\-invert\-captures\fP option.
.IP \(bu 2
\fBR S\fP concatenation: \fBR\fP followed by \fBS\fP
.IP \(bu 2
@@ -1515,17 +1537,23 @@ re2c uses the following syntax for regular expressions:
.IP \(bu 2
\fBR / S\fP lookahead: \fBR\fP followed by \fBS\fP, but \fBS\fP is not consumed
.IP \(bu 2
\fBname\fP the regular expression defined as \fBname\fP (or literal string \fB\(dqname\(dq\fP in Flex compatibility mode)
\fBname\fP the regular expression defined as \fBname\fP (or literal string
\fB\(dqname\(dq\fP in Flex compatibility mode)
.IP \(bu 2
\fB{name}\fP the regular expression defined as \fBname\fP in Flex compatibility mode
\fB{name}\fP the regular expression defined as \fBname\fP in Flex
compatibility mode
.IP \(bu 2
\fB@stag\fP an \fIs\-tag\fP: saves the last input position at which \fB@stag\fP matches in a variable named \fBstag\fP
\fB@stag\fP an \fIs\-tag\fP: saves the last input position at which \fB@stag\fP
matches in a variable named \fBstag\fP
.IP \(bu 2
\fB#mtag\fP an \fIm\-tag\fP: saves all input positions at which \fB#mtag\fP matches in a variable named \fBmtag\fP
\fB#mtag\fP an \fIm\-tag\fP: saves all input positions at which \fB#mtag\fP matches
in a variable named \fBmtag\fP
.UNINDENT
.sp
Character classes and string literals may contain the following escape sequences:
\fB\ea\fP, \fB\eb\fP, \fB\ef\fP, \fB\en\fP, \fB\er\fP, \fB\et\fP, \fB\ev\fP, \fB\e\e\fP, octal escapes \fB\eooo\fP and hexadecimal escapes \fB\exhh\fP, \fB\euhhhh\fP and \fB\eUhhhhhhhh\fP\&.
Character classes and string literals may contain the following escape
sequences: \fB\ea\fP, \fB\eb\fP, \fB\ef\fP, \fB\en\fP, \fB\er\fP, \fB\et\fP, \fB\ev\fP, \fB\e\e\fP,
octal escapes \fB\eooo\fP and hexadecimal escapes \fB\exhh\fP, \fB\euhhhh\fP and
\fB\eUhhhhhhhh\fP\&.
.SH HANDLING THE END OF INPUT
.sp
One of the main problems for the lexer is to know when to stop.
+35 -7
View File
@@ -442,10 +442,18 @@ sequence of code units is a sequence of standalone 1\-byte characters.
With \fButf8\fP re2c handles input as UTF8\-encoded and recognizes multibyte
characters.
.TP
.B \fB\-\-invert\-captures\fP
Invert the meaning of capturing and non\-capturing groups. By default
\fB(...)\fP is capturing and \fB(! ...)\fP is non\-capturing. With this option
\fB(! ...)\fP is capturing and \fB(...)\fP is non\-capturing.
.TP
.B \fB\-\-lang <c | go | rust>\fP
Specify the output language. Supported languages are C, Go and Rust.
The default is C for re2c, Go for re2go and Rust for re2rust.
.TP
.B \fB\-\-leftmost\-captures\fP
Enable submatch extraction with leftmost greedy capturing groups.
.TP
.B \fB\-\-location\-format <gnu | msvc>\fP
Specify location format in messages.
With \fBgnu\fP locations are printed as \(aqfilename:line:column: ...\(aq.
@@ -1347,6 +1355,10 @@ To disable indentation entirely, set this configuration to an empty string.
Specifies the minimum amount of indentation to use. The default value is
zero. The value should be a non\-negative integer number.
.TP
.B \fBre2c:invert\-captures\fP
Same as the \fB\-\-invert\-captures\fP option, but can be configured on per\-block
basis.
.TP
.B \fBre2c:label:prefix\fP, \fBre2c:labelprefix\fP
Specifies the prefix used for DFA state labels. The default is \fByy\fP\&.
.TP
@@ -1371,6 +1383,10 @@ Specifies the name of the optional label that follows \fBYYGETSTATE\fP switch
in storable state mode (enabled with \fBre2c:state:nextlabel\fP). The default
is \fByyNext\fP\&.
.TP
.B \fBre2c:leftmost\-captures\fP
Same as the \fB\-\-leftmost\-captures\fP option, but can be configured on
per\-block basis.
.TP
.B \fBre2c:lookahead\fP, \fBre2c:flags:lookahead\fP
Deprecated (see the deprecated \fB\-\-no\-lookahead\fP option).
.TP
@@ -1511,7 +1527,13 @@ re2c uses the following syntax for regular expressions:
.IP \(bu 2
\fBR{n,m}\fP repetition of \fBR\fP from \fBn\fP to \fBm\fP times
.IP \(bu 2
\fB(R)\fP just \fBR\fP; parentheses are used to override precedence or for POSIX\-style submatch
\fB(R)\fP just \fBR\fP; parentheses are used to override precedence.
If submatch extraction is enabled, \fB(R)\fP is a capturing or a
non\-capturing group depending on \fB\-\-invert\-captures\fP option.
.IP \(bu 2
\fB(!R)\fP
If submatch extraction is enabled, \fB(!R)\fP is a non\-capturing or a
capturing group depending on \fB\-\-invert\-captures\fP option.
.IP \(bu 2
\fBR S\fP concatenation: \fBR\fP followed by \fBS\fP
.IP \(bu 2
@@ -1519,17 +1541,23 @@ re2c uses the following syntax for regular expressions:
.IP \(bu 2
\fBR / S\fP lookahead: \fBR\fP followed by \fBS\fP, but \fBS\fP is not consumed
.IP \(bu 2
\fBname\fP the regular expression defined as \fBname\fP (or literal string \fB\(dqname\(dq\fP in Flex compatibility mode)
\fBname\fP the regular expression defined as \fBname\fP (or literal string
\fB\(dqname\(dq\fP in Flex compatibility mode)
.IP \(bu 2
\fB{name}\fP the regular expression defined as \fBname\fP in Flex compatibility mode
\fB{name}\fP the regular expression defined as \fBname\fP in Flex
compatibility mode
.IP \(bu 2
\fB@stag\fP an \fIs\-tag\fP: saves the last input position at which \fB@stag\fP matches in a variable named \fBstag\fP
\fB@stag\fP an \fIs\-tag\fP: saves the last input position at which \fB@stag\fP
matches in a variable named \fBstag\fP
.IP \(bu 2
\fB#mtag\fP an \fIm\-tag\fP: saves all input positions at which \fB#mtag\fP matches in a variable named \fBmtag\fP
\fB#mtag\fP an \fIm\-tag\fP: saves all input positions at which \fB#mtag\fP matches
in a variable named \fBmtag\fP
.UNINDENT
.sp
Character classes and string literals may contain the following escape sequences:
\fB\ea\fP, \fB\eb\fP, \fB\ef\fP, \fB\en\fP, \fB\er\fP, \fB\et\fP, \fB\ev\fP, \fB\e\e\fP, octal escapes \fB\eooo\fP and hexadecimal escapes \fB\exhh\fP, \fB\euhhhh\fP and \fB\eUhhhhhhhh\fP\&.
Character classes and string literals may contain the following escape
sequences: \fB\ea\fP, \fB\eb\fP, \fB\ef\fP, \fB\en\fP, \fB\er\fP, \fB\et\fP, \fB\ev\fP, \fB\e\e\fP,
octal escapes \fB\eooo\fP and hexadecimal escapes \fB\exhh\fP, \fB\euhhhh\fP and
\fB\eUhhhhhhhh\fP\&.
.SH HANDLING THE END OF INPUT
.sp
One of the main problems for the lexer is to know when to stop.
+35 -7
View File
@@ -458,10 +458,18 @@ sequence of code units is a sequence of standalone 1\-byte characters.
With \fButf8\fP re2c handles input as UTF8\-encoded and recognizes multibyte
characters.
.TP
.B \fB\-\-invert\-captures\fP
Invert the meaning of capturing and non\-capturing groups. By default
\fB(...)\fP is capturing and \fB(! ...)\fP is non\-capturing. With this option
\fB(! ...)\fP is capturing and \fB(...)\fP is non\-capturing.
.TP
.B \fB\-\-lang <c | go | rust>\fP
Specify the output language. Supported languages are C, Go and Rust.
The default is C for re2c, Go for re2go and Rust for re2rust.
.TP
.B \fB\-\-leftmost\-captures\fP
Enable submatch extraction with leftmost greedy capturing groups.
.TP
.B \fB\-\-location\-format <gnu | msvc>\fP
Specify location format in messages.
With \fBgnu\fP locations are printed as \(aqfilename:line:column: ...\(aq.
@@ -1363,6 +1371,10 @@ To disable indentation entirely, set this configuration to an empty string.
Specifies the minimum amount of indentation to use. The default value is
zero. The value should be a non\-negative integer number.
.TP
.B \fBre2c:invert\-captures\fP
Same as the \fB\-\-invert\-captures\fP option, but can be configured on per\-block
basis.
.TP
.B \fBre2c:label:prefix\fP, \fBre2c:labelprefix\fP
Specifies the prefix used for DFA state labels. The default is \fByy\fP\&.
.TP
@@ -1387,6 +1399,10 @@ Specifies the name of the optional label that follows \fBYYGETSTATE\fP switch
in storable state mode (enabled with \fBre2c:state:nextlabel\fP). The default
is \fByyNext\fP\&.
.TP
.B \fBre2c:leftmost\-captures\fP
Same as the \fB\-\-leftmost\-captures\fP option, but can be configured on
per\-block basis.
.TP
.B \fBre2c:lookahead\fP, \fBre2c:flags:lookahead\fP
Deprecated (see the deprecated \fB\-\-no\-lookahead\fP option).
.TP
@@ -1527,7 +1543,13 @@ re2c uses the following syntax for regular expressions:
.IP \(bu 2
\fBR{n,m}\fP repetition of \fBR\fP from \fBn\fP to \fBm\fP times
.IP \(bu 2
\fB(R)\fP just \fBR\fP; parentheses are used to override precedence or for POSIX\-style submatch
\fB(R)\fP just \fBR\fP; parentheses are used to override precedence.
If submatch extraction is enabled, \fB(R)\fP is a capturing or a
non\-capturing group depending on \fB\-\-invert\-captures\fP option.
.IP \(bu 2
\fB(!R)\fP
If submatch extraction is enabled, \fB(!R)\fP is a non\-capturing or a
capturing group depending on \fB\-\-invert\-captures\fP option.
.IP \(bu 2
\fBR S\fP concatenation: \fBR\fP followed by \fBS\fP
.IP \(bu 2
@@ -1535,17 +1557,23 @@ re2c uses the following syntax for regular expressions:
.IP \(bu 2
\fBR / S\fP lookahead: \fBR\fP followed by \fBS\fP, but \fBS\fP is not consumed
.IP \(bu 2
\fBname\fP the regular expression defined as \fBname\fP (or literal string \fB\(dqname\(dq\fP in Flex compatibility mode)
\fBname\fP the regular expression defined as \fBname\fP (or literal string
\fB\(dqname\(dq\fP in Flex compatibility mode)
.IP \(bu 2
\fB{name}\fP the regular expression defined as \fBname\fP in Flex compatibility mode
\fB{name}\fP the regular expression defined as \fBname\fP in Flex
compatibility mode
.IP \(bu 2
\fB@stag\fP an \fIs\-tag\fP: saves the last input position at which \fB@stag\fP matches in a variable named \fBstag\fP
\fB@stag\fP an \fIs\-tag\fP: saves the last input position at which \fB@stag\fP
matches in a variable named \fBstag\fP
.IP \(bu 2
\fB#mtag\fP an \fIm\-tag\fP: saves all input positions at which \fB#mtag\fP matches in a variable named \fBmtag\fP
\fB#mtag\fP an \fIm\-tag\fP: saves all input positions at which \fB#mtag\fP matches
in a variable named \fBmtag\fP
.UNINDENT
.sp
Character classes and string literals may contain the following escape sequences:
\fB\ea\fP, \fB\eb\fP, \fB\ef\fP, \fB\en\fP, \fB\er\fP, \fB\et\fP, \fB\ev\fP, \fB\e\e\fP, octal escapes \fB\eooo\fP and hexadecimal escapes \fB\exhh\fP, \fB\euhhhh\fP and \fB\eUhhhhhhhh\fP\&.
Character classes and string literals may contain the following escape
sequences: \fB\ea\fP, \fB\eb\fP, \fB\ef\fP, \fB\en\fP, \fB\er\fP, \fB\et\fP, \fB\ev\fP, \fB\e\e\fP,
octal escapes \fB\eooo\fP and hexadecimal escapes \fB\exhh\fP, \fB\euhhhh\fP and
\fB\eUhhhhhhhh\fP\&.
.SH HANDLING THE END OF INPUT
.sp
One of the main problems for the lexer is to know when to stop.
+1 -1
View File
@@ -1,4 +1,4 @@
/* Generated by re2c 3.0 */
/* Generated by re2c 3.1 */
#line 1 "../lib/lex.re"
#include <stdint.h>
#include <stdio.h>
+2 -2
View File
@@ -1144,13 +1144,13 @@ yyreduce:
case 13: /* primary: '(' ')' */
#line 77 "../lib/parse.ypp"
{ (yyval.regexp) = ast.cap(ast.nil(NOWHERE)); }
{ (yyval.regexp) = ast.cap(ast.nil(NOWHERE), CAPTURE); }
#line 1149 "lib/parse.cc"
break;
case 14: /* primary: '(' expr ')' */
#line 78 "../lib/parse.ypp"
{ (yyval.regexp) = ast.cap((yyvsp[-1].regexp)); }
{ (yyval.regexp) = ast.cap((yyvsp[-1].regexp), CAPTURE); }
#line 1155 "lib/parse.cc"
break;
+1 -1
View File
@@ -51,7 +51,7 @@ extern int yydebug;
#include "src/parse/ast.h"
namespace re2c {
struct AstNode;
};
}
#line 57 "lib/parse.h"
+1 -1
View File
@@ -1,4 +1,4 @@
/* Generated by re2c 3.0 */
/* Generated by re2c 3.1 */
#line 1 "../lib/test_helper.re"
#include "lib/test_helper.h"
+10
View File
@@ -116,11 +116,21 @@ const char* help =
" units is a sequence of standalone 1-byte characters. With utf8 re2c\n"
" handles input as UTF8-encoded and recognizes multibyte characters.\n"
"\n"
" --invert-captures\n"
"\n"
" Invert the meaning of capturing and non-capturing groups. By default\n"
" (...) is capturing and (! ...) is non-capturing. With this option (!\n"
" ...) is capturing and (...) is non-capturing.\n"
"\n"
" --lang <c | go | rust>\n"
"\n"
" Specify the output language. Supported languages are C, Go and Rust.\n"
" The default is C for re2c, Go for re2go and Rust for re2rust.\n"
"\n"
" --leftmost-captures\n"
"\n"
" Enable submatch extraction with leftmost greedy capturing groups.\n"
"\n"
" --location-format <gnu | msvc>\n"
"\n"
" Specify location format in messages. With gnu locations are printed as\n"
+1 -1
View File
@@ -1,4 +1,4 @@
/* Generated by re2c 3.0 */
/* Generated by re2c 3.1 */
#line 1 "../src/msg/ver_to_vernum.re"
#include <stddef.h>
#include <stdint.h>
File diff suppressed because it is too large Load Diff
+353 -345
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,4 +1,4 @@
/* Generated by re2c 3.0 */
/* Generated by re2c 3.1 */
#ifndef _RE2C_PARSE_LEX_
#define _RE2C_PARSE_LEX_
File diff suppressed because it is too large Load Diff
+110 -108
View File
@@ -144,21 +144,22 @@ enum yysymbol_kind_t
YYSYMBOL_26_ = 26, /* '?' */
YYSYMBOL_27_ = 27, /* '(' */
YYSYMBOL_28_ = 28, /* ')' */
YYSYMBOL_YYACCEPT = 29, /* $accept */
YYSYMBOL_spec = 30, /* spec */
YYSYMBOL_def = 31, /* def */
YYSYMBOL_name = 32, /* name */
YYSYMBOL_enddef = 33, /* enddef */
YYSYMBOL_rule = 34, /* rule */
YYSYMBOL_ccode = 35, /* ccode */
YYSYMBOL_trailexpr = 36, /* trailexpr */
YYSYMBOL_expr = 37, /* expr */
YYSYMBOL_diff = 38, /* diff */
YYSYMBOL_term = 39, /* term */
YYSYMBOL_factor = 40, /* factor */
YYSYMBOL_closes = 41, /* closes */
YYSYMBOL_close = 42, /* close */
YYSYMBOL_primary = 43 /* primary */
YYSYMBOL_29_ = 29, /* '!' */
YYSYMBOL_YYACCEPT = 30, /* $accept */
YYSYMBOL_spec = 31, /* spec */
YYSYMBOL_def = 32, /* def */
YYSYMBOL_name = 33, /* name */
YYSYMBOL_enddef = 34, /* enddef */
YYSYMBOL_rule = 35, /* rule */
YYSYMBOL_ccode = 36, /* ccode */
YYSYMBOL_trailexpr = 37, /* trailexpr */
YYSYMBOL_expr = 38, /* expr */
YYSYMBOL_diff = 39, /* diff */
YYSYMBOL_term = 40, /* term */
YYSYMBOL_factor = 41, /* factor */
YYSYMBOL_closes = 42, /* closes */
YYSYMBOL_close = 43, /* close */
YYSYMBOL_primary = 44 /* primary */
};
typedef enum yysymbol_kind_t yysymbol_kind_t;
@@ -486,10 +487,10 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
#define YYLAST 64
#define YYLAST 67
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 29
#define YYNTOKENS 30
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 15
/* YYNRULES -- Number of rules. */
@@ -515,7 +516,7 @@ static const yytype_int8 yytranslate[] =
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 22, 2, 2, 2,
2, 2, 2, 29, 2, 2, 22, 2, 2, 2,
27, 28, 21, 25, 2, 2, 2, 18, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 20,
2, 19, 2, 26, 2, 2, 2, 2, 2, 2,
@@ -548,9 +549,9 @@ static const yytype_uint8 yyrline[] =
{
0, 76, 76, 77, 81, 85, 86, 87, 91, 94,
100, 101, 104, 104, 107, 110, 113, 116, 122, 128,
134, 140, 147, 148, 153, 158, 159, 164, 165, 169,
170, 174, 176, 180, 181, 194, 200, 201, 205, 206,
207, 211, 212, 221, 222
134, 140, 147, 148, 153, 158, 159, 165, 166, 170,
171, 175, 177, 181, 182, 195, 201, 202, 206, 207,
208, 212, 213, 222, 223
};
#endif
@@ -571,8 +572,8 @@ static const char *const yytname[] =
"TOKEN_CLOSESIZE", "TOKEN_CODE", "TOKEN_CONF", "TOKEN_ID", "TOKEN_FID",
"TOKEN_FID_END", "TOKEN_LINE_INFO", "TOKEN_REGEXP", "TOKEN_BLOCK",
"TOKEN_ERROR", "'/'", "'='", "';'", "'*'", "'$'", "'|'", "'\\\\'", "'+'",
"'?'", "'('", "')'", "$accept", "spec", "def", "name", "enddef", "rule",
"ccode", "trailexpr", "expr", "diff", "term", "factor", "closes",
"'?'", "'('", "')'", "'!'", "$accept", "spec", "def", "name", "enddef",
"rule", "ccode", "trailexpr", "expr", "diff", "term", "factor", "closes",
"close", "primary", YY_NULLPTR
};
@@ -597,13 +598,13 @@ yysymbol_name (yysymbol_kind_t yysymbol)
STATE-NUM. */
static const yytype_int8 yypact[] =
{
-20, 0, -20, 14, -1, 36, -20, -18, -20, -20,
-20, -20, 11, 45, 22, -20, 23, -20, 52, 24,
-15, -20, 23, 5, -20, 36, 36, 36, -20, -20,
53, -20, -20, -20, -20, -20, 23, 29, 33, -20,
23, 23, 23, -20, -20, -20, -20, -20, 34, -20,
-20, -20, -20, -20, 35, -20, -20, -20, -20, -20,
9, -15, -20, -20, -20
-20, 0, -20, 19, -8, 46, -20, -11, -20, -20,
-20, -20, 9, 17, 2, -20, 24, -20, 33, 35,
-15, -20, 24, 11, -20, 46, 46, 46, -20, -20,
38, -20, -20, -20, -20, -20, 24, -3, 25, -20,
24, 24, 24, -20, -20, -20, -20, -20, 31, -20,
-20, -20, -20, -20, 36, -20, -20, -20, -20, -20,
10, -15, -20, -20, -20
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -623,8 +624,8 @@ static const yytype_int8 yydefact[] =
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
-20, -20, -20, -20, -20, -20, -8, 40, -12, 3,
-19, -20, -20, 16, -20
-20, -20, -20, -20, -20, -20, 40, 41, -12, 13,
-19, -20, -20, 12, -20
};
/* YYDEFGOTO[NTERM-NUM]. */
@@ -639,47 +640,47 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int8 yytable[] =
{
2, 33, 37, 43, 38, 3, 4, 5, 28, 42,
6, 7, 8, 44, 9, 10, 11, 50, 51, 52,
34, 12, 13, 62, 54, 24, 45, 14, 60, 10,
46, 47, 41, 24, 24, 25, 26, 10, 10, 29,
30, 14, 40, 27, 61, 31, 56, 41, 36, 14,
14, 57, 41, 58, 35, 45, 41, 55, 41, 46,
47, 39, 53, 64, 63
2, 28, 37, 43, 38, 3, 4, 5, 33, 42,
6, 7, 8, 24, 9, 10, 11, 10, 34, 44,
41, 12, 13, 62, 54, 55, 35, 14, 60, 14,
24, 36, 45, 41, 10, 24, 46, 47, 56, 10,
25, 26, 39, 57, 27, 58, 14, 53, 41, 29,
30, 14, 45, 40, 61, 31, 46, 47, 41, 41,
63, 0, 0, 0, 64, 50, 51, 52
};
static const yytype_int8 yycheck[] =
{
0, 19, 14, 22, 16, 5, 6, 7, 9, 24,
10, 11, 12, 8, 14, 15, 16, 25, 26, 27,
9, 21, 22, 42, 36, 11, 21, 27, 40, 15,
25, 26, 23, 11, 11, 21, 22, 15, 15, 3,
4, 27, 18, 3, 41, 9, 13, 23, 26, 27,
27, 18, 23, 20, 9, 21, 23, 28, 23, 25,
26, 9, 9, 28, 48
0, 9, 14, 22, 16, 5, 6, 7, 19, 24,
10, 11, 12, 11, 14, 15, 16, 15, 9, 8,
23, 21, 22, 42, 36, 28, 9, 27, 40, 27,
11, 29, 21, 23, 15, 11, 25, 26, 13, 15,
21, 22, 9, 18, 3, 20, 27, 9, 23, 3,
4, 27, 21, 18, 41, 9, 25, 26, 23, 23,
48, -1, -1, -1, 28, 25, 26, 27
};
/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
state STATE-NUM. */
static const yytype_int8 yystos[] =
{
0, 30, 0, 5, 6, 7, 10, 11, 12, 14,
15, 16, 21, 22, 27, 31, 32, 34, 36, 37,
38, 39, 40, 43, 11, 21, 22, 36, 9, 3,
4, 9, 35, 19, 9, 9, 26, 37, 37, 9,
18, 23, 24, 39, 8, 21, 25, 26, 41, 42,
35, 35, 35, 9, 37, 28, 13, 18, 20, 33,
37, 38, 39, 42, 28
0, 31, 0, 5, 6, 7, 10, 11, 12, 14,
15, 16, 21, 22, 27, 32, 33, 35, 37, 38,
39, 40, 41, 44, 11, 21, 22, 37, 9, 3,
4, 9, 36, 19, 9, 9, 29, 38, 38, 9,
18, 23, 24, 40, 8, 21, 25, 26, 42, 43,
36, 36, 36, 9, 38, 28, 13, 18, 20, 34,
38, 39, 40, 43, 28
};
/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
static const yytype_int8 yyr1[] =
{
0, 29, 30, 30, 30, 30, 30, 30, 31, 31,
32, 32, 33, 33, 34, 34, 34, 34, 34, 34,
34, 34, 35, 35, 35, 36, 36, 37, 37, 38,
38, 39, 39, 40, 40, 40, 41, 41, 42, 42,
42, 43, 43, 43, 43
0, 30, 31, 31, 31, 31, 31, 31, 32, 32,
33, 33, 34, 34, 35, 35, 35, 35, 35, 35,
35, 35, 36, 36, 36, 37, 37, 38, 38, 39,
39, 40, 40, 41, 41, 41, 42, 42, 43, 43,
43, 44, 44, 44, 44
};
/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
@@ -1172,7 +1173,7 @@ yyreduce:
if (use_block(input, ast, opts, grams, ast.temp_blockname) != Ret::OK) YYABORT;
ast.temp_blockname.clear();
}
#line 1176 "src/parse/parser.cc"
#line 1177 "src/parse/parser.cc"
break;
case 4: /* spec: spec TOKEN_CONF */
@@ -1181,7 +1182,7 @@ yyreduce:
// Handled here, as the main lexer should not get access to opts under construction.
if (input.lex_conf(opts) != Ret::OK) YYABORT;
}
#line 1185 "src/parse/parser.cc"
#line 1186 "src/parse/parser.cc"
break;
case 8: /* def: name expr enddef */
@@ -1189,7 +1190,7 @@ yyreduce:
{
if (add_named_def(opts.symtab, (yyvsp[-2].cstr), (yyvsp[-1].regexp), input) != Ret::OK) YYABORT;
}
#line 1193 "src/parse/parser.cc"
#line 1194 "src/parse/parser.cc"
break;
case 9: /* def: name expr '/' */
@@ -1198,13 +1199,13 @@ yyreduce:
input.error_at_tok("trailing contexts are not allowed in named definitions");
YYABORT;
}
#line 1202 "src/parse/parser.cc"
#line 1203 "src/parse/parser.cc"
break;
case 10: /* name: TOKEN_ID '=' */
#line 100 "../src/parse/parser.ypp"
{ (yyval.cstr) = (yyvsp[-1].cstr); }
#line 1208 "src/parse/parser.cc"
#line 1209 "src/parse/parser.cc"
break;
case 14: /* rule: trailexpr TOKEN_CODE */
@@ -1212,7 +1213,7 @@ yyreduce:
{
find_or_add_gram(grams, "").rules.push_back(AstRule((yyvsp[-1].regexp), (yyvsp[0].semact)));
}
#line 1216 "src/parse/parser.cc"
#line 1217 "src/parse/parser.cc"
break;
case 15: /* rule: '*' TOKEN_CODE */
@@ -1220,7 +1221,7 @@ yyreduce:
{
find_or_add_gram(grams, "").defs.push_back((yyvsp[0].semact));
}
#line 1224 "src/parse/parser.cc"
#line 1225 "src/parse/parser.cc"
break;
case 16: /* rule: '$' TOKEN_CODE */
@@ -1228,7 +1229,7 @@ yyreduce:
{
find_or_add_gram(grams, "").eofs.push_back((yyvsp[0].semact));
}
#line 1232 "src/parse/parser.cc"
#line 1233 "src/parse/parser.cc"
break;
case 17: /* rule: TOKEN_CLIST trailexpr ccode */
@@ -1239,7 +1240,7 @@ yyreduce:
}
ast.temp_condlist.clear();
}
#line 1243 "src/parse/parser.cc"
#line 1244 "src/parse/parser.cc"
break;
case 18: /* rule: TOKEN_CLIST '*' ccode */
@@ -1250,7 +1251,7 @@ yyreduce:
}
ast.temp_condlist.clear();
}
#line 1254 "src/parse/parser.cc"
#line 1255 "src/parse/parser.cc"
break;
case 19: /* rule: TOKEN_CLIST '$' ccode */
@@ -1261,7 +1262,7 @@ yyreduce:
}
ast.temp_condlist.clear();
}
#line 1265 "src/parse/parser.cc"
#line 1266 "src/parse/parser.cc"
break;
case 20: /* rule: TOKEN_CSETUP TOKEN_CODE */
@@ -1272,7 +1273,7 @@ yyreduce:
}
ast.temp_condlist.clear();
}
#line 1276 "src/parse/parser.cc"
#line 1277 "src/parse/parser.cc"
break;
case 21: /* rule: TOKEN_CZERO ccode */
@@ -1282,7 +1283,7 @@ yyreduce:
find_or_add_gram(grams, "0").rules.push_back(AstRule(r, (yyvsp[0].semact)));
ast.temp_condlist.clear();
}
#line 1286 "src/parse/parser.cc"
#line 1287 "src/parse/parser.cc"
break;
case 23: /* ccode: TOKEN_CNEXT TOKEN_CODE */
@@ -1292,7 +1293,7 @@ yyreduce:
// parser needs to to update condition, but for the rest of the code actions are immutable
const_cast<SemAct*>((yyval.semact))->cond = (yyvsp[-1].cstr);
}
#line 1296 "src/parse/parser.cc"
#line 1297 "src/parse/parser.cc"
break;
case 24: /* ccode: TOKEN_CJUMP */
@@ -1300,43 +1301,44 @@ yyreduce:
{
(yyval.semact) = ast.sem_act(input.tok_loc(), nullptr, (yyvsp[0].cstr), true);
}
#line 1304 "src/parse/parser.cc"
#line 1305 "src/parse/parser.cc"
break;
case 25: /* trailexpr: expr */
#line 158 "../src/parse/parser.ypp"
{ (yyval.regexp) = ast.cap((yyvsp[0].regexp)); }
#line 1310 "src/parse/parser.cc"
{ (yyval.regexp) = ast.cap((yyvsp[0].regexp), CAPTURE_IF_NOT_INVERTED); }
#line 1311 "src/parse/parser.cc"
break;
case 26: /* trailexpr: expr '/' expr */
#line 159 "../src/parse/parser.ypp"
{
(yyval.regexp) = ast.cat(ast.cap((yyvsp[-2].regexp)), ast.cat(ast.tag(input.tok_loc(), nullptr, false), (yyvsp[0].regexp)));
(yyval.regexp) = ast.cat(ast.cap((yyvsp[-2].regexp), CAPTURE_IF_NOT_INVERTED),
ast.cat(ast.tag(input.tok_loc(), nullptr, false), (yyvsp[0].regexp)));
}
#line 1318 "src/parse/parser.cc"
#line 1320 "src/parse/parser.cc"
break;
case 28: /* expr: expr '|' diff */
#line 165 "../src/parse/parser.ypp"
#line 166 "../src/parse/parser.ypp"
{ (yyval.regexp) = ast.alt((yyvsp[-2].regexp), (yyvsp[0].regexp)); }
#line 1324 "src/parse/parser.cc"
#line 1326 "src/parse/parser.cc"
break;
case 30: /* diff: diff '\\' term */
#line 170 "../src/parse/parser.ypp"
#line 171 "../src/parse/parser.ypp"
{ (yyval.regexp) = ast.diff((yyvsp[-2].regexp), (yyvsp[0].regexp)); }
#line 1330 "src/parse/parser.cc"
#line 1332 "src/parse/parser.cc"
break;
case 32: /* term: factor term */
#line 176 "../src/parse/parser.ypp"
#line 177 "../src/parse/parser.ypp"
{ (yyval.regexp) = ast.cat((yyvsp[-1].regexp), (yyvsp[0].regexp)); }
#line 1336 "src/parse/parser.cc"
#line 1338 "src/parse/parser.cc"
break;
case 34: /* factor: primary closes */
#line 181 "../src/parse/parser.ypp"
#line 182 "../src/parse/parser.ypp"
{
switch((yyvsp[0].op)) {
case '*':
@@ -1350,69 +1352,69 @@ yyreduce:
break;
}
}
#line 1354 "src/parse/parser.cc"
#line 1356 "src/parse/parser.cc"
break;
case 35: /* factor: primary TOKEN_CLOSESIZE */
#line 194 "../src/parse/parser.ypp"
#line 195 "../src/parse/parser.ypp"
{
(yyval.regexp) = ast.iter((yyvsp[-1].regexp), (yyvsp[0].bounds).min, (yyvsp[0].bounds).max);
}
#line 1362 "src/parse/parser.cc"
#line 1364 "src/parse/parser.cc"
break;
case 37: /* closes: closes close */
#line 201 "../src/parse/parser.ypp"
#line 202 "../src/parse/parser.ypp"
{ (yyval.op) = ((yyvsp[-1].op) == (yyvsp[0].op)) ? (yyvsp[-1].op) : '*'; }
#line 1368 "src/parse/parser.cc"
#line 1370 "src/parse/parser.cc"
break;
case 38: /* close: '*' */
#line 205 "../src/parse/parser.ypp"
#line 206 "../src/parse/parser.ypp"
{ (yyval.op) = '*'; }
#line 1374 "src/parse/parser.cc"
#line 1376 "src/parse/parser.cc"
break;
case 39: /* close: '+' */
#line 206 "../src/parse/parser.ypp"
#line 207 "../src/parse/parser.ypp"
{ (yyval.op) = '+'; }
#line 1380 "src/parse/parser.cc"
#line 1382 "src/parse/parser.cc"
break;
case 40: /* close: '?' */
#line 207 "../src/parse/parser.ypp"
#line 208 "../src/parse/parser.ypp"
{ (yyval.op) = '?'; }
#line 1386 "src/parse/parser.cc"
#line 1388 "src/parse/parser.cc"
break;
case 42: /* primary: TOKEN_ID */
#line 212 "../src/parse/parser.ypp"
#line 213 "../src/parse/parser.ypp"
{
(yyval.regexp) = find_def(opts.symtab, (yyvsp[0].cstr));
if ((yyval.regexp) == nullptr) {
input.error_at_tok("undefined symbol '%s'", (yyvsp[0].cstr));
YYABORT;
} else if (Ast::needs_wrap((yyval.regexp))) {
(yyval.regexp) = ast.ref((yyval.regexp));
(yyval.regexp) = ast.cap((yyval.regexp), NO_CAPTURE);
}
}
#line 1400 "src/parse/parser.cc"
#line 1402 "src/parse/parser.cc"
break;
case 43: /* primary: '(' expr ')' */
#line 221 "../src/parse/parser.ypp"
{ (yyval.regexp) = ast.cap((yyvsp[-1].regexp)); }
#line 1406 "src/parse/parser.cc"
break;
case 44: /* primary: '(' '?' expr ')' */
#line 222 "../src/parse/parser.ypp"
{ (yyval.regexp) = ast.ref((yyvsp[-1].regexp)); }
#line 1412 "src/parse/parser.cc"
{ (yyval.regexp) = ast.cap((yyvsp[-1].regexp), CAPTURE_IF_NOT_INVERTED); }
#line 1408 "src/parse/parser.cc"
break;
case 44: /* primary: '(' '!' expr ')' */
#line 223 "../src/parse/parser.ypp"
{ (yyval.regexp) = ast.cap((yyvsp[-1].regexp), CAPTURE_IF_INVERTED); }
#line 1414 "src/parse/parser.cc"
break;
#line 1416 "src/parse/parser.cc"
#line 1418 "src/parse/parser.cc"
default: break;
}
@@ -1605,7 +1607,7 @@ yyreturnlab:
return yyresult;
}
#line 225 "../src/parse/parser.ypp"
#line 226 "../src/parse/parser.ypp"
#pragma GCC diagnostic pop
+1 -1
View File
@@ -52,7 +52,7 @@ extern int yydebug;
namespace re2c {
struct AstNode;
struct SemAct;
};
}
#line 58 "src/parse/parser.h"
+2 -1
View File
@@ -12,5 +12,6 @@ cd $builddir
--enable-debug \
--enable-libs \
--host i686-w64-mingw32 \
&& make -j$(nproc)
&& make -j$(nproc) \
&& ../build/copy_wine_libs_on_nixos.sh
cd ..
+2 -1
View File
@@ -16,5 +16,6 @@ cd $builddir
--enable-debug \
--enable-libs \
--host i686-w64-mingw32 \
&& make -j$(nproc) LIBTOOL="slibtool"
&& make -j$(nproc) LIBTOOL="slibtool" \
&& ../build/copy_wine_libs_on_nixos.sh
cd ..
+2 -1
View File
@@ -12,5 +12,6 @@ cmake .. \
-DBUILD_SHARED_LIBS=no \
-DCMAKE_EXE_LINKER_FLAGS="-static -static-libstdc++ -static-libgcc" \
-DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-cross-mingw32-linux.cmake \
&& cmake --build . -j$(nproc)
&& cmake --build . -j$(nproc) \
&& ../build/copy_wine_libs_on_nixos.sh
cd ..
+19
View File
@@ -0,0 +1,19 @@
#!/bin/sh
# On NixOS, Wine cannot find DLLs by their absolute paths in /nix/store,
# so find and copy them in the same directory with re2c.exe.
uname -a | grep -q NixOS || exit 0
test -e re2c.exe || \
{ echo "$0 must be ran from the build directory containing re2c.exe"; exit 1; }
nix_wine="$(nix-build --no-link '<nixpkgs>' -A wine)"
nix_mcfgthreads="$(nix-build --no-link '<nixpkgs>' -A pkgsCross.mingw32.windows.mcfgthreads)"
uname -a | grep -q NixOS && (
cp -f "$nix_mcfgthreads/bin/mcfgthread"*".dll" .
cp -f "$nix_wine/lib/wine/i386-windows/win32u.dll" .
cp -f "$nix_wine/lib/wine/i386-windows/user32.dll" .
cp -f "$nix_wine/lib/wine/i386-windows/gdi32.dll" .
)
+3 -2
View File
@@ -1,4 +1,4 @@
AC_INIT([re2c],[3.0],[re2c-general@lists.sourceforge.net])
AC_INIT([re2c],[3.1],[re2c-general@lists.sourceforge.net])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([foreign subdir-objects dist-xz dist-lzip no-dist-gzip])
AM_SILENT_RULES([yes])
@@ -15,7 +15,8 @@ AC_SUBST(PACKAGE_RELEASE, ${PACKAGE_RELEASE:-1})
AM_PATH_PYTHON([3.7])
# without this, --std=c++98 disables POSIX functions on Cygwin
# without this, --std=c++11 disables POSIX functions on Cygwin and NetBSD
# (alternatively we could use -std=gnu++11, as CMake does)
AC_USE_SYSTEM_EXTENSIONS
@@ -250,6 +250,10 @@
Specifies the minimum amount of indentation to use. The default value is
zero. The value should be a non-negative integer number.
``re2c:invert-captures``
Same as the ``--invert-captures`` option, but can be configured on per-block
basis.
``re2c:label:prefix``, ``re2c:labelprefix``
Specifies the prefix used for DFA state labels. The default is ``yy``.
@@ -274,6 +278,10 @@
in storable state mode (enabled with ``re2c:state:nextlabel``). The default
is ``yyNext``.
``re2c:leftmost-captures``
Same as the ``--leftmost-captures`` option, but can be configured on
per-block basis.
``re2c:lookahead``, ``re2c:flags:lookahead``
Deprecated (see the deprecated ``--no-lookahead`` option).
+8
View File
@@ -89,10 +89,18 @@
With ``utf8`` re2c handles input as UTF8-encoded and recognizes multibyte
characters.
``--invert-captures``
Invert the meaning of capturing and non-capturing groups. By default
``(...)`` is capturing and ``(! ...)`` is non-capturing. With this option
``(! ...)`` is capturing and ``(...)`` is non-capturing.
``--lang <c | go | rust>``
Specify the output language. Supported languages are C, Go and Rust.
The default is C for re2c, Go for re2go and Rust for re2rust.
``--leftmost-captures``
Enable submatch extraction with leftmost greedy capturing groups.
``--location-format <gnu | msvc>``
Specify location format in messages.
With ``gnu`` locations are printed as 'filename:line:column: ...'.
+19 -7
View File
@@ -23,7 +23,13 @@ re2c uses the following syntax for regular expressions:
* ``R{n,m}`` repetition of ``R`` from ``n`` to ``m`` times
* ``(R)`` just ``R``; parentheses are used to override precedence or for POSIX-style submatch
* ``(R)`` just ``R``; parentheses are used to override precedence.
If submatch extraction is enabled, ``(R)`` is a capturing or a
non-capturing group depending on ``--invert-captures`` option.
* ``(!R)``
If submatch extraction is enabled, ``(!R)`` is a non-capturing or a
capturing group depending on ``--invert-captures`` option.
* ``R S`` concatenation: ``R`` followed by ``S``
@@ -31,14 +37,20 @@ re2c uses the following syntax for regular expressions:
* ``R / S`` lookahead: ``R`` followed by ``S``, but ``S`` is not consumed
* ``name`` the regular expression defined as ``name`` (or literal string ``"name"`` in Flex compatibility mode)
* ``name`` the regular expression defined as ``name`` (or literal string
``"name"`` in Flex compatibility mode)
* ``{name}`` the regular expression defined as ``name`` in Flex compatibility mode
* ``{name}`` the regular expression defined as ``name`` in Flex
compatibility mode
* ``@stag`` an *s-tag*: saves the last input position at which ``@stag`` matches in a variable named ``stag``
* ``@stag`` an *s-tag*: saves the last input position at which ``@stag``
matches in a variable named ``stag``
* ``#mtag`` an *m-tag*: saves all input positions at which ``#mtag`` matches in a variable named ``mtag``
* ``#mtag`` an *m-tag*: saves all input positions at which ``#mtag`` matches
in a variable named ``mtag``
Character classes and string literals may contain the following escape sequences:
``\a``, ``\b``, ``\f``, ``\n``, ``\r``, ``\t``, ``\v``, ``\\``, octal escapes ``\ooo`` and hexadecimal escapes ``\xhh``, ``\uhhhh`` and ``\Uhhhhhhhh``.
Character classes and string literals may contain the following escape
sequences: ``\a``, ``\b``, ``\f``, ``\n``, ``\r``, ``\t``, ``\v``, ``\\``,
octal escapes ``\ooo`` and hexadecimal escapes ``\xhh``, ``\uhhhh`` and
``\Uhhhhhhhh``.
+3 -3
View File
@@ -3,7 +3,7 @@
#include "src/parse/ast.h"
namespace re2c {
struct AstNode;
};
}
}
%{
@@ -74,8 +74,8 @@ factor
primary
: TOKEN_REGEXP
| '(' ')' { $$ = ast.cap(ast.nil(NOWHERE)); }
| '(' expr ')' { $$ = ast.cap($2); }
| '(' ')' { $$ = ast.cap(ast.nil(NOWHERE), CAPTURE); }
| '(' expr ')' { $$ = ast.cap($2, CAPTURE); }
;
%%
+2 -2
View File
@@ -66,7 +66,7 @@ void make_one_step(psimctx_t& ctx, uint32_t sym) {
s->clos = NOCLOS;
s->arcidx = 0;
DCHECK(s->status == GorPass::NOPASS && s->active == 0);
DCHECK(s->status == GOR_NOPASS && s->active == 0);
if (s->kind == TnfaState::Kind::RAN) {
for (const Range* r = s->ran; r; r = r->next()) {
@@ -105,7 +105,7 @@ void make_final_step(psimctx_t& ctx) {
s->clos = NOCLOS;
s->arcidx = 0;
DCHECK(s->status == GorPass::NOPASS && s->active == 0);
DCHECK(s->status == GOR_NOPASS && s->active == 0);
if (s->kind == TnfaState::Kind::FIN) {
update_offsets(ctx, *i, NONCORE);
+2 -2
View File
@@ -87,7 +87,7 @@ void make_step(pzsimctx_t& ctx, uint32_t sym) {
s->clos = NOCLOS;
s->arcidx = 0;
DCHECK(s->status == GorPass::NOPASS && s->active == 0);
DCHECK(s->status == GOR_NOPASS && s->active == 0);
if (s->kind == TnfaState::Kind::RAN) {
for (const Range* r = s->ran; r; r = r->next()) {
@@ -113,7 +113,7 @@ void make_final_step(pzsimctx_t& ctx) {
s->clos = NOCLOS;
s->arcidx = 0;
DCHECK(s->status == GorPass::NOPASS && s->active == 0);
DCHECK(s->status == GOR_NOPASS && s->active == 0);
if (s->kind == TnfaState::Kind::FIN) {
ctx.marker = ctx.cursor;
+2 -2
View File
@@ -1,10 +1,10 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
# checks for which there are no scripts yet
echo 'RUNME: cppcheck --enable=all --inconclusive --std=posix --quiet --force -I. src/'
echo "RUNME: uselex `find <objdir> -type f -name '*.o'`"
echo 'RUNME: uselex `find <objdir> -type f -name '"'*.o'"'`'
echo 'RUNME: configure CFLAGS="-ffunction-sections -fdata-sections" LDFLAGS="-Wl,--gc-sections -Wl,--print-gc-sections"'
if [[ $# -ne 2 ]]; then
+2 -12
View File
@@ -31,13 +31,9 @@ TOP_BUILDIR = '@top_builddir@'
RE2C_PATTERN = re.compile(r'.*re2c[ \t]*(.*)$')
TYPE_HEADER_PATTERN1 = re.compile(r'--header[ \t]*')
TYPE_HEADER_PATTERN2 = re.compile(r'.*--header[ \t]*([^ \t]*).*')
START_OF_MESSAGE = b'^[a-z0-9_]+([\\\\/]+[a-z0-9_]+)+([.][a-z]+)+[(:]'
FILEPATH = b'^[a-z0-9_]+([\\\\/]+[a-z0-9_]+)+([.][a-z]+)+'
START_OF_LINEDIR = b'^(//|#)line '
FILEPATH_CONTEXT_PATTERN = re.compile(b'('
+ START_OF_MESSAGE
+ b'|'
+ START_OF_LINEDIR
+ b')')
FILEPATH_CONTEXT_PATTERN = re.compile(b'(' + START_OF_LINEDIR + b'|' + FILEPATH + b')')
@dataclass
@@ -361,12 +357,6 @@ def run_test(test):
stem = os.path.splitext(outx)[0]
outy = f'{stem}.{ext}'
# Known failure: on windows overflow-1.re fails due to small stack size.
if os.name == 'nt' and outx.endswith('overflow-1.re'):
if not _ctx.keep_temp_files:
remove(outx, outy)
return 0, 0, 0
# Prepare re2c flags
switches = head
switches = switches.replace('re2go', 're2c --lang go')
+1
View File
@@ -4,6 +4,7 @@
#include <stdint.h>
#include <string.h>
#include "src/constants.h"
#include "src/dfa/tcmd.h"
#include "src/msg/location.h"
#include "src/util/allocator.h"
+1 -1
View File
@@ -746,7 +746,7 @@ static void render(RenderContext& rctx, const Code* code) {
}
}
uint32_t write_converting_newlines(const std::string& str, FILE* f) {
static uint32_t write_converting_newlines(const std::string& str, FILE* f) {
const char* s = str.c_str(), *e = s + str.length();
uint32_t lines = 0;
+9
View File
@@ -53,6 +53,15 @@ enum class Minimization: uint32_t {
MOORE
};
// Whether a group is capturing or non-capturng depending on --invert-capture option and
// `re2c:invert_captures` configuration.
enum CaptureMode : uint8_t {
NO_CAPTURE = 0, // 00
CAPTURE_IF_INVERTED = 1, // 01
CAPTURE_IF_NOT_INVERTED = 2, // 10
CAPTURE = CAPTURE_IF_INVERTED | CAPTURE_IF_NOT_INVERTED
};
// Algorithm for construction of POSIX precedence table for disambiguation.
// Complexity estimates are in terms of TNFA size (m) and the number of tags (t).
enum class PosixPrectable: uint32_t {
+7 -7
View File
@@ -65,13 +65,13 @@ void closure_posix_gor1(ctx_t& ctx) {
// 1st pass: depth-first postorder traversal of admissible subgraph
for (; !topsort.empty(); ) {
TnfaState* q = topsort.back();
if (q->status == GorPass::LINEAR) {
if (q->status == GOR_LINEAR) {
topsort.pop_back();
} else {
q->status = GorPass::TOPSORT;
q->status = GOR_TOPSORT;
DINCCOUNT_CLSCANS(ctx);
if (!scan(ctx, q, false)) {
q->status = GorPass::LINEAR;
q->status = GOR_LINEAR;
topsort.pop_back();
linear.push_back(q);
}
@@ -88,7 +88,7 @@ void closure_posix_gor1(ctx_t& ctx) {
DINCCOUNT_CLSCANS(ctx);
scan(ctx, q, true);
}
q->status = GorPass::NOPASS;
q->status = GOR_NOPASS;
}
}
}
@@ -154,7 +154,7 @@ bool relax_gor1(ctx_t& ctx, const typename ctx_t::conf_t& x) {
const uint32_t idx = q->clos;
int32_t p1, p2;
if (q->status == GorPass::TOPSORT) {
if (q->status == GOR_TOPSORT) {
return false;
}
@@ -167,7 +167,7 @@ bool relax_gor1(ctx_t& ctx, const typename ctx_t::conf_t& x) {
return false;
}
if (q->status == GorPass::NOPASS) {
if (q->status == GOR_NOPASS) {
ctx.gor1_topsort.push_back(q);
q->arcidx = 0;
return true;
@@ -181,7 +181,7 @@ template<>
inline void closure_cleanup<pdetctx_t>(TnfaState* q) {
q->clos = NOCLOS;
q->arcidx = 0;
DCHECK(q->status == GorPass::NOPASS && q->active == 0);
DCHECK(q->status == GOR_NOPASS && q->active == 0);
}
} // namespace re2c
+1 -1
View File
@@ -223,7 +223,7 @@ LOCAL_NODISCARD(Ret compile(int, char* argv[])) {
out_alc.clear(); // Release memory used for codegen.
CHECK_RET(input.gen_dep_file());
CHECK_RET(input.gen_dep_file(output.total_opts->header_file));
if (globopts.verbose) fprintf(stderr, "re2c: success\n");
return Ret::OK;
+9 -7
View File
@@ -15,11 +15,13 @@ namespace re2c {
struct clos_t;
// Passes of Goldberg-Radzik shortest path algorithm.
enum class GorPass: uint32_t {
NOPASS = 0u,
TOPSORT = 1u,
LINEAR = 2u
};
//
// This cannot be a `enum class` because it is used in a bitfield, which triggers compiler
// warnings and errors on some toolchains, see https://github.com/skvadrik/re2c/issues/446.
// It cannot be a plain `enum` defaulting to `int` as well because of -Wsigned-enum-bitfield.
constexpr uint32_t GOR_NOPASS = 0u;
constexpr uint32_t GOR_TOPSORT = 1u;
constexpr uint32_t GOR_LINEAR = 2u;
static constexpr uint32_t NOCLOS = ~0u;
@@ -33,7 +35,7 @@ struct TnfaState {
tag_info_t tag; // tag information (number and sign, only for TAG states)
};
uint32_t clos; // GOR1: closure item for this stack
GorPass status : 2; // GOR1: status (values 0, 1, 2)
uint32_t status : 2; // GOR1: status (values 0, 1, 2)
uint32_t arcidx : 2; // GOR1: index of the next transtion (maximum out-dergee is 2)
uint32_t active : 1; // GOR1: if the state is on stack (boolean)
uint32_t indeg : 27; // GOR1: in-degree (we are unlikely to have more than 2^27 states)
@@ -85,7 +87,7 @@ struct Tnfa {
s->kind = kind;
s->rule = rule;
s->clos = NOCLOS;
s->status = GorPass::NOPASS;
s->status = GOR_NOPASS;
s->arcidx = 0;
s->active = 0;
s->indeg = 0;
+1
View File
@@ -167,6 +167,7 @@ class Input;
MUTOPT(bool, tags_posix_syntax, false) \
MUTOPT(bool, tags_posix_semantics, false) \
MUTOPT(std::string, tags_prefix, "yyt") \
MUTOPT(bool, invert_captures, false) \
/* labels */ \
MUTOPT(std::string, label_fill, "yyFillLabel") \
MUTOPT(std::string, label_loop, "") \
+1
View File
@@ -160,6 +160,7 @@ opt_long: /*!local:re2c
"case-inverted" end { opts.set_case_inverted(true); goto opt; }
"tags" end { opts.set_tags(true); goto opt; }
"no-unsafe" end { opts.set_unsafe(false); goto opt; }
"invert-captures" end { opts.set_invert_captures(true); goto opt; }
"ebcdic" | "ecb" end { opts.set_encoding(Enc::Type::EBCDIC, true); goto opt; }
"utf32" | "unicode" end { opts.set_encoding(Enc::Type::UTF32, true); goto opt; }
+14 -20
View File
@@ -58,7 +58,7 @@ Ast::Ast(AstAllocator& ast_alc, OutAllocator& out_alc)
temp_blockname(),
blocks() {}
AstNode* Ast::make(const loc_t& loc, AstKind kind, bool has_caps) {
AstNode* Ast::make(const loc_t& loc, AstKind kind, uint8_t has_caps) {
AstNode* p = ast_alc.alloct<AstNode>(1);
p->kind = kind;
p->loc = loc;
@@ -67,11 +67,11 @@ AstNode* Ast::make(const loc_t& loc, AstKind kind, bool has_caps) {
}
const AstNode* Ast::nil(const loc_t& loc) {
return make(loc, AstKind::NIL, false);
return make(loc, AstKind::NIL, NO_CAPTURE);
}
const AstNode* Ast::str(const loc_t& loc, bool icase) {
AstNode* ast = make(loc, AstKind::STR, false);
AstNode* ast = make(loc, AstKind::STR, NO_CAPTURE);
ast->str.chars.init(temp_chars.data(), temp_chars.size(), ast_alc);
ast->str.icase = icase;
temp_chars.clear();
@@ -79,7 +79,7 @@ const AstNode* Ast::str(const loc_t& loc, bool icase) {
}
const AstNode* Ast::cls(const loc_t& loc, bool negated) {
AstNode* ast = make(loc, AstKind::CLS, false);
AstNode* ast = make(loc, AstKind::CLS, NO_CAPTURE);
ast->cls.ranges.init(temp_ranges.data(), temp_ranges.size(), ast_alc);
ast->cls.negated = negated;
temp_ranges.clear();
@@ -87,17 +87,17 @@ const AstNode* Ast::cls(const loc_t& loc, bool negated) {
}
const AstNode* Ast::dot(const loc_t& loc) {
return make(loc, AstKind::DOT, false);
return make(loc, AstKind::DOT, NO_CAPTURE);
}
const AstNode* Ast::def(const loc_t& loc) {
return make(loc, AstKind::DEF, false);
return make(loc, AstKind::DEF, NO_CAPTURE);
}
const AstNode* Ast::alt(const AstNode* a1, const AstNode* a2) {
if (!a1) return a2;
if (!a2) return a1;
AstNode* ast = make(a1->loc, AstKind::ALT, a1->has_caps || a2->has_caps);
AstNode* ast = make(a1->loc, AstKind::ALT, a1->has_caps | a2->has_caps);
ast->alt.ast1 = a1;
ast->alt.ast2 = a2;
return ast;
@@ -106,7 +106,7 @@ const AstNode* Ast::alt(const AstNode* a1, const AstNode* a2) {
const AstNode* Ast::cat(const AstNode* a1, const AstNode* a2) {
if (!a1) return a2;
if (!a2) return a1;
AstNode* ast = make(a1->loc, AstKind::CAT, a1->has_caps || a2->has_caps);
AstNode* ast = make(a1->loc, AstKind::CAT, a1->has_caps | a2->has_caps);
ast->cat.ast1 = a1;
ast->cat.ast2 = a2;
return ast;
@@ -122,28 +122,23 @@ const AstNode* Ast::iter(const AstNode* a, uint32_t n, uint32_t m) {
}
const AstNode* Ast::diff(const AstNode* a1, const AstNode* a2) {
AstNode* ast = make(a1->loc, AstKind::DIFF, a1->has_caps || a2->has_caps);
AstNode* ast = make(a1->loc, AstKind::DIFF, a1->has_caps | a2->has_caps);
ast->cat.ast1 = a1;
ast->cat.ast2 = a2;
return ast;
}
const AstNode* Ast::tag(const loc_t& loc, const char* n, bool h) {
AstNode* ast = make(loc, AstKind::TAG, false);
AstNode* ast = make(loc, AstKind::TAG, NO_CAPTURE);
ast->tag.name = n;
ast->tag.history = h;
return ast;
}
const AstNode* Ast::cap(const AstNode* a) {
AstNode* ast = make(a->loc, AstKind::CAP, true);
ast->cap = a;
return ast;
}
const AstNode* Ast::ref(const AstNode* a) {
AstNode* ast = make(a->loc, AstKind::REF, a->has_caps);
ast->ref = a;
const AstNode* Ast::cap(const AstNode* a, CaptureMode mode) {
AstNode* ast = make(a->loc, AstKind::CAP, mode | a->has_caps);
ast->cap.ast = a;
ast->cap.mode = mode;
return ast;
}
@@ -180,7 +175,6 @@ bool Ast::needs_wrap(const AstNode* a) {
case AstKind::ALT:
case AstKind::CAT:
case AstKind::DIFF:
case AstKind::REF:
return true;
}
return false; // unreachable
+11 -8
View File
@@ -32,8 +32,7 @@ enum class AstKind: uint32_t {
ITER, // generalized repetition of two nodes: x{n,m} or x{n,} or x{n} or x* or x+
DIFF, // difference of two node (only applies to character classes)
TAG, // a tag, like @t (s-tag, single-valued tag) or #t (m-tag. multi-valued tag)
CAP, // capturing group (submatch group)
REF // non-capturing group
CAP // capturing or non-capturing group
};
// A character (symbol) in the abstract syntax tree.
@@ -92,11 +91,16 @@ struct AstNode {
const char* name;
bool history;
} tag;
const AstNode* cap;
const AstNode* ref;
struct {
const AstNode* ast;
CaptureMode mode;
} cap;
};
loc_t loc;
bool has_caps; // whether this AST has nested capturing groups
// Whether this AST has nested capturing groups (a combination of `CaptureMode` bit flags
// accumulated from the nested regexp).
uint8_t has_caps;
};
// Semanic action associated with an AST for a regular expression.
@@ -166,7 +170,7 @@ class Ast {
// survive until the main codegen pass (e.g. semantic actions, condition names, tag names).
OutAllocator& out_alc;
AstNode* make(const loc_t& loc, AstKind kind, bool has_caps);
AstNode* make(const loc_t& loc, AstKind kind, uint8_t has_caps);
public:
// Temporary buffers for constructing character strings and classes in lexer/parser. Generally
@@ -197,8 +201,7 @@ class Ast {
const AstNode* iter(const AstNode* a, uint32_t n, uint32_t m);
const AstNode* diff(const AstNode* a1, const AstNode* a2);
const AstNode* tag(const loc_t& loc, const char* n, bool h);
const AstNode* cap(const AstNode* a);
const AstNode* ref(const AstNode* a);
const AstNode* cap(const AstNode* a, CaptureMode mode);
const SemAct* sem_act(const loc_t& loc, const char* text, const char* cond, bool autogen);
// Local and global strings differ in their lifetimes: local ones live during AST construction,
+6 -2
View File
@@ -247,14 +247,18 @@ bool Input::fill(size_t need) {
return true;
}
Ret Input::gen_dep_file() const {
Ret Input::gen_dep_file(const std::string& header) const {
const std::string& fname = globopts->dep_file;
if (fname.empty()) return Ret::OK;
FILE* file = fopen(fname.c_str(), "w");
if (file == nullptr) RET_FAIL(error("cannot open dep file %s", fname.c_str()));
fprintf(file, "%s:", escape_backslashes(globopts->output_file).c_str());
fprintf(file, "%s", escape_backslashes(globopts->output_file).c_str());
if (!header.empty()) {
fprintf(file, " %s", header.c_str());
}
fprintf(file, ":");
for (const std::string& fdep : filedeps) {
fprintf(file, " %s", fdep.c_str());
}
+1 -1
View File
@@ -68,7 +68,7 @@ class Input: private LexerState {
loc_t cur_loc() const;
Ret open(const std::string& filename, const std::string* parent) NODISCARD;
Ret include(const std::string& filename, uint8_t* at) NODISCARD;
Ret gen_dep_file() const NODISCARD;
Ret gen_dep_file(const std::string& header) const NODISCARD;
Ret lex_program(Output& out, std::string& block_name, InputBlock& kind) NODISCARD;
Ret lex_block(YYSTYPE* yylval, Ast& ast, int& token) NODISCARD;
Ret lex_conf(Opt& opts) NODISCARD;
+14 -2
View File
@@ -428,7 +428,7 @@ scan:
RET_TOK(TOKEN_REGEXP);
}
[*+?()|;/\\=$] { RET_TOK(*tok); }
[*+?!()|;/\\=$] { RET_TOK(*tok); }
"{" [0-9]+ "}" {
if (!s_to_u32_unsafe (tok + 1, cur - 1, yylval->bounds.min)) {
@@ -532,7 +532,19 @@ scan:
goto scan;
}
* { RET_FAIL(error_at_tok("unexpected character: '%c'", *tok)); }
* {
if (globopts->flex_syntax && globopts->input_encoding == Enc::Type::UTF8) {
// Try to lex this as a raw UTF-8 code point (not captured by the `name` rule above
// because it is restricted to alphanumeric ASCII characters and underscore).
--cur;
uint32_t c;
CHECK_RET(lex_cls_chr(c));
ast.temp_chars.push_back({c, tok_loc()});
yylval->regexp = ast.str(tok_loc(), false);
RET_TOK(TOKEN_REGEXP);
}
RET_FAIL(error_at_tok("unexpected character: '%c'", *tok));
}
*/
}
+7 -1
View File
@@ -80,7 +80,12 @@ Ret Input::lex_conf(Opt& opts) {
"yyfill:parameter" { RET_CONF_BOOL(fill_param_enable); }
"yyfill:check" { RET_CONF_BOOL(fill_check); }
"flags:"? "tags" | "flags:T" { RET_CONF_BOOL(tags); }
"flags:"? "tags" | "flags:T" { RET_CONF_BOOL(tags); }
"flags:"? "leftmost-captures" {
CHECK_RET(lex_conf_bool(b));
opts.set_tags_posix_syntax(b);
return Ret::OK;
}
"flags:"? "posix-captures" | "flags:P" {
CHECK_RET(lex_conf_bool(b));
opts.set_tags_posix_syntax(b);
@@ -89,6 +94,7 @@ Ret Input::lex_conf(Opt& opts) {
}
"tags:prefix" { RET_CONF_STR(tags_prefix); }
"tags:expression" { RET_CONF_STR(tags_expression); }
"invert-captures" { RET_CONF_BOOL(invert_captures); }
"define:YYBACKUP" { RET_CONF_STR(api_backup); }
"define:YYBACKUPCTX" { RET_CONF_STR(api_backup_ctx); }
+7 -6
View File
@@ -4,7 +4,7 @@
namespace re2c {
struct AstNode;
struct SemAct;
};
}
}
%{
@@ -155,9 +155,10 @@ ccode
};
trailexpr
: expr { $$ = ast.cap($1); }
: expr { $$ = ast.cap($1, CAPTURE_IF_NOT_INVERTED); }
| expr '/' expr {
$$ = ast.cat(ast.cap($1), ast.cat(ast.tag(input.tok_loc(), nullptr, false), $3));
$$ = ast.cat(ast.cap($1, CAPTURE_IF_NOT_INVERTED),
ast.cat(ast.tag(input.tok_loc(), nullptr, false), $3));
};
expr
@@ -215,11 +216,11 @@ primary
input.error_at_tok("undefined symbol '%s'", $1);
YYABORT;
} else if (Ast::needs_wrap($$)) {
$$ = ast.ref($$);
$$ = ast.cap($$, NO_CAPTURE);
}
}
| '(' expr ')' { $$ = ast.cap($2); } // capturing group (in POSIX mode)
| '(' '?' expr ')' { $$ = ast.ref($3); } // non-capturing group
| '(' expr ')' { $$ = ast.cap($2, CAPTURE_IF_NOT_INVERTED); }
| '(' '!' expr ')' { $$ = ast.cap($3, CAPTURE_IF_INVERTED); }
;
%%
+28 -34
View File
@@ -83,6 +83,15 @@ LOCAL_NODISCARD(Regexp* fictive_tags(RESpec& spec, int32_t height)) {
return re_cat(spec, t1, t2);
}
LOCAL_NODISCARD(bool is_capture_mode(uint8_t mode, const opt_t* opts)) {
return mode == CAPTURE ||
mode == (opts->invert_captures ? CAPTURE_IF_INVERTED : CAPTURE_IF_NOT_INVERTED);
}
LOCAL_NODISCARD(bool is_capture(const AstNode* a, const opt_t* opts)) {
return a->kind == AstKind::CAP && is_capture_mode(a->cap.mode, opts);
}
LOCAL_NODISCARD(Regexp* capture_tags(
RESpec& spec, DfsAstToRe& x, bool orbit, const AstNode** psub, size_t* pncap)) {
std::vector<Tag>& tags = spec.tags;
@@ -90,14 +99,14 @@ LOCAL_NODISCARD(Regexp* capture_tags(
size_t ncap = *pncap, lcap = ncap;
const AstNode* ast = *psub;
if (ast->kind == AstKind::CAP) {
if (is_capture(ast, spec.opts)) {
// save the range of repeated captures and collapse them: (...(R)...) -> (R)
for (ast = ast->cap; ast && ast->kind == AstKind::CAP; ast = ast->cap) {
for (ast = ast->cap.ast; ast && is_capture(ast, spec.opts); ast = ast->cap.ast) {
++ncap;
}
// dereference to avoid future check for non-parenthesized rerefences
if (ast->kind == AstKind::REF) {
ast = ast->ref;
if (ast->kind == AstKind::CAP) { // non-capturing group
ast = ast->cap.ast;
}
*psub = ast;
}
@@ -116,12 +125,12 @@ LOCAL_NODISCARD(Regexp* capture_tags(
LOCAL_NODISCARD(Regexp* structural_tags(
RESpec& spec, DfsAstToRe& x, const AstNode* sub, size_t* pncap)) {
if (sub->kind == AstKind::CAP) {
if (is_capture(sub, spec.opts)) {
// If this sub-AST is already a capture, no need for structural tags.
} else if (spec.opts->tags_automatic) {
// Full parsing: automatically add tags as if this sub-regexp was a capture.
return capture_tags(spec, x, false, &x.ast, pncap);
} else if (spec.opts->tags_posix_semantics && x.ast->has_caps) {
} else if (spec.opts->tags_posix_semantics && is_capture_mode(x.ast->has_caps, spec.opts)) {
// POSIX submatch extraction: add fictive structural tags.
// See note [POSIX subexpression hierarchy].
return fictive_tags(spec, x.height);
@@ -314,12 +323,8 @@ LOCAL_NODISCARD(Ret diff_to_range(RESpec& spec,
break;
case AstKind::CAP:
if (spec.opts->tags_posix_syntax) goto error;
x.ast = ast->cap; // replace on stack
break;
case AstKind::REF:
x.ast = ast->ref; // replace on stack
if (is_capture(ast, spec.opts) && spec.opts->tags_posix_syntax) goto error;
x.ast = ast->cap.ast; // replace on stack
break;
case AstKind::DIFF:
@@ -380,7 +385,7 @@ LOCAL_NODISCARD(Ret ast_to_re(RESpec& spec,
const AstNode* ast = x.ast;
if (ast->kind != AstKind::CAP && ast->kind != AstKind::REF) ++x.height;
if (ast->kind != AstKind::CAP) ++x.height;
switch (ast->kind) {
case AstKind::NIL:
@@ -432,27 +437,17 @@ LOCAL_NODISCARD(Ret ast_to_re(RESpec& spec,
case AstKind::CAP:
if (!opts->tags_posix_syntax) { // ordinary group, replace with subexpr on stack
x.ast = ast->cap;
} else { // capturing group
x.ast = ast->cap.ast;
} else { // capturing or non-capturing group
if (x.succ == 0) { // 1st visit: push successor
++x.succ;
x.re1 = capture_tags(spec, x, false, &ast, pncap);
stack.emplace_back(ast, x.height, x.in_iter);
} else { // 2nd visit: return
re = insert_between_tags(spec, x.re1, re);
stack.pop_back();
}
}
break;
case AstKind::REF:
if (!opts->tags_posix_semantics) { // ordinary group, replace with subexpr on stack
x.ast = ast->ref;
} else { // non-capturing group
if (x.succ == 0) { // 1st visit: push successor
++x.succ;
x.re1 = structural_tags(spec, x, ast->ref, pncap);
stack.emplace_back(ast->ref, x.height, x.in_iter);
if (is_capture(ast, opts)) {
x.re1 = capture_tags(spec, x, false, &ast, pncap);
stack.emplace_back(ast, x.height, x.in_iter);
} else {
x.re1 = structural_tags(spec, x, ast->cap.ast, pncap);
stack.emplace_back(ast->cap.ast, x.height, x.in_iter);
}
} else { // 2nd visit: return
re = insert_between_tags(spec, x.re1, re);
stack.pop_back();
@@ -500,8 +495,7 @@ LOCAL_NODISCARD(Ret ast_to_re(RESpec& spec,
++x.succ;
const uint32_t m = ast->iter.max;
ast = ast->iter.ast;
if ((opts->tags_posix_semantics && ast->kind == AstKind::CAP)
|| opts->tags_automatic) {
if ((opts->tags_posix_semantics && is_capture(ast, opts)) || opts->tags_automatic) {
x.re1 = capture_tags(spec, x, m > 1, &ast, pncap);
}
if (m > 0) {
-16
View File
@@ -1,19 +1,3 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-macros"
// See https://github.com/skvadrik/re2c/pull/376
// _POSIX_SOURCE is needed for fdopen on Cygwin.
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE 1
#endif
// However the above definition of _POSIX_SOURCE breaks the build on FreeBSD,
// which also needs _POSIX_C_SOURCE to be defined.
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#endif
#pragma GCC diagnostic pop
#include "config.h"
#include <time.h>
#include "src/util/file_utils.h"
+2 -2
View File
@@ -1,5 +1,5 @@
/* Generated by re2c */
// re2c $INPUT -o $OUTPUT -i --leftmost-captures --input custom
// re2c $INPUT -o $OUTPUT -i --input custom
// POSIX and leftmost policies produce different results.
#include <stddef.h>
#include <stdio.h>
@@ -66,4 +66,4 @@ int main(int argc, char **argv)
}
return 0;
}
captures/diff1_leftmost.re:24:22: warning: rule matches empty string [-Wmatch-empty-string]
captures/diff1_leftmost.re:25:22: warning: rule matches empty string [-Wmatch-empty-string]
+2 -1
View File
@@ -1,4 +1,4 @@
// re2c $INPUT -o $OUTPUT -i --leftmost-captures --input custom
// re2c $INPUT -o $OUTPUT -i --input custom
// POSIX and leftmost policies produce different results.
#include <stddef.h>
#include <stdio.h>
@@ -19,6 +19,7 @@ static void lex(const char *s)
/*!re2c
re2c:define:YYCTYPE = char;
re2c:yyfill:enable = 0;
re2c:leftmost-captures = 1;
* { printf("error\n"); return; }
("a" | "aa")* {
+2 -2
View File
@@ -1,5 +1,5 @@
/* Generated by re2c */
// re2c $INPUT -o $OUTPUT -i --posix-captures --input custom
// re2c $INPUT -o $OUTPUT -i --input custom
// POSIX and leftmost policies produce different results.
#include <stddef.h>
#include <stdio.h>
@@ -75,4 +75,4 @@ int main(int argc, char **argv)
}
return 0;
}
captures/diff1_posix.re:24:22: warning: rule matches empty string [-Wmatch-empty-string]
captures/diff1_posix.re:25:22: warning: rule matches empty string [-Wmatch-empty-string]
+2 -1
View File
@@ -1,4 +1,4 @@
// re2c $INPUT -o $OUTPUT -i --posix-captures --input custom
// re2c $INPUT -o $OUTPUT -i --input custom
// POSIX and leftmost policies produce different results.
#include <stddef.h>
#include <stdio.h>
@@ -19,6 +19,7 @@ static void lex(const char *s)
/*!re2c
re2c:define:YYCTYPE = char;
re2c:yyfill:enable = 0;
re2c:posix-captures = 1;
* { printf("error\n"); return; }
("a" | "aa")* {
@@ -1,41 +1,41 @@
// re2c $INPUT -o $OUTPUT -i --leftmost-captures
/*!local:re2c
x = (?"a");
x = (!"a");
x x {}
* {}
*/
/*!local:re2c
x = (?"a" "b");
x = (!"a" "b");
x x {}
* {}
*/
/*!local:re2c
x = (?"a" ("b"));
x = (!"a" ("b"));
x x {}
* {}
*/
/*!local:re2c
x = (?"a" | "b");
x = (!"a" | "b");
x x {}
* {}
*/
/*!local:re2c
x = (?"a" | ("b"));
x = (!"a" | ("b"));
x x {}
* {}
*/
/*!local:re2c
x = (?"a" | "aa");
x = (!"a" | "aa");
x*x* {}
*/
/*!local:re2c
x = (?"a" | ("aa"));
x = (!"a" | ("aa"));
x*x* {}
*/
@@ -0,0 +1,241 @@
/* Generated by re2c */
// re2c $INPUT -o $OUTPUT -i --leftmost-captures --invert-captures
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy3;
default: goto yy1;
}
yy1:
++YYCURSOR;
yy2:
{}
yy3:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy4;
default: goto yy2;
}
yy4:
++YYCURSOR;
{}
}
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy8;
default: goto yy6;
}
yy6:
++YYCURSOR;
yy7:
{}
yy8:
yych = *(YYMARKER = ++YYCURSOR);
switch (yych) {
case 'b': goto yy9;
default: goto yy7;
}
yy9:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy11;
default: goto yy10;
}
yy10:
YYCURSOR = YYMARKER;
goto yy7;
yy11:
yych = *++YYCURSOR;
switch (yych) {
case 'b': goto yy12;
default: goto yy10;
}
yy12:
++YYCURSOR;
{}
}
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy16;
default: goto yy14;
}
yy14:
++YYCURSOR;
yy15:
{}
yy16:
yych = *(YYMARKER = ++YYCURSOR);
switch (yych) {
case 'b': goto yy17;
default: goto yy15;
}
yy17:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy19;
default: goto yy18;
}
yy18:
YYCURSOR = YYMARKER;
goto yy15;
yy19:
yych = *++YYCURSOR;
switch (yych) {
case 'b': goto yy20;
default: goto yy18;
}
yy20:
++YYCURSOR;
yynmatch = 2;
yypmatch[0] = YYCURSOR - 3;
yypmatch[1] = YYCURSOR - 2;
yypmatch[2] = YYCURSOR - 1;
yypmatch[3] = YYCURSOR;
{}
}
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
switch (yych) {
case 'a':
case 'b': goto yy24;
default: goto yy22;
}
yy22:
++YYCURSOR;
yy23:
{}
yy24:
yych = *++YYCURSOR;
switch (yych) {
case 'a':
case 'b': goto yy25;
default: goto yy23;
}
yy25:
++YYCURSOR;
{}
}
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy29;
case 'b': goto yy30;
default: goto yy27;
}
yy27:
++YYCURSOR;
yy28:
{}
yy29:
yych = *++YYCURSOR;
switch (yych) {
case 'a':
yyt1 = NULL;
goto yy31;
case 'b':
yyt1 = NULL;
goto yy33;
default: goto yy28;
}
yy30:
yych = *++YYCURSOR;
switch (yych) {
case 'a':
yyt1 = YYCURSOR;
goto yy31;
case 'b':
yyt1 = YYCURSOR;
goto yy33;
default: goto yy28;
}
yy31:
++YYCURSOR;
yyt2 = NULL;
yy32:
yynmatch = 2;
yypmatch[1] = yyt1;
yypmatch[3] = yyt2;
yypmatch[0] = yyt1;
if (yyt1 != NULL) yypmatch[0] -= 1;
yypmatch[2] = yyt2;
if (yyt2 != NULL) yypmatch[2] -= 1;
{}
yy33:
++YYCURSOR;
yyt2 = YYCURSOR;
goto yy32;
}
{
YYCTYPE yych;
goto yy34;
yy35:
++YYCURSOR;
yy34:
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy35;
default: goto yy36;
}
yy36:
{}
}
{
YYCTYPE yych;
goto yy37;
yy38:
++YYCURSOR;
yy37:
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy38;
default:
yyt1 = NULL;
goto yy39;
}
yy39:
yynmatch = 2;
yypmatch[1] = yyt1;
yypmatch[3] = yyt1;
yypmatch[0] = yyt1;
if (yyt1 != NULL) yypmatch[0] -= 2;
yypmatch[2] = yyt1;
if (yyt1 != NULL) yypmatch[2] -= 2;
{}
}
captures/noncapturing/explicit2_leftmost_inverted.re:35:9: warning: rule matches empty string [-Wmatch-empty-string]
captures/noncapturing/explicit2_leftmost_inverted.re:40:9: warning: rule matches empty string [-Wmatch-empty-string]
@@ -0,0 +1,41 @@
// re2c $INPUT -o $OUTPUT -i --leftmost-captures --invert-captures
/*!local:re2c
x = ("a");
x x {}
* {}
*/
/*!local:re2c
x = ("a" "b");
x x {}
* {}
*/
/*!local:re2c
x = ("a" (!"b"));
x x {}
* {}
*/
/*!local:re2c
x = ("a" | "b");
x x {}
* {}
*/
/*!local:re2c
x = ("a" | (!"b"));
x x {}
* {}
*/
/*!local:re2c
x = ("a" | "aa");
x*x* {}
*/
/*!local:re2c
x = ("a" | (!"aa"));
x*x* {}
*/
@@ -1,41 +1,41 @@
// re2c $INPUT -o $OUTPUT -i --posix-captures
/*!local:re2c
x = (?"a");
x = (!"a");
x x {}
* {}
*/
/*!local:re2c
x = (?"a" "b");
x = (!"a" "b");
x x {}
* {}
*/
/*!local:re2c
x = (?"a" ("b"));
x = (!"a" ("b"));
x x {}
* {}
*/
/*!local:re2c
x = (?"a" | "b");
x = (!"a" | "b");
x x {}
* {}
*/
/*!local:re2c
x = (?"a" | ("b"));
x = (!"a" | ("b"));
x x {}
* {}
*/
/*!local:re2c
x = (?"a" | "aa");
x = (!"a" | "aa");
x*x* {}
*/
/*!local:re2c
x = (?"a" | ("aa"));
x = (!"a" | ("aa"));
x*x* {}
*/
@@ -2,40 +2,40 @@
/*!local:re2c
x = "a";
(x)(?x) {}
(x)(!x) {}
* {}
*/
/*!local:re2c
x = "a" "b";
(x)(?x) {}
(x)(!x) {}
* {}
*/
/*!local:re2c
x = "a" ("b");
(x)(?x) {}
(x)(!x) {}
* {}
*/
/*!local:re2c
x = "a" | "b";
(x)(?x) {}
(x)(!x) {}
* {}
*/
/*!local:re2c
x = "a" | ("b");
(x)(?x) {}
(x)(!x) {}
* {}
*/
/*!local:re2c
x = "a" | "aa";
(x)*(?x)* {}
(x)*(!x)* {}
*/
/*!local:re2c
x = "a" | ("aa");
(x)*(?x)* {}
(x)*(!x)* {}
*/
@@ -2,40 +2,40 @@
/*!local:re2c
x = "a";
(x)(?x) {}
(x)(!x) {}
* {}
*/
/*!local:re2c
x = "a" "b";
(x)(?x) {}
(x)(!x) {}
* {}
*/
/*!local:re2c
x = "a" ("b");
(x)(?x) {}
(x)(!x) {}
* {}
*/
/*!local:re2c
x = "a" | "b";
(x)(?x) {}
(x)(!x) {}
* {}
*/
/*!local:re2c
x = "a" | ("b");
(x)(?x) {}
(x)(!x) {}
* {}
*/
/*!local:re2c
x = "a" | "aa";
(x)*(?x)* {}
(x)*(!x)* {}
*/
/*!local:re2c
x = "a" | ("aa");
(x)*(?x)* {}
(x)*(!x)* {}
*/
@@ -0,0 +1,303 @@
/* Generated by re2c */
// re2c $INPUT -o $OUTPUT -i --posix-captures --invert-captures
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy3;
default: goto yy1;
}
yy1:
++YYCURSOR;
yy2:
{}
yy3:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy4;
default: goto yy2;
}
yy4:
++YYCURSOR;
yynmatch = 1;
yypmatch[0] = YYCURSOR - 2;
yypmatch[1] = YYCURSOR - 1;
{}
}
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy8;
default: goto yy6;
}
yy6:
++YYCURSOR;
yy7:
{}
yy8:
yych = *(YYMARKER = ++YYCURSOR);
switch (yych) {
case 'b': goto yy9;
default: goto yy7;
}
yy9:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy11;
default: goto yy10;
}
yy10:
YYCURSOR = YYMARKER;
goto yy7;
yy11:
yych = *++YYCURSOR;
switch (yych) {
case 'b': goto yy12;
default: goto yy10;
}
yy12:
++YYCURSOR;
yynmatch = 1;
yypmatch[0] = YYCURSOR - 4;
yypmatch[1] = YYCURSOR - 2;
{}
}
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy16;
default: goto yy14;
}
yy14:
++YYCURSOR;
yy15:
{}
yy16:
yych = *(YYMARKER = ++YYCURSOR);
switch (yych) {
case 'b': goto yy17;
default: goto yy15;
}
yy17:
yych = *++YYCURSOR;
switch (yych) {
case 'a': goto yy19;
default: goto yy18;
}
yy18:
YYCURSOR = YYMARKER;
goto yy15;
yy19:
yych = *++YYCURSOR;
switch (yych) {
case 'b': goto yy20;
default: goto yy18;
}
yy20:
++YYCURSOR;
yynmatch = 3;
yypmatch[0] = YYCURSOR - 4;
yypmatch[1] = YYCURSOR - 2;
yypmatch[2] = YYCURSOR - 3;
yypmatch[3] = YYCURSOR - 2;
yypmatch[4] = YYCURSOR - 1;
yypmatch[5] = YYCURSOR;
{}
}
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
switch (yych) {
case 'a':
case 'b': goto yy24;
default: goto yy22;
}
yy22:
++YYCURSOR;
yy23:
{}
yy24:
yych = *++YYCURSOR;
switch (yych) {
case 'a':
case 'b': goto yy25;
default: goto yy23;
}
yy25:
++YYCURSOR;
yynmatch = 1;
yypmatch[0] = YYCURSOR - 2;
yypmatch[1] = YYCURSOR - 1;
{}
}
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy29;
case 'b': goto yy30;
default: goto yy27;
}
yy27:
++YYCURSOR;
yy28:
{}
yy29:
yych = *++YYCURSOR;
switch (yych) {
case 'a':
yyt1 = NULL;
goto yy31;
case 'b':
yyt1 = NULL;
goto yy33;
default: goto yy28;
}
yy30:
yych = *++YYCURSOR;
switch (yych) {
case 'a':
yyt1 = YYCURSOR;
goto yy31;
case 'b':
yyt1 = YYCURSOR;
goto yy33;
default: goto yy28;
}
yy31:
++YYCURSOR;
yyt2 = NULL;
yy32:
yynmatch = 3;
yypmatch[3] = yyt1;
yypmatch[5] = yyt2;
yypmatch[0] = YYCURSOR - 2;
yypmatch[1] = YYCURSOR - 1;
yypmatch[2] = yyt1;
if (yyt1 != NULL) yypmatch[2] -= 1;
yypmatch[4] = yyt2;
if (yyt2 != NULL) yypmatch[4] -= 1;
{}
yy33:
++YYCURSOR;
yyt2 = YYCURSOR;
goto yy32;
}
{
YYCTYPE yych;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'a':
yyt2 = YYCURSOR;
goto yy36;
default:
yyt1 = yyt2 = NULL;
goto yy35;
}
yy35:
yynmatch = 1;
yypmatch[0] = yyt2;
yypmatch[1] = yyt1;
{}
yy36:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy37;
default:
yyt1 = YYCURSOR;
goto yy35;
}
yy37:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'a':
yyt2 = YYCURSOR;
goto yy36;
default:
yyt1 = YYCURSOR;
goto yy35;
}
}
{
YYCTYPE yych;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'a':
yyt4 = YYCURSOR;
goto yy40;
default:
yyt1 = yyt2 = yyt3 = yyt4 = NULL;
goto yy39;
}
yy39:
yynmatch = 3;
yypmatch[0] = yyt4;
yypmatch[1] = yyt1;
yypmatch[3] = yyt2;
yypmatch[5] = yyt3;
yypmatch[2] = yyt2;
if (yyt2 != NULL) yypmatch[2] -= 2;
yypmatch[4] = yyt3;
if (yyt3 != NULL) yypmatch[4] -= 2;
{}
yy40:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'a': goto yy41;
default:
yyt2 = yyt3 = NULL;
yyt1 = YYCURSOR;
goto yy39;
}
yy41:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'a':
yyt4 = YYCURSOR;
goto yy40;
default:
yyt3 = NULL;
yyt1 = yyt2 = YYCURSOR;
goto yy39;
}
}
captures/noncapturing/explicit3_posix_inverted.re:35:14: warning: rule matches empty string [-Wmatch-empty-string]
captures/noncapturing/explicit3_posix_inverted.re:40:14: warning: rule matches empty string [-Wmatch-empty-string]
@@ -0,0 +1,41 @@
// re2c $INPUT -o $OUTPUT -i --posix-captures --invert-captures
/*!local:re2c
x = "a";
(!x)(x) {}
* {}
*/
/*!local:re2c
x = "a" "b";
(!x)(x) {}
* {}
*/
/*!local:re2c
x = "a" (!"b");
(!x)(x) {}
* {}
*/
/*!local:re2c
x = "a" | "b";
(!x)(x) {}
* {}
*/
/*!local:re2c
x = "a" | (!"b");
(!x)(x) {}
* {}
*/
/*!local:re2c
x = "a" | "aa";
(!x)*(x)* {}
*/
/*!local:re2c
x = "a" | (!"aa");
(!x)*(x)* {}
*/
@@ -2,40 +2,40 @@
/*!local:re2c
x = "a";
(?x)x {}
(!x)x {}
* {}
*/
/*!local:re2c
x = "a" "b";
(?x)x {}
(!x)x {}
* {}
*/
/*!local:re2c
x = "a" ("b");
(?x)x {}
(!x)x {}
* {}
*/
/*!local:re2c
x = "a" | "b";
(?x)x {}
(!x)x {}
* {}
*/
/*!local:re2c
x = "a" | ("b");
(?x)x {}
(!x)x {}
* {}
*/
/*!local:re2c
x = "a" | "aa";
(?x)*x* {}
(!x)*x* {}
*/
/*!local:re2c
x = "a" | ("aa");
(?x)*x* {}
(!x)*x* {}
*/
@@ -2,40 +2,40 @@
/*!local:re2c
x = "a";
(?x)x {}
(!x)x {}
* {}
*/
/*!local:re2c
x = "a" "b";
(?x)x {}
(!x)x {}
* {}
*/
/*!local:re2c
x = "a" ("b");
(?x)x {}
(!x)x {}
* {}
*/
/*!local:re2c
x = "a" | "b";
(?x)x {}
(!x)x {}
* {}
*/
/*!local:re2c
x = "a" | ("b");
(?x)x {}
(!x)x {}
* {}
*/
/*!local:re2c
x = "a" | "aa";
(?x)*x* {}
(!x)*x* {}
*/
/*!local:re2c
x = "a" | ("aa");
(?x)*x* {}
(!x)*x* {}
*/
@@ -0,0 +1,83 @@
/* Generated by re2c */
// re2c $INPUT -o $OUTPUT -i --leftmost-captures --invert-captures
// B is capturing
{
YYCTYPE yych;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'A': goto yy2;
case 'B': goto yy3;
default: goto yy1;
}
yy1:
++YYCURSOR;
{ * }
yy2:
++YYCURSOR;
{ A }
yy3:
++YYCURSOR;
yynmatch = 1;
yypmatch[0] = YYCURSOR - 1;
yypmatch[1] = YYCURSOR;
{ B }
}
// B is non-capturing, A is capturing, plus the implicit whole rule capture for A and B
{
YYCTYPE yych;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'A': goto yy6;
case 'B': goto yy7;
default: goto yy5;
}
yy5:
++YYCURSOR;
{ * }
yy6:
++YYCURSOR;
yynmatch = 2;
yypmatch[0] = yypmatch[2] = YYCURSOR - 1;
yypmatch[1] = yypmatch[3] = YYCURSOR;
{ A }
yy7:
++YYCURSOR;
yynmatch = 1;
yypmatch[0] = YYCURSOR - 1;
yypmatch[1] = YYCURSOR;
{ B }
}
// B is capturing
{
YYCTYPE yych;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'A': goto yy10;
case 'B': goto yy11;
default: goto yy9;
}
yy9:
++YYCURSOR;
{ * }
yy10:
++YYCURSOR;
{ A }
yy11:
++YYCURSOR;
yynmatch = 1;
yypmatch[0] = YYCURSOR - 1;
yypmatch[1] = YYCURSOR;
{ B }
}
@@ -0,0 +1,24 @@
// re2c $INPUT -o $OUTPUT -i --leftmost-captures --invert-captures
// B is capturing
/*!re2c
([A]) { A }
(![B]) { B }
* { * }
*/
// B is non-capturing, A is capturing, plus the implicit whole rule capture for A and B
/*!re2c
re2c:invert-captures = 0;
([A]) { A }
(![B]) { B }
* { * }
*/
// B is capturing
/*!re2c
re2c:invert-captures = 1;
([A]) { A }
(![B]) { B }
* { * }
*/
+1 -1
View File
@@ -1,5 +1,5 @@
/* Generated by re2c */
#line 1 "config/all_configs.re"
// re2c $INPUT -o $OUTPUT
#line 156 "config/all_configs.re"
#line 158 "config/all_configs.re"
+2
View File
@@ -19,9 +19,11 @@
re2c:tags = 0;
re2c:flags:tags = 0;
re2c:flags:T = 0;
re2c:leftmost-captures = 0;
re2c:posix-captures = 0;
re2c:flags:posix-captures = 0;
re2c:flags:P = 0;
re2c:invert-captures = 0;
re2c:tags:prefix = "";
re2c:tags:expression = "";
+1 -1
View File
@@ -1,4 +1,4 @@
// re2c $INPUT -o $OUTPUT --start-conditions --conditions --emit-dot --storable-state --flex-syntax --verbose --no-debug-info --no-generation-date --no-version --skeleton --eager-skip --loop-switch --bit-vectors --debug-output --case-ranges --computed-gotos --nested-ifs --case-insensitive --case-inverted --tags --posix-captures --no-unsafe --ebcdic --ecb --utf32 --unicode --ucs2 --wide-chars --utf16 --utf-16 --utf8 --utf-8 --lang rust --lang go --lang c --header all_options.h --type-header all_options.h --depfile all_options.d --encoding-policy ignore --encoding-policy substitute --encoding-policy fail --api custom --api default --input custom --input default --empty-class match-empty --empty-class match-none --empty-class error --location-format gnu --location-format msvc --input-encoding ascii --input-encoding utf8 --single-pass --reusable --dfa-minimization table --dfa-minimization moore --posix-prectable naive --posix-prectable complex --fixed-tags none --fixed-tags toplevel --fixed-tags all --no-optimize-tags --dump-nfa --dump-dfa-tree --dump-dfa-raw --dump-dfa-det --dump-dfa-tagopt --dump-dfa-min --dump-adfa --dump-cfg --dump-interf --dump-closure-stats -cDfFiSbdgsTeuwx8P1r -I . -t all_options.h
// re2c $INPUT -o $OUTPUT --start-conditions --conditions --emit-dot --storable-state --flex-syntax --verbose --no-debug-info --no-generation-date --no-version --skeleton --eager-skip --loop-switch --bit-vectors --debug-output --case-ranges --computed-gotos --nested-ifs --case-insensitive --case-inverted --tags --leftmost-captures --posix-captures --invert-captures --no-unsafe --ebcdic --ecb --utf32 --unicode --ucs2 --wide-chars --utf16 --utf-16 --utf8 --utf-8 --lang rust --lang go --lang c --header all_options.h --type-header all_options.h --depfile all_options.d --encoding-policy ignore --encoding-policy substitute --encoding-policy fail --api custom --api default --input custom --input default --empty-class match-empty --empty-class match-none --empty-class error --location-format gnu --location-format msvc --input-encoding ascii --input-encoding utf8 --single-pass --reusable --dfa-minimization table --dfa-minimization moore --posix-prectable naive --posix-prectable complex --fixed-tags none --fixed-tags toplevel --fixed-tags all --no-optimize-tags --dump-nfa --dump-dfa-tree --dump-dfa-raw --dump-dfa-det --dump-dfa-tagopt --dump-dfa-min --dump-adfa --dump-cfg --dump-interf --dump-closure-stats -cDfFiSbdgsTeuwx8P1r -I . -t all_options.h
// Not really *all* options: -v, -V, -h and variations are missing, as their
// output depends on the version, build configuration and OS (help foramtting).
+268
View File
@@ -0,0 +1,268 @@
// Code generated by re2c, DO NOT EDIT.
//go:generate re2go $INPUT -o $OUTPUT --utf8 --input-encoding utf8 --flex-syntax -i
package main
func parse(str string) int {
var cur, mar int
for {
{
var yych byte
yych = str[cur]
switch (yych) {
case 0x00:
goto yy1
case 'a':
goto yy4
case 'c':
goto yy5
case 'e':
goto yy6
case 'g':
goto yy7
default:
goto yy2
}
yy1:
cur += 1
{ return -1 }
yy2:
cur += 1
yy3:
{ continue }
yy4:
cur += 1
mar = cur
yych = str[cur]
switch (yych) {
case 'b':
goto yy8
case 0xC3:
goto yy9
default:
goto yy3
}
yy5:
cur += 1
mar = cur
yych = str[cur]
switch (yych) {
case 0xC3:
goto yy11
default:
goto yy3
}
yy6:
cur += 1
mar = cur
yych = str[cur]
switch (yych) {
case 0xC3:
goto yy12
default:
goto yy3
}
yy7:
cur += 1
mar = cur
yych = str[cur]
switch (yych) {
case 0xC3:
goto yy13
default:
goto yy3
}
yy8:
cur += 1
{ return 1 }
yy9:
cur += 1
yych = str[cur]
switch (yych) {
case 0xBC:
goto yy14
default:
goto yy10
}
yy10:
cur = mar
goto yy3
yy11:
cur += 1
yych = str[cur]
switch (yych) {
case 0xBC:
goto yy15
default:
goto yy10
}
yy12:
cur += 1
yych = str[cur]
switch (yych) {
case 0xBC:
goto yy16
default:
goto yy10
}
yy13:
cur += 1
yych = str[cur]
switch (yych) {
case 0xBC:
goto yy17
default:
goto yy10
}
yy14:
cur += 1
yych = str[cur]
switch (yych) {
case 'b':
goto yy8
default:
goto yy10
}
yy15:
cur += 1
yych = str[cur]
switch (yych) {
case 0xC3:
goto yy18
default:
goto yy10
}
yy16:
cur += 1
yych = str[cur]
switch (yych) {
case 'f':
goto yy19
default:
goto yy10
}
yy17:
cur += 1
yych = str[cur]
switch (yych) {
case 'n':
goto yy20
default:
goto yy10
}
yy18:
cur += 1
yych = str[cur]
switch (yych) {
case 0xBC:
goto yy21
default:
goto yy10
}
yy19:
cur += 1
{ return 3 }
yy20:
cur += 1
yych = str[cur]
switch (yych) {
case 'c':
goto yy22
default:
goto yy10
}
yy21:
cur += 1
yych = str[cur]
switch (yych) {
case 'd':
goto yy23
case 0xC3:
goto yy18
default:
goto yy10
}
yy22:
cur += 1
yych = str[cur]
switch (yych) {
case 'e':
goto yy24
default:
goto yy10
}
yy23:
cur += 1
{ return 2 }
yy24:
cur += 1
yych = str[cur]
switch (yych) {
case 'l':
goto yy25
default:
goto yy10
}
yy25:
cur += 1
yych = str[cur]
switch (yych) {
case 'l':
goto yy26
default:
goto yy10
}
yy26:
cur += 1
yych = str[cur]
switch (yych) {
case 'e':
goto yy27
default:
goto yy10
}
yy27:
cur += 1
yych = str[cur]
switch (yych) {
case 'm':
goto yy28
case 'n':
goto yy29
default:
goto yy10
}
yy28:
cur += 1
yych = str[cur]
switch (yych) {
case 'e':
goto yy30
default:
goto yy10
}
yy29:
cur += 1
yych = str[cur]
switch (yych) {
case 'm':
goto yy28
default:
goto yy10
}
yy30:
cur += 1
{ return 0 }
}
}
}
func main() {
assert_eq := func(x, y int) { if x != y { panic("error") } }
assert_eq(parse("<html><body><p><em>Son güncelleme: 5/5/2020</em></p></body></html>\000"), 0)
assert_eq(parse("ab"), 1)
assert_eq(parse("aüb"), 1)
assert_eq(parse("cüüüüd"), 2)
assert_eq(parse("eüf"), 3)
}
+32
View File
@@ -0,0 +1,32 @@
//go:generate re2go $INPUT -o $OUTPUT --utf8 --input-encoding utf8 --flex-syntax -i
package main
func parse(str string) int {
var cur, mar int
for {
/*!re2c
re2c:yyfill:enable = 0;
re2c:define:YYCTYPE = byte;
re2c:define:YYPEEK = "str[cur]";
re2c:define:YYSKIP = "cur += 1";
re2c:define:YYBACKUP = "mar = cur";
re2c:define:YYRESTORE = "cur = mar";
güncellen?me { return 0 }
aü?b { return 1 }
cüüü*d { return 2 }
e[ü]f { return 3 }
[\000] { return -1 }
* { continue }
*/
}
}
func main() {
assert_eq := func(x, y int) { if x != y { panic("error") } }
assert_eq(parse("<html><body><p><em>Son güncelleme: 5/5/2020</em></p></body></html>\000"), 0)
assert_eq(parse("ab"), 1)
assert_eq(parse("aüb"), 1)
assert_eq(parse("cüüüüd"), 2)
assert_eq(parse("eüf"), 3)
}
+4
View File
@@ -0,0 +1,4 @@
/*!re2c
[b] { b }
* { * }
*/
+4
View File
@@ -0,0 +1,4 @@
/*!re2c
[c] { c }
* { * }
*/
+61
View File
@@ -0,0 +1,61 @@
/* Generated by re2c */
#line 1 "include/include008_header.re"
// re2c $INPUT -o $OUTPUT --depfile $DEPFILE --header include008.h
#line 1 "include/include008.re.b.inc"
#line 7 "include/include008_header.c"
{
YYCTYPE yych;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'b': goto yy2;
default: goto yy1;
}
yy1:
++YYCURSOR;
#line 3 "include/include008.re.b.inc"
{ * }
#line 20 "include/include008_header.c"
yy2:
++YYCURSOR;
#line 2 "include/include008.re.b.inc"
{ b }
#line 25 "include/include008_header.c"
}
#line 4 "include/include008.re.b.inc"
#line 2 "include/include008_header.re"
#line 6 "include/include008_header.re"
/* Generated by re2c */
#line 1 "include/include008.re.c.inc"
#line 6 "include/include008.h"
{
YYCTYPE yych;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case 'c': goto yy5;
default: goto yy4;
}
yy4:
++YYCURSOR;
#line 3 "include/include008.re.c.inc"
{ * }
#line 19 "include/include008.h"
yy5:
++YYCURSOR;
#line 2 "include/include008.re.c.inc"
{ c }
#line 24 "include/include008.h"
}
#line 4 "include/include008.re.c.inc"
#line 5 "include/include008_header.re"
include/include008_header.c include/include008.h: include/include008.re.b.inc include/include008.re.c.inc include/include008_header.re
+6
View File
@@ -0,0 +1,6 @@
// re2c $INPUT -o $OUTPUT --depfile $DEPFILE --header include008.h
/*!include:re2c "include008.re.b.inc" */
/*!header:re2c:on */
/*!include:re2c "include008.re.c.inc" */
/*!header:re2c:off */