Почему я получаю разные результаты от лимонного парсера для одного и того же ввода?
Я использую лимон от cmake и затем делаю. Лимон будет генерировать разные shellparser.c
от shellparser.y
в зависимости от того, как я его вызываю. Я не уверен в деталях, но, по крайней мере, я могу построить проект сейчас.
Проблема в том, что lemon будет генерировать два разных файла в зависимости от того, как вызывался lemon. Если я вызываю лимон из скрипта cmake, то он работает, и полученный файл может быть скомпилирован без ошибок. Но если я просто 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
Но я могу скомпилировать его, если сгенерирую shellparser.c
от cmake. Я посмотрел на файл cmake, но я не мог понять, что еще он делает, как обычно lemon -s
, Почему это происходит?