Skip to content

Instantly share code, notes, and snippets.

@wolf0403
Forked from justjkk/LICENSE
Created February 26, 2012 22:08
Show Gist options
  • Save wolf0403/1919294 to your computer and use it in GitHub Desktop.
Save wolf0403/1919294 to your computer and use it in GitHub Desktop.
Parsing JSON with lex and yacc
%{
#include<stdio.h>
#include "y.tab.h"
char *strclone(char *str);
/*
#define STRING "str"
#define NUMBER "number"
#define O_BEGIN "o_begin"
#define O_END "o_end"
#define A_BEGIN "a_begin"
#define A_END "a_end"
#define COMMA "comma"
*/
%}
DIGIT1to9 [1-9]
DIGIT [0-9]
DIGITS {DIGIT}+
INT {DIGIT}|{DIGIT1to9}{DIGITS}|-{DIGIT}|-{DIGIT1to9}{DIGITS}
FRAC [.]{DIGITS}
EXP {E}{DIGITS}
E [eE][+-]?
HEX_DIGIT [0-9a-f]
NUMBER {INT}|{INT}{FRAC}|{INT}{EXP}|{INT}{FRAC}{EXP}
UNESCAPEDCHAR [ -!#-\[\]-~]
ESCAPEDCHAR \\["\\bfnrt/]
UNICODECHAR \\u{HEX_DIGIT}{HEX_DIGIT}{HEX_DIGIT}{HEX_DIGIT}
CHAR {UNESCAPEDCHAR}|{ESCAPEDCHAR}|{UNICODECHAR}
CHARS {CHAR}+
DBL_QUOTE ["]
%%
{DBL_QUOTE}{DBL_QUOTE} |
{DBL_QUOTE}{CHARS}{DBL_QUOTE} {
yylval=strclone(yytext);
return STRING;
};
{NUMBER} {
yylval=strclone(yytext);
return NUMBER;
}
true {
return true;
};
false {
return false;
};
null {
return null;
};
\{ {
return O_BEGIN;
};
\} {
return O_END;
};
\[ {
return A_BEGIN;
};
\] {
return A_END;
};
, {
return COMMA;
};
: {
return COLON;
};
. {
printf("Unexpected: %c\nExiting...\n",*yytext);
exit(0);
}
%%
char *strclone(char *str)
{
int len = strlen(str);
char *clone = (char *)malloc(sizeof(char)*(len+1));
strcpy(clone,str);
return clone;
}
%{
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define YYSTYPE char*
char *strconcat(char *str1, char *str2);
%}
%token NUMBER
%token STRING
%token true false null
%left O_BEGIN O_END A_BEGIN A_END
%left COMMA
%left COLON
%%
START: ARRAY {
printf("%s",$1);
}
| OBJECT {
printf("%s",$1);
}
;
OBJECT: O_BEGIN O_END {
$$ = "{}";
}
| O_BEGIN MEMBERS O_END {
$$ = (char *)malloc(sizeof(char)*(1+strlen($2)+1+1));
sprintf($$,"{%s}",$2);
}
;
MEMBERS: PAIR {
$$ = $1;
}
| PAIR COMMA MEMBERS {
$$ = (char *)malloc(sizeof(char)*(strlen($1)+1+strlen($3)+1));
sprintf($$,"%s,%s",$1,$3);
}
;
PAIR: STRING COLON VALUE {
$$ = (char *)malloc(sizeof(char)*(strlen($1)+1+strlen($3)+1));
sprintf($$,"%s:%s",$1,$3);
}
;
ARRAY: A_BEGIN A_END {
$$ = (char *)malloc(sizeof(char)*(2+1));
sprintf($$,"[]");
}
| A_BEGIN ELEMENTS A_END {
$$ = (char *)malloc(sizeof(char)*(1+strlen($2)+1+1));
sprintf($$,"[%s]",$2);
}
;
ELEMENTS: VALUE {
$$ = $1;
}
| VALUE COMMA ELEMENTS {
$$ = (char *)malloc(sizeof(char)*(strlen($1)+1+strlen($3)+1));
sprintf($$,"%s,%s",$1,$3);
}
;
VALUE: STRING {$$=yylval;}
| NUMBER {$$=yylval;}
| OBJECT {$$=$1;}
| ARRAY {$$=$1;}
| true {$$="true";}
| false {$$="false";}
| null {$$="null";}
;
%%
int main()
{
printf("\n");
yyparse();
printf("\n");
return 0;
}
int yywrap()
{
return 1;
}
char *strconcat(char *str1, char *str2)
{
int len1 = strlen(str1);
int len2 = strlen(str2);
char *str3 = (char *)malloc(sizeof(char)*(len1+len2+1));
strcpy(str3,str1);
strcpy(&(str3[len1]),str2);
return str3;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment