LINUX.ORG.RU

История изменений

Исправление beastie, (текущая версия) :

Пытаясь вспомнить, всё, что я забыл:

lexer.l:

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

%%
[0-9]+      { yylval = atoi(yytext); return NUMBER; }
"("         { return LBRAKET; }
")"         { return RBRAKET; }
","         { return COMA; }
[ \n\t\r]   {}

%%

int
yywrap(void){
	return 1;
}

parser.y:

// declarations
%{
#include <stdio.h>
#include <stdarg.h>

int yylex(void);
void yyerror(const char *, ...);
int i;
int n;
int numbers[100];
%}

%%
// rules
%token NUMBER LBRAKET RBRAKET COMA;

expression	: /* empty */
		| paris
		| expression COMA paris
		;

paris		: NUMBER LBRAKET list RBRAKET
		{
			for (i = 0; i < n; i++) {
				printf("%d_%d\n", $1, numbers[i]);
			}
		}
		;

list		: NUMBER
		{
			n = 0;
			numbers[n++] = $1;
		}
		| list COMA NUMBER
		{
			numbers[n++] = $3;
		}
		;

%%
#include "lex.yy.c"

int main() {
	yyparse();
	return 0;
}

void
yyerror(const char *s, ...)
{
	va_list ap;
	va_start(ap, s);
	vfprintf(stderr, s, ap);
	fprintf(stderr, "\n");
	va_end(ap);
}

Makefile:

prog: y.tab.c lex.yy.c
	$(CC) -o $@ $<

y.tab.c: parser.y
	$(YACC) -d $<

lex.yy.c: lexer.l
	$(LEX) $<

input.txt:

211(1,2,5,8),212(9,14,36)

И результат:

make && ./prog < input.txt
211_1
211_2
211_5
211_8
212_9
212_14
212_36

Исходная версия beastie, :

Пытаясь вспомнить, всё, что я забыл:

lexer.l:

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

%%
[0-9]+      { yylval = atoi(yytext); return NUMBER; }
"("         { return LBRAKET; }
")"         { return RBRAKET; }
","         { return COMA; }
[ \n\t\r]   {}

%%

int
yywrap(void){
	return 1;
}

parser.y:

// declarations
%{
#include <stdio.h>
#include <stdarg.h>

int yylex(void);
void yyerror(const char *, ...);
int i;
int n;
int numbers[100];
%}

%%
// rules
%token NUMBER LBRAKET RBRAKET COMA EOL;

expression	: /* empty */
		| paris
		| expression COMA paris
		;

paris		: NUMBER LBRAKET list RBRAKET
		{
			for (i = 0; i < n; i++) {
				printf("%d_%d\n", $1, numbers[i]);
			}
		}
		;

list		: NUMBER
		{
			n = 0;
			numbers[n++] = $1;
		}
		| list COMA NUMBER
		{
			numbers[n++] = $3;
		}
		;

%%
#include "lex.yy.c"

int main() {
	yyparse();
	return 0;
}

void
yyerror(const char *s, ...)
{
	va_list ap;
	va_start(ap, s);
	vfprintf(stderr, s, ap);
	fprintf(stderr, "\n");
	va_end(ap);
}

Makefile:

prog: y.tab.c lex.yy.c
	$(CC) -o $@ $<

y.tab.c: parser.y
	$(YACC) -d $<

lex.yy.c: lexer.l
	$(LEX) $<

input.txt:

211(1,2,5,8),212(9,14,36)

И результат:

make && ./prog < input.txt
211_1
211_2
211_5
211_8
212_9
212_14
212_36