My first programming challenge

by mucky

mucky
Junior Member
Kohai
Posts: 5
Threads: 2
Joined: Sep 2017
Reputation: 0
10-02-2017, 12:38 PM
#73214 (1)
It is a beginner implementation of some of what you can read in Language Implementation Patterns by Terence Parr.

The goal is to implement a LL(0) parser for Brainfuck. It just returns 1 if the code isn't valid and 0 if it is.

Note that it could become a recursive-descent parser if it was to parse more complicated grammars. That would just be an like an extent.

I implemented it in C. No compilation flag needed. Here is my code:

Code:
#include <stdio.h>
#include <stdlib.h>

int my_strlen(char *m) {
 int i = 0;
 while (m[i++] != '\0');
 return i;
}

void my_strcpy(char *to, char *from) {
 while ((*(to++) = *(from++)) != '\0');
}

void consume(char **p, char *t) {
 if (**p == '\0') return;
 if (**p == *t) (*p)++;
}

int abs(int i) {
 if (i < 0) return (i * (-1));
 else return i;
}

int expression(char **p) {
 static int loops;
 switch (**p) {
   case '+':
   case '-':
   case '.':
   case ',':
   case '<':
   case '>':
     consume(p, *p);
     break;
   case '[':
     consume(p, "[");
     loops++;
     break;
   case ']':
     consume(p, "]");
     loops--;
     if (loops < 0) {
       exit(1);
     }
     break;
   default:
     exit(1);
 }
 return loops;
}

void whole(char **p) {
 int loops;
 while (**p != '\0') {
   loops = expression(p);
 }
 if (loops > 0) {
   exit(1);
 }
}

int main(int argc, char *argv[]) {
 if (argc < 2) {
   printf("Feed me argument.\nFor example: ++[[-]].");
   exit(1);
 }
 char *f = malloc(sizeof(char) * my_strlen(argv[1]));
 my_strcpy(f, argv[1]);
 char *bf = argv[1];
 whole(&bf);
 return 0;
}

If you're using bash, use the following to output the return code of the program:

Code:
echo $?


Waiting for your codes ! Any language.
ayyyLmaoNekos
Junior Member
Kohai
Posts: 5
Threads: 1
Joined: May 2018
Reputation: 1
05-22-2018, 12:16 PM (This post was last modified: 05-22-2018, 12:17 PM by ayyyLmaoNekos.)
#77836 (2)
This was way easier than expected now I am trying to do an interpreter however loops ([]) are giving me some trouble.
As for your code I have two suggestions,
1. Don't re-implement standard library routines - you linked them to your executable so you might as well use them and they are probably better than your implementation by both speed and bugs.
2. Don't break your code up into little functions unnecessarily - it just makes things messy and doesn't simplify your code
Code:
#include <stdio.h>

int main(int argc, char const *argv[]) {
   if (argc < 2) {
       printf("Need at least one argument\n");
       return 1;
   }

   FILE *fp = fopen(argv[1], "r");
   if (fp == NULL) {
       printf("Can't open %s\n", argv[1]);
       return 1;
   }

   char c = 0, bracket = 0;
   while ((c = getc(fp)) != EOF) {
       switch (c) {
           case '<':
           case '>':
           case '+':
           case '-':
           case '.':
           case ',':
           break;
           case ']':
           bracket--;
           if (bracket < 0) {
               goto end;
           }
           break;
           case '[':
           bracket++;
           break;
       }
   }
   end:

   if (bracket != 0) {
       return 1;
   }

   return 0;
}

Forums are cool