1

我正在尝试re::engine::RE2使用cpan.

构建时,编译器会发出错误消息:

re2_xs.cc:254:25: error: variable length array of non-POD element type
      're2::StringPiece'
    re2::StringPiece res[re->nparens + 1];
                        ^

这意味着什么?我该如何解决?我使用的是 2011 Macbook Air 和 Perl 5.12。

4

3 回答 3

0

re::engine::RE2 从未在 darwin/Perl 5.12 上成功测试过。

谷歌搜索错误消息表明这是 Xcode 附带的旧 clang 中的一个缺陷,并且不存在于较新版本中。

升级你的软件,你失去了支持,也许使用 Macports 来获得一个新的 gcc。

于 2013-07-03T07:51:33.320 回答
0

没错,re::engine::RE2从来没有在 OS X 上编译过。但你可以让它编译。找到 cpan 目录。对我来说是~/.cpan/build/re-engine-RE2-0.13-BY20k3/。然后在其中更改两个 C++ 源文件。

$ diff -p re2_xs.cc.old re2_xs.cc
*** re2_xs.cc.old   2015-04-20 20:20:15.000000000 +0200
--- re2_xs.cc   2015-04-20 20:22:24.000000000 +0200
*************** RE2_exec(pTHX_ REGEXP * const rx, char *
*** 229,236 ****
      RE2 * ri = (RE2*) SvANY(rx)->pprivate;
      regexp * re = SvANY(rx);

-     re2::StringPiece res[re->nparens + 1];
-
  #ifdef RE2_DEBUG
      Perl_warner(aTHX_ packWARN(WARN_MISC), "RE2: Matching '%s' (%p, %p) against '%s'", stringarg, strbeg, stringarg, RX_WRAPPED(rx));
  #endif
--- 229,234 ----
*************** RE2_exec(pTHX_ REGEXP * const rx, char *
*** 241,246 ****
--- 239,246 ----
        return 0;
      }

+     re2::StringPiece *res = new re2::StringPiece[re->nparens + 1];
+
      bool ok = ri->Match(
              re2::StringPiece(strbeg, strend - strbeg),
              stringarg - strbeg,
*************** RE2_exec(pTHX_ REGEXP * const rx, char *
*** 250,255 ****
--- 250,256 ----

      /* Matching failed */
      if (!ok) {
+         delete [] res;
          return 0;
      }

*************** RE2_exec(pTHX_ REGEXP * const rx, char *
*** 266,271 ****
--- 267,274 ----
          }
      }

+     delete [] res;
+
      return 1;
  }

在那之后尝试编译会让你遇到一个tr1问题。

/usr/bin/clang -o obj/util/arena.o -xc++   -O3 -DHAVE_PTHREAD -pthread -Wno-sign-compare -c -I.    -DNDEBUG util/arena.cc
In file included from util/arena.cc:5:
./util/util.h:45:10: fatal error: 'tr1/unordered_set' file not found

我确信-DMakefile 有更简单的修复,但我更改了代码。

# diff -p re2/util/util.h.old re2/util/util.h
*** re2/util/util.h.old 2015-04-20 20:29:01.000000000 +0200
--- re2/util/util.h 2015-04-20 20:29:26.000000000 +0200
*************** using std::make_pair;
*** 42,49 ****

  #if defined(__GNUC__) && !defined(USE_CXX0X)

! #include <tr1/unordered_set>
! using std::tr1::unordered_set;

  #else

--- 42,51 ----

  #if defined(__GNUC__) && !defined(USE_CXX0X)

! //#include <tr1/unordered_set>
! //using std::tr1::unordered_set;
! #include <unordered_set>
! using std::unordered_set;

  #else

现在只是

make && make install

你现在re::engine::RE2可以在 OS X上使用了。

于 2015-04-20T18:33:55.350 回答
0

Douglas Scofield的回答是正确的,但需要进行额外的更改。在 re2_xs.cc 中,您还必须更改第 244 行,如下所示:

          bool ok = ri->Match(
              re2::StringPiece(strbeg, strend - strbeg),
              stringarg - strbeg,
              strend - strbeg,
              RE2::UNANCHORED,
!             res, re->nparens + 1);

Douglas Scofield 的回答将数组 res 更改为指针 *res 以避免变长数组的编译器错误。但是,在此之后更改行

sizeof res / sizeof *res

不起作用,因为您将获取指针的大小并除以数组的大小。因此,您必须进行上述更改

re->nparens + 1

获取 *res 指向的数组的大小,这是原始代码中所需要的。

如果您不进行更改,则捕获组将无法在 re2 中工作。您将收到诸如 $1、$2 等捕获组未初始化的错误。

上面的答案很好,只需要一个附录。

于 2016-12-31T04:40:44.717 回答