Skip to content

Instantly share code, notes, and snippets.

@hasherezade
Created May 28, 2015 18:28
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hasherezade/aa0fd5d16fd9cc0e9391 to your computer and use it in GitHub Desktop.
Save hasherezade/aa0fd5d16fd9cc0e9391 to your computer and use it in GitHub Desktop.
BrainfuckToC (Flex & Bison)
%{
#include "brainfuck.tab.h"
#include <string.h>
#include <stdlib.h>
void error()
{
fprintf(stdout, "Plik niepoprawny pod wzglêdem leksykalnym. Linia: %d\n", yylineno);
exit(1);
}
%}
INT [0-9]+
ID [A-Za-z][A-Za-z0-9]*
%%
">" {
yylval=1;
return POINTER;
}
"<" {
yylval=-1;
return POINTER;
}
"+" {
yylval=1;
return VALUE;
}
"-" {
yylval=-1;
return VALUE;
}
"[" {
return LOOP_BEGIN;
}
"]" {
return LOOP_END;
}
"," {
return INPUT;
}
"." {
return OUTPUT;
}
[ \t] { /* Nic */ }
[\n] { return yytext[0]; }
. { yylval=yytext[0]; return COMMENT; }
%%
%{
#include <stdio.h>
#include <strings.h>
#define BUF_MAX 3000
int pointerPos=0;
//---------------------------------------
int pointerStack[BUF_MAX];
int stackIndex=-1;
int pointerPush(int pos){
if(stackIndex>=BUF_MAX)
return -1; //failor
stackIndex++;
pointerStack[stackIndex]=pos;
return 1; //success
}
int pointerPop(){
if(stackIndex==-1) return -1; //failor
int p = pointerStack[stackIndex];
stackIndex--;
return p;
}
//----------------------------------------
int ind=1;
void printInd(){
int i=0;
for(i=0;i<ind;i++){
printf("\t");
}
}
//----------------------------------------
void printHeader(){
printf("\
#include <stdio.h>\n\
#define BUF_MAX 3000\n\
int buffer[BUF_MAX];\n\n\
main(){\n \
\tint *ptr=&buffer[0];\n"
);
}
void printFooter(){
printf("}\n");
}
//----------------------------------------
%}
%token POINTER VALUE INPUT OUTPUT LOOP_BEGIN LOOP_END COMMENT
%%
input: /* nic */
| input commands
;
pointer_ch : pointer_ch POINTER { $$ = $1 + $2 }
| POINTER
;
value_ch : value_ch VALUE { $$ = $1 + $2 }
| VALUE
;
commands : commands pointer_ch {
pointerPos=pointerPos+$2;
printInd();
int chVal=$2;
char sign='+';
if(chVal!=0){
if(chVal<0){
sign='-';
chVal*=(-1);
}
if(chVal==1) printf("ptr%c%c;\t\t",sign,sign);
else printf("ptr%c=%d;\t\t",sign,chVal);
}
printf("//ptr=&buffer[%d]\n",pointerPos);
}
| commands value_ch {
printInd();
int chVal=$2;
char sign='+';
if(chVal!=0){
if(chVal<0){
sign='-';
chVal*=(-1);
}
if(chVal==1) printf("(*ptr)%c%c;\t\t//buffer[%d]%c%c\n",sign, sign, pointerPos,sign,sign);
else printf("(*ptr)%c=%d;\t\t//buffer[%d]%c=%d\n",sign, chVal,pointerPos,sign,chVal);
}
}
| commands INPUT {
printInd();
printf("(*ptr)=getchar();");
printf("\t\t//buffer[%d]=getchar();",pointerPos);
printf("\n");
}
| commands OUTPUT {
printInd();
printf("putchar(*ptr);");
printf("\t\t//putchar(buffer[%d]);",pointerPos);
printf("\n");
}
| commands loop
| commands '\n'
| commands comments { printf("/*comment*/\n"); };
| /**/
;
loop : loop_b commands loop_e
;
loop_b : LOOP_BEGIN {
putchar('\n');
printInd();
printf("while(*ptr){");
ind++;
pointerPush(pointerPos);
printf("\t\t//while(buffer[%d]){",pointerPos);
printf("\n");
}
loop_e : LOOP_END {
ind--;
printInd();
printf("}");
printf("\t\t//while(buffer[%d]);",pointerPos);
int outP=pointerPop();
if(outP==pointerPos)
printf("while OK!\n");
else
printf("while not OK\n");
printf("\n\n"); }
comments: comments COMMENT
| COMMENT
;
%%
main()
{
printHeader();
yyparse();
printFooter();
}
yyerror(s)
char *s;
{
fprintf(stderr, "%s\n", s);
}
#
# Ogolny makefile do specyfikacji dla Flexa i Bisona
#
# Programy do wygenerowania ze specyfikacji dla Yacc'a
YACC = $(patsubst %.y, %, $(wildcard [a-z]*.y))
# Programy do wygenerowania (tylko) ze specyfikacji dla Lex'a
LEX = $(filter-out $(YACC), $(patsubst %.l, %, $(wildcard [a-z]*.l)))
# Wszystkie programy do wygenerowania
EXE = $(LEX) $(YACC)
# Kody po¶rednie skanerów zale¿nych tylko od specyfikacji skanera
OBJL = $(patsubst %, %.yy.o, $(LEX))
# Kody po¶rednie skanerów zale¿nych od specyfikacji skanera i pliku nag³ówkowego parsera
OBJLY = $(patsubst %, %.yy.o, $(YACC))
all: $(EXE)
echo $(OBJLY)
%.yy.c: %.l
flex -o$*.yy.c $*.l
%.tab.c %.tab.h: %.y
bison -d $*.y
%.tab.o: %.tab.c
gcc -c $*.tab.c
$(OBJL): %.yy.o : %.yy.c
gcc -c $*.yy.c
$(OBJLY): %.yy.o : %.yy.c %.tab.h
gcc -c $*.yy.c
$(LEX): %: %.yy.o
gcc -o $* $*.yy.o -lfl
$(YACC): %: %.yy.o %.tab.o
gcc -o $* $*.yy.o $*.tab.o -lfl
.PHONY: clean mrproper
mrproper: clean
rm -f $(EXE)
clean:
rm -f *~
rm -f *.yy.c
rm -f *.tab.c
rm -f *.tab.h
rm -f *.o
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment