Skip to content

Instantly share code, notes, and snippets.

@zsrkmyn
Created June 25, 2019 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zsrkmyn/aadfa6a859054be8bd5c52e7bde3c328 to your computer and use it in GitHub Desktop.
Save zsrkmyn/aadfa6a859054be8bd5c52e7bde3c328 to your computer and use it in GitHub Desktop.
dcl
/*
* My 'dcl' implementation of <the C programming language> chap 5.12.
* Slightly different from the given implementation.
*
* Using left recursion elimination to expand 'dirdcl':
* dcl -> optional *'s dirdcl
* dirdcl -> name
* | (dcl)
* | dirdcl()
* | dirdcl[optional size]
*
* V
*
* dcl -> optional *'s dirdcl
* dirdcl -> name dirdcl2
* | (dcl) dirdcl2
* dirdcl2 -> () dirdcl
* | [optional size] dirdcl
* | \epsilon
*
* Usage:
* cc dcl.c -o dcl
* echo 'int (*(*x())[])()' | ./dcl
*
* Author: Senran Zhang
* Date: Jun. 26, 2019
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
static
char cur = ' ';
static
char tok_str[512];
static
char tok_type;
static
void gettok()
{
while (isspace(cur))
cur = getchar();
if (isalpha(cur) || cur == '_') {
int i = 0;
do {
tok_str[i++] = cur;
cur = getchar();
} while (isalnum(cur) || cur == '_');
tok_str[i] = 0;
tok_type = -2;
return;
}
if (isdigit(cur)) {
int i = 0;
do {
tok_str[i++] = cur;
cur = getchar();
} while (isdigit(cur));
tok_str[i] = 0;
tok_type = -3;
return;
}
tok_type = cur;
cur = getchar();
}
static void dcl();
static void dirdcl();
static
void dcl()
{
int ns = 0;
while (tok_type == '*') {
ns++;
gettok();
}
dirdcl();
while (ns--)
printf(" pointer to");
}
static
void dirdcl2()
{
if (tok_type == '[') {
fputs(" array[", stdout);
gettok();
if (tok_type == -2 || tok_type == -3) {
fputs(tok_str, stdout);
gettok();
}
if (tok_type != ']') {
fprintf(stderr, "\nUnclosed branket!\n");
exit(-1);
}
fputs("] of", stdout);
} else if (tok_type == '(') {
// TODO: add arguments
gettok();
if (tok_type != ')') {
fprintf(stderr, "\nUnclosed parenthese!\n");
exit(-1);
}
fputs(" function returning", stdout);
} else {
fprintf(stderr, "\nInvalid syntax! line %d\n", __LINE__);
exit(-1);
}
gettok();
if (tok_type != EOF && tok_type != ')') {
dirdcl();
}
}
static
void dirdcl()
{
if (tok_type == '(') {
gettok();
dcl();
if (tok_type != ')') {
fprintf(stderr, "\nUnclosed parenthese!\n");
exit(-1);
}
} else if (tok_type == -2) {
fputs(tok_str, stdout);
putchar(':');
} else {
fprintf(stderr, "\nInvalid syntax! line %d\n", __LINE__);
exit(-1);
}
gettok();
if (tok_type == '(' || tok_type == '[') {
dirdcl2();
}
}
int main()
{
gettok();
if (tok_type != -2) {
fprintf(stderr, "\nDatetype Expected!\n");
exit(-1);
}
const char *ret_type = strdup(tok_str);
gettok();
dcl();
putchar(' ');
puts(ret_type);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment