makefile和lex + yacc中的错误 - >错误:'noyywrap'未声明(首次使用此功能)

时间:2017-03-10 21:39:14

标签: c++ makefile yacc lex

执行以下makefile时:

  # %W% %G%

# make and run all the example programs for
# lex & yacc, Second Edition
CC = gcc -g
LIBS = -ly -ll
LEX = flex 
YACC = yacc -dv
CFLAGS = -DYYDEBUG=1

all: sql1

# chapter 5

sql1:   sql1.o scn1.o
    ${CC} -o $@ sql1.o scn1.o

sql1.c sql1.h:  sql1.y
    ${YACC} sql1.y
    mv y.tab.h sql1.h
    mv y.tab.c sql1.c
    mv y.output sql1.out

scn1.o: sql1.h

我收到这些错误:

 ➤ 

make
flex   -t scn1.l > scn1.c
gcc -g -DYYDEBUG=1   -c -o scn1.o scn1.c
scn1.l: In function ‘yylex’:
scn1.l:18:1: error: ‘noyywrap’ undeclared (first use in this function)
  /* literal keyword tokens */
 ^
scn1.l:18:1: note: each undeclared identifier is reported only once for each function it appears in
<stdout>:956:28: error: expected ‘;’ before ‘break’
scn1.l:19:2: note: in expansion of macro ‘YY_BREAK’
scn1.l: At top level:
scn1.l:166:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 {
 ^
make: *** [<builtin>: scn1.o] Error 1

有人可以提供一些如何解决这些问题的提示吗?

我实际上是在尝试编译本书中与SQL相关的资源: http://shop.oreilly.com/product/9781565920002.do

这是.l文件的代码:

%{
/*
 * AT&T lex can't handle this lexer due to lex bugs.  It works with flex
 * 2.3.7, pclex 2.0.5, and MKS lex 3.1a.
 */

#include "sql1.h"
#include <string.h>

int lineno = 1;
void yyerror(char *s);
%}
    /* MKS needs the next line to increase the NFA table */
%e 1200

%%
%option noyywrap
    /* literal keyword tokens */

ADA     { return ADA; }
ALL     { return ALL; }
AND     { return AND; }
AVG     { return AMMSC; }
MIN     { return AMMSC; }
MAX     { return AMMSC; }
SUM     { return AMMSC; }
COUNT       { return AMMSC; }
ANY     { return ANY; }
AS      { return AS; }
ASC     { return ASC; }
AUTHORIZATION   { return AUTHORIZATION; }
BETWEEN     { return BETWEEN; }
BY      { return BY; }
C       { return C; }
CHAR(ACTER)?    { return CHARACTER; }
CHECK       { return CHECK; }
CLOSE       { return CLOSE; }
COBOL       { return COBOL; }
COMMIT      { return COMMIT; }
CONTINUE    { return CONTINUE; }
CREATE      { return CREATE; }
CURRENT     { return CURRENT; }
CURSOR      { return CURSOR; }
DECIMAL     { return DECIMAL; }
DECLARE     { return DECLARE; }
DEFAULT     { return DEFAULT; }
DELETE      { return DELETE; }
DESC        { return DESC; }
DISTINCT    { return DISTINCT; }
DOUBLE      { return DOUBLE; }
ESCAPE      { return ESCAPE; }
EXISTS      { return EXISTS; }
FETCH       { return FETCH; }
FLOAT       { return FLOAT; }
FOR     { return FOR; }
FOREIGN     { return FOREIGN; }
FORTRAN     { return FORTRAN; }
FOUND       { return FOUND; }
FROM        { return FROM; }
GO[ \t]*TO  { return GOTO; }
GRANT       { return GRANT; }
GROUP       { return GROUP; }
HAVING      { return HAVING; }
IN      { return IN; }
INDICATOR   { return INDICATOR; }
INSERT      { return INSERT; }
INT(EGER)?  { return INTEGER; }
INTO        { return INTO; }
IS      { return IS; }
KEY     { return KEY; }
LANGUAGE    { return LANGUAGE; }
LIKE        { return LIKE; }
MODULE      { return MODULE; }
NOT     { return NOT; }
NULL        { return NULLX; }
NUMERIC     { return NUMERIC; }
OF      { return OF; }
ON      { return ON; }
OPEN        { return OPEN; }
OPTION      { return OPTION; }
OR      { return OR; }
ORDER       { return ORDER; }
PASCAL      { return PASCAL; }
PLI     { return PLI; }
PRECISION   { return PRECISION; }
PRIMARY     { return PRIMARY; }
PRIVILEGES  { return PRIVILEGES; }
PROCEDURE   { return PROCEDURE; }
PUBLIC      { return PUBLIC; }
REAL        { return REAL; }
REFERENCES  { return REFERENCES; }
ROLLBACK    { return ROLLBACK; }
SCHEMA      { return SCHEMA; }
SELECT      { return SELECT; }
SET     { return SET; }
SMALLINT    { return SMALLINT; }
SOME        { return SOME; }
SQLCODE     { return SQLCODE; }
TABLE       { return TABLE; }
TO      { return TO; }
UNION       { return UNION; }
UNIQUE      { return UNIQUE; }
UPDATE      { return UPDATE; }
USER        { return USER; }
VALUES      { return VALUES; }
VIEW        { return VIEW; }
WHENEVER    { return WHENEVER; }
WHERE       { return WHERE; }
WITH        { return WITH; }
WORK        { return WORK; }

    /* punctuation */

"=" |
"<>"    |
"<" |
">" |
"<="    |
">="        { return COMPARISON; }

[-+*/:(),.;]    { return yytext[0]; }

    /* names */

[A-Za-z][A-Za-z0-9_]*   { return NAME; }

    /* numbers */

[0-9]+  |
[0-9]+"."[0-9]* |
"."[0-9]*   { return INTNUM; }

[0-9]+[eE][+-]?[0-9]+   |
[0-9]+"."[0-9]*[eE][+-]?[0-9]+ |
"."[0-9]*[eE][+-]?[0-9]+    { return APPROXNUM; }

    /* strings */

'[^'\n]*'   {
        int c = input();

        unput(c);   /* just peeking */
        if(c != '\'') {
            return STRING;
        } else
            yymore();
    }

'[^'\n]*$   { yyerror("Unterminated string"); }

\n      lineno++;

[ \t\r]+    ;   /* white space */

"--".*$     ;   /* comment */

%%

void
yyerror(char *s)
{
    printf("%d: %s at %s\n", lineno, s, yytext);
}

main(int ac, char **av)
{
    if(ac > 1 && (yyin = fopen(av[1], "r")) == NULL) {
        perror(av[1]);
        exit(1);
    }

    if(!yyparse())
        printf("SQL parse worked\n");
    else
        printf("SQL parse failed\n");
} /* main */

1 个答案:

答案 0 :(得分:1)

问题在于:

%%
%option noyywrap

因为%option位于第二部分(%%之后),所以它不是%option指令的使用。相反,它声明了一个与输入字符串%option匹配的模式,并在响应中执行代码noyywrap,这没有任何意义(并导致您看到的错误)。

而是交换这两行的顺序

%option noyywrap
%%

这将它放在第一部分中,因此它是%option指令。