在C中的GNU automake中使用解析器

普拉巴卡

我是GNU自动工具的新手,在我的项目中使用了lex和yacc解析器,将它们作为源包含在makefile.am中会导致以下错误:

configure.in:

...
AC_CHECK_PROGS(YACC,bison yacc,none)
if test "x$YACC" = "xbison"; then
    YACC="$YACC -y"
fi

AC_CHECK_PROGS(LEX,flex,none)
...

makefile.am:

## $Id
AUTOMAKE_OPTIONS=foreign no-dependencies
include $(srcdir)/Makefile_defs

dynamicpreprocessordir = ${libdir}/snort_dynamicpreprocessor

dynamicpreprocessor_LTLIBRARIES = libsf_appid_preproc.la


libsf_appid_preproc_la_LDFLAGS = -export-dynamic -module @XCCFLAGS@
if SO_WITH_STATIC_LIB
libsf_appid_preproc_la_LIBADD = ../libsf_dynamic_preproc.la 


../libsf_dynamic_utils.la $(LUA_LIBS)
else
nodist_libsf_appid_preproc_la_SOURCES = \
../include/sf_dynamic_preproc_lib.c \
../include/sf_ip.c \
../include/sfPolicyUserData.c \
../include/sfxhash.c \
../include/sfghash.c \
../include/sflsq.c \
../include/sfhashfcn.c \
../include/sfmemcap.c \
../include/sfprimetable.c

libsf_appid_preproc_la_LIBADD = $(LUA_LIBS)
endif

libsf_appid_preproc_la_CFLAGS = -DDYNAMIC_PREPROC_CONTEXT -DSTATIC=static $(LUA_CFLAGS)

libsf_appid_preproc_la_SOURCES = $(APPID_SOURCES)

all-local: $(LTLIBRARIES)
    $(MAKE) DESTDIR=`pwd`/../build install-dynamicpreprocessorLTLIBRARIES

在Makefile_defs中:

APPID_SRC_DIR = ${top_srcdir}/src/dynamic-preprocessors/appid
...
APPID_SOURCES =  \
$(APPID_SRC_DIR)/vfml/fc45.lex  \
$(APPID_SRC_DIR)/vfml/fc45.y \
...

当我运行程序时,出现以下错误:

libsf_appid_preproc.so: undefined symbol: FC45SetFile

虽然已经在fc45.lex文件中定义了FC45SetFile()。

fc45.lex:

%{
#include "fc45.tab.h"
//#include "vfml.h"
#include <string.h>
#include <stdlib.h>

  /* HERE  doesn't match strings starting with numbers other than 0 right */

char string_buf[4000]; /* BUG - maybe check for strings that are too long? */
char *string_buf_ptr;

void FC45FinishString(void);

extern int gLineNumber;
%}

%x str_rule

%%
<str_rule,INITIAL>\|[^\n]* ;

[\ \t\r]+ ;
\n      gLineNumber++;

\. { return '.';}
, { return ',';}
: { return ':';}

ignore { return tIgnore; }
continuous { return tContinuous; }
discrete { return tDiscrete; }


[^:?,\t\n\r\|\.\\\ ] string_buf_ptr = string_buf; unput(yytext[0]); BEGIN(str_rule);

<str_rule>[:,?]             FC45FinishString(); unput(yytext[0]); return tString;
<str_rule>\.[\t\r\ ]    FC45FinishString(); unput(yytext[1]); unput(yytext[0]); return tString;
<str_rule>\.\n    FC45FinishString(); unput(yytext[1]); unput(yytext[0]); return tString; gLineNumber++;

<str_rule><<EOF>> {
   int len = strlen(string_buf);
   //   printf("eof rule.\n");
   if(len == 1 && string_buf[0] == '.') {
     //printf("   period at end of file\n");
      return '.';
   } else if(string_buf[len - 1] == '.') {
     // printf("   period: %s - unput .\n", string_buf);

      FC45FinishString(); unput('.'); return tString;
   } else {
     // printf("   no-period: %s\n", string_buf);
      FC45FinishString(); return tString;
   }
}

<str_rule>\\:   *string_buf_ptr++ = ':';
<str_rule>\\\?  *string_buf_ptr++ = '?';
<str_rule>\\,   *string_buf_ptr++ = ',';
<str_rule>\\.    *string_buf_ptr++ = '.';

<str_rule>\n  *string_buf_ptr++ = ' '; gLineNumber++;
<str_rule>[ \t\r]+  *string_buf_ptr++ = ' ';

<str_rule>[^:?,\t\n\r\|\.\\\ ]+        {
   char *yptr = yytext;

   while(*yptr) {
      *string_buf_ptr++ = *yptr++;
   }
}


%%
int fc45wrap(void) {
    return 1;
}

void FC45SetFile(FILE *file) {
    fc45in = file;
    yyrestart(fc45in);
}

void FC45FinishString(void) {
   int len;
   char *tmpStr;

   BEGIN(INITIAL);
   *string_buf_ptr = '\0';

   len = strlen(string_buf);

   /* remove any ending spaces */
   while(string_buf[len - 1] == ' ') {
     string_buf[len - 1] = '\0';
     len--;
   }

   tmpStr = MNewPtr(len + 1);
   strncpy(tmpStr, string_buf, len + 1);
   fc45lval.string = tmpStr;
   string_buf[0] = '\0';
}

fc45.y:

%{
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "ExampleSpec1.h"
//#include "AttributeTracker.c"
//#include "vfml.h"
%}

%{
int fc45lex(void);
int fc45error(const char *);

/* HERE figure out how to give better error messages */
/* BUG needs a \n at the end of the names file */

/* These tmps are allocated at the begining of parsing and then
    used during parsing.  For example, so that we can simply
    add terrains to an area while parsing.  After parsing a
    statement, the associated tmp is added to the appropriate
    global list, and a new tmp is allocated.  Finally, at the
    end of parsing, all the tmps are freed
*/

ExampleSpecPtr        exampleSpec;
AttributeSpecPtr      attributeSpec;
int gLineNumber;

%}

%union {
   int integer;
   float f;
   char *string;
}

%token <integer> tInteger
%token <string>  tString

%token tIgnore tContinuous tDiscrete tEOF

%%

ExampleSpec: ClassList '.' AttributeList;

ClassList: ClassList ',' ClassSpec | ClassSpec /* ending */;

ClassSpec: tString { ExampleSpecAddClass(exampleSpec, $1); };

AttributeList: AttributeList AttributeSpec | /* ending */;

AttributeSpec: tString ':' AttributeInfo '.' { 
   AttributeSpecSetName(attributeSpec, $1);
   ExampleSpecAddAttributeSpec(exampleSpec, attributeSpec);
   attributeSpec = AttributeSpecNew();
};

AttributeInfo: tIgnore {
                   AttributeSpecSetType(attributeSpec, asIgnore);} |
               tContinuous {
                   AttributeSpecSetType(attributeSpec, asContinuous);} |
               tDiscrete tString {
                   AttributeSpecSetType(attributeSpec, asDiscreteNoName);
                   AttributeSpecSetNumValues(attributeSpec, atoi($2)); } |
               AttributeValueNameList { 
         AttributeSpecSetType(attributeSpec, asDiscreteNamed); };

AttributeValueNameList: AttributeValueNameList ',' tString {
   AttributeSpecSetNumValues(attributeSpec,
                     AttributeSpecGetNumValues(attributeSpec) + 1);
   AttributeSpecAddValue(attributeSpec, $3); } |
tString {
   AttributeSpecSetNumValues(attributeSpec,
                     AttributeSpecGetNumValues(attributeSpec) + 1);
   AttributeSpecAddValue(attributeSpec, $1); };

%%

void FC45SetFile(FILE *file);

int fc45error(const char *msg) {
   fprintf(stderr, "%s line %d\n", msg, gLineNumber);
   return 0;
}

ExampleSpecPtr ParseFC45(const char *file) {
   FILE *input;

   input = fopen(file, "r");
   if(input == 0) {
      return 0;
   }

   FC45SetFile(input);

   exampleSpec = ExampleSpecNew();
   attributeSpec = AttributeSpecNew();

   gLineNumber = 0;

   if(fc45parse()) {
      /* parse failed! */
      fprintf(stderr, "Error in parsing: %s\n", file);
   }

   fclose(input);

   /* free the left over attribute spec */
   AttributeSpecFree(attributeSpec);

   return exampleSpec;
}

我已经在Internet上搜索了解决方案,但无法提出任何解决方案。希望有人认识到问题并对此有快速的解决方案。任何帮助将不胜感激。

用户539810

我只看了一个简单的示例,添加了以下Autotools文件:

configure.ac

AC_PREREQ([2.69])
AC_INIT([example], [0.1a], [[email protected]])
AC_CONFIG_SRCDIR([ex1.l])

# Used only to shorten the otherwise lengthy compilation line in the output below.
AC_CONFIG_HEADERS([config.h])

AM_INIT_AUTOMAKE([foreign])

# I used C instead of C++.
AC_PROG_CC
AM_PROG_LEX
AC_PROG_YACC

AC_CONFIG_FILES([Makefile])
AC_OUTPUT

Makefile.am(从Automake手册中直接获取):

BUILT_SOURCES = ex1.h
AM_YFLAGS = -d
bin_PROGRAMS = ex1
ex1_SOURCES = ex1.l ex1.y

原来,您不能使用相同的基本文件名来命名文件。就我而言,我不得不ex1.lex1.yex1_SOURCES = ex1.l ex1.y当我调用时,使用导致以下输出make

make[1]: Entering directory '/home/kit/ex1'
/bin/bash ./ylwrap ex1.l lex.yy.c ex1.c -- flex  
make[1]: Leaving directory '/home/kit/ex1'
make  all-am
make[1]: Entering directory '/home/kit/ex1'
gcc -DHAVE_CONFIG_H=1 -I. -g -O2 -MT ex1.o -MD -MP -MF .deps/ex1.Tpo -c -o ex1.o ex1.c
ex1.l:5:17: fatal error: ex1.h: No such file or directory
 #include "ex1.h"
                 ^
compilation terminated.
Makefile:378: recipe for target 'ex1.o' failed
make[1]: *** [ex1.o] Error 1
make[1]: Leaving directory '/home/kit/ex1'
Makefile:281: recipe for target 'all' failed
make: *** [all] Error 2

请注意,flex是在第二行中调用的,而bison / yacc不是。什么原因?好吧,ylwrap脚本是原因:

ex1.c: ex1.l
ex1.c: ex1.y

由于该脚本将ex1.l的输出从“ lex.yy.c”重命名为“ ex1.c”,因此makefile认为ex1.c已经生成,因此它对bison / yacc文件不会做任何事情,这意味着ex1.h也不被构建。

您不能禁用该ylwrap脚本,但是可以解决该问题:只需重命名Flex源文件,并根据需要更改对Makefile.in和configure.ac文件中文件名的引用。您不需要重命名bison / yacc源文件,因为这意味着将每个C文件以及flex源文件中的每个文件都更改#include "fc45.h"#include "fc45_g.h"(或将文件重命名为)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Python 3中使用SAX解析器解析XML

来自分类Dev

在Python 3中使用SAX解析器解析XML

来自分类Dev

如何在Android中使用解析器动态设置线性布局中的背景图像

来自分类Dev

如何在C#中使用xml解析器提取xml中节点的所有值?

来自分类Dev

使用JParsec在解析器中解析文本

来自分类Dev

在FastAPI中,无法使用解析器异步等待

来自分类Dev

ANTLR v4 C#:解析器::使用{}

来自分类Dev

使用Bison的C到Forth解析器

来自分类Dev

在C中实现xml解析器

来自分类Dev

C#中的Sip解析器

来自分类Dev

C#中的Sip解析器

来自分类Dev

使用C#中的解析器从剪贴板获取中文数据

来自分类Dev

解析器语法错误:意外的令牌<-在ASP.NET MVC 4中使用jQuery Ajax加载部分视图

来自分类Dev

如何在 Haskell 中使用解析器来查找字符串中某些子字符串的位置?

来自分类Dev

另一个解析器中的C字符串解析器

来自分类Dev

如何使用Scala解析器解决解析路径中的错误?

来自分类Dev

使用simle json解析器的Java中的JSON解析错误

来自分类Dev

Haskell 解析中 CPS 与非 CPS 解析器的堆使用情况

来自分类Dev

在路由解析器中使用订阅

来自分类Dev

在子解析器中使用`err`

来自分类Dev

如何使用网络管理器在Fedora中设置DNS解析器?

来自分类Dev

了解Scala中的Packrat解析器

来自分类Dev

JSON解析器中的错误(NullPointerException)

来自分类Dev

angularjs中的通用路由解析器?

来自分类Dev

QT中的json解析器

来自分类Dev

Go中的通用XML解析器

来自分类Dev

解析器中的Java异常处理

来自分类Dev

BNF fparsec解析器中的错误

来自分类Dev

ANTLR:忽略解析器中的语句

Related 相关文章

热门标签

归档