Syntax error Yacc&Lex

Нужно написать синтаксический и лексический анализаторы для определенного типа файлов и сохранить необходимую информацию. Но даже не выходит получить список цифр из тестового файла

test.txt

port (
     3,  5,  7,
     9, 11, 13,
    15, 17, 19
);

Для лексического анализа использую простые правила

lex.l

%{
#include <stdio.h>
#include "y.tab.h"
%}

delim [ \t\n]
ws {delim}+
digit [0-9]
number {digit}+
sym [a-zA-z]

%%
port { return PORT; }
"(" { return OBRACE; }
")" { return CBRACE; }
";" { return SEMICOLON; }
"," { return COMMA; }
{delim} {}
{number} { yylval.ival = atoi(yytext); return NUMBER; }
%%

int yywrap (void)
{
    return 1;
}

Для синтаксического анализа приходится использовать рекурсию

yacc.y

%{
#include <stdio.h>
#include <stdlib.h>

extern int yylex();
extern char *yytext;
int ports[9];
int curPort = 0;
%}

%union {
    int ival;
    char *cval;
}

%token NUMBER;
%token PORT OBRACE CBRACE COMMA SEMICOLON

%type <ival> exp NUMBER

%%
commands: /* empty */
    | commands command
    ;

command:
    ports_set
    ;

ports_set:
    OBRACE exp CBRACE SEMICOLON
    ;

exp: 
    NUMBER { $$ = $1; }
    | exp COMMA NUMBER { ports[curPort++] = $3; }
    ;
%%

extern FILE *yyin;

int main (int argc, char **argv)
{
    yyin = fopen("text.txt", "r");
    do {
        yyparse();
    } while (!feof(yyin));
    
    fclose(yyin);

    int i;
    for (i = 0; i < 9; ++i) {
        printf("port %d: %d\n", i, ports[i]);   
    }
}

int yyerror(char const *s)
{
    printf("ERROR: %s\n", s);
    return 0;
}

В результате получаю ошибку и массив ports c нулевыми значениями

$ ./test.exe
ERROR: syntax error
port 0: 0
port 1: 0
port 2: 0
port 3: 0
port 4: 0
port 5: 0
port 6: 0
port 7: 0
port 8: 0

Ответы (1 шт):

Автор решения: Sergey

Раз выдаёт "ERROR: syntax error", значит анализируемый файл не соответствует синтаксису. Я бы рекомендовал поставить обработку ошибки, в которой распечатывается строка анализируемого файла и токен, вызвавший ошибку.

В чём ошибка синтаксического описания грамматики? Не уверен, но мне кажется - у Вас в грамматике отсутствует главное правило. О том, что Ваш файл это:

port OBRACE commands CBRACE

И с точками с запятой - перебор, IMHO.

→ Ссылка