我使用cmake中的柠檬然后制作。 Lemon会根据我调用它的方式从shellparser.c
生成不同的shellparser.y
。我不确定细节,但至少我现在可以建立这个项目。
问题是,柠檬会根据柠檬的调用方式生成两个不同的文件。如果我从cmake脚本调用lemon,那么它可以工作,并且可以编译生成的文件而不会出错。但是,如果我只是lemon -s shellparser.y
,那么由于编译器错误,无法编译生成的shellparser.c
。
这个问题并没有阻止我,但我想知道它是什么。我的cmake是:
cmake_minimum_required(VERSION 3.0)
project(shell.test)
if (EDITLINE_LIBRARIES AND EDITLINE_INCLUDE_DIRS)
set (Editline_FIND_QUIETLY TRUE)
endif (EDITLINE_LIBRARIES AND EDITLINE_INCLUDE_DIRS)
find_path(EDITLINE_INCLUDE_DIRS NAMES editline/readline.h)
find_library(EDITLINE_LIBRARIES NAMES edit)
include (FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Editline DEFAULT_MSG
EDITLINE_LIBRARIES
EDITLINE_INCLUDE_DIRS)
mark_as_advanced(EDITLINE_INCLUDE_DIRS EDITLINE_LIBRARIES)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L/usr/local/include/ -L/usr/include -std=c99 -pedantic-errors -O3 -g -Wall -pedantic -ledit -ltermcap")
include_directories(/usr/local/include/ /usr/include)
link_directories(/usr/lib)
link_directories(/usr/local/lib)
add_executable(shell main.c errors.c util.c shellparser.c)
target_link_libraries(shell edit readline)
add_custom_target(shellparser DEPENDS ${CMAKE_SOURCE_DIR}/shellparser.c)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/shellparser.c COMMAND lemon -s ${CMAKE_SOURCE_DIR}/shellparser.y DEPENDS ${CMAKE_SOURCE_DIR}/shellparser.y)
add_dependencies(shell shellparser)
违规语法是:
%include
{
#include "types.h"
#include "assert.h"
}
%syntax_error { fprintf(stderr, "Syntax error\n"); }
%token_type { struct SToken* }
%type expr { int }
%left PLUS MINUS.
%left TIMES DIVIDE.
%left WHILE.
program ::= expr(A). { printf("Result = %d\n", A); }
expr(A)::= WHILE LPAR expr(B) RPAR expr(C). {printf("test"); A = B + C; }
expr(A) ::= expr(B) PLUS expr(C). {A = B + C; }
expr(A) ::= expr(B) MINUS expr(C). {A = B - C; }
expr(A) ::= expr(B) TIMES expr(C). {A = B * C; }
expr(A) ::= expr(B) DIVIDE expr(C).
{
if (C != 0)
{
A = B / C;
}
else
{
fprintf(stderr, "divide by 0");
}
}
expr(A) ::= LPAR expr(B) RPAR. { A = B; }
expr(A) ::= INTEGER(B).
{
printf("the result = %s\n", B->token);
A = B->value;
printf("Passed argument: %s\n", B->token);
}
编译错误是:
$ make
[ 14%] Built target shellparser
Scanning dependencies of target shell
[ 28%] Building C object CMakeFiles/shell.dir/shellparser.c.o
/home/dac/osh/shellparser.c:89:0: error: "YY_NO_ACTION" redefined
#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
^
/home/dac/osh/shellparser.c:88:0: note: this is the location of the previous definition
#define YY_NO_ACTION 37
^
/home/dac/osh/shellparser.c:90:0: error: "YY_ACCEPT_ACTION" redefined
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
^
/home/dac/osh/shellparser.c:87:0: note: this is the location of the previous definition
#define YY_ACCEPT_ACTION 36
^
/home/dac/osh/shellparser.c:91:0: error: "YY_ERROR_ACTION" redefined
#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
^
/home/dac/osh/shellparser.c:86:0: note: this is the location of the previous definition
#define YY_ERROR_ACTION 35
^
/home/dac/osh/shellparser.c:288:9: error: expected expression before ‘%’ token
%%
^
/home/dac/osh/shellparser.c:296:9: error: expected expression before ‘%’ token
%%
^
/home/dac/osh/shellparser.c:296:9: error: initializer element is not constant
但是如果我从cmake生成shellparser.c
,我可以编译它。我查看了cmake文件,但我真的看不出它通常的lemon -s
做了什么。为什么会这样?