Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %option reentrant noyywrap bison-bridge bison-locations
- %option extra-type="struct Extra *"
- %{
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "lexer.h"
- #include "parser.tab.h"
- #define FLOAT_TYPENAME "float"
- #define INT_TYPENAME "int"
- #define YY_USER_ACTION \
- { \
- int i; \
- struct Extra *extra = yyextra; \
- if (! extra->continued) { \
- yylloc->first_line = extra->cur_line; \
- yylloc->first_column = extra->cur_column; \
- } \
- extra->continued = 0; \
- for (i = 0; i < yyleng; i++) \
- { \
- if (yytext[i] == '\n') \
- { \
- extra->cur_line++; \
- extra->cur_column = 1; \
- } \
- else \
- extra->cur_column++; \
- } \
- \
- yylloc->last_line = extra->cur_line; \
- yylloc->last_column = extra->cur_column; \
- }
- void yyerror(YYLTYPE *loc, yyscan_t scanner, long env[26], char *msg)
- {
- printf("Error (%d,%d): %s\n", loc->first_line, loc->first_column, msg);
- }
- %}
- CHAR [a-zA-Z0-9_\/\\.]
- STRING ["]["]|["]{CHAR}+["]
- DIGIT [0-9]
- DIGIT1TO9 [1-9]
- DIGITS {DIGIT}+
- INT {DIGIT}|{DIGIT1TO9}{DIGITS}|-{DIGIT}|-{DIGIT1TO9}{DIGITS}
- FRAC [.]{DIGITS}
- EXP [eE][+-]?{DIGITS}
- NUMBER {INT}|{INT}{FRAC}|{INT}{EXP}|{INT}{FRAC}{EXP}
- %%
- [ \n\t]+
- true { return VAL_TRUE; }
- false { return VAL_FALSE; }
- null { return VAL_NULL; }
- {STRING} { yylval->string = strdup(yytext); return STRING; }
- {NUMBER} {
- if (strchr(yytext, '.')) {
- yylval->number.typeName = FLOAT_TYPENAME;
- yylval->number.numData.numFloat = atof(yytext);
- } else {
- yylval->number.typeName = INT_TYPENAME;
- yylval->number.numData.numInt = atoi(yytext);
- }
- return NUMBER;
- }
- \{ { return OBJ_BEG; }
- \} { return OBJ_END; }
- \[ { return ARR_BEG; }
- \] { return ARR_END; }
- : { return SYM_COLON; }
- , { return SYM_COMMA; }
- %%
- void init_scanner(char *program, yyscan_t *scanner, struct Extra *extra)
- {
- extra->continued = 0;
- extra->cur_line = 1;
- extra->cur_column = 1;
- yylex_init(scanner);
- yylex_init_extra(extra, scanner);
- yy_scan_string(program, *scanner);
- }
- void destroy_scanner(yyscan_t scanner)
- {
- yylex_destroy(scanner);
- }
- %{
- #include <stdio.h>
- #include <string.h>
- #include "lexer.h"
- #define MEM(size) ((char *)malloc(sizeof(char) * (size + 1)))
- #define FLOAT_TYPENAME "float"
- #define INT_TYPENAME "int"
- %}
- %define api.pure
- %locations
- %lex-param {yyscan_t scanner}
- %parse-param {yyscan_t scanner}
- %parse-param {long env[26]}
- %union {
- char *string;
- struct number {
- char *typeName;
- union numData {
- int numInt;
- float numFloat;
- } numData;
- } number;
- }
- %token <string> STRING
- %token <number> NUMBER
- %token VAL_TRUE VAL_FALSE VAL_NULL
- %left OBJ_BEG OBJ_END ARR_BEG ARR_END
- %left SYM_COMMA
- %left SYM_COLON
- %start START
- %type<string> OBJECT ARRAY OBJ_BEG OBJ_END ARR_BEG ARR_END MEMBERS PAIR ELEMENTS VALUE
- %{
- int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param , yyscan_t scanner);
- void yyerror(YYLTYPE *yylloc, yyscan_t scanner, long env[26], char *msg);
- %}
- %%
- START: OBJECT { printf("%s\n", $1); }
- ;
- OBJECT: OBJ_BEG OBJ_END { $$ = "{}\n"; }
- | OBJ_BEG MEMBERS OBJ_END { $$ = MEM(2+strlen($2)+2); sprintf($$,"{ %s }",$2); }
- ;
- MEMBERS: PAIR { $$ = $1; }
- | PAIR SYM_COMMA MEMBERS { $$ = MEM(strlen($1)+2+strlen($3)); sprintf($$,"%s, %s",$1,$3); }
- ;
- PAIR: STRING SYM_COLON VALUE { $$ = MEM(strlen($1)+2+strlen($3)); sprintf($$,"%s: %s",$1,$3); }
- ;
- ARRAY: ARR_BEG ARR_END { $$ = MEM(2); sprintf($$,"[]"); }
- | ARR_BEG ELEMENTS ARR_END { $$ = MEM(2+strlen($2)+2); sprintf($$,"[ %s ]",$2); }
- ;
- ELEMENTS: VALUE { $$ = $1; }
- | VALUE SYM_COMMA ELEMENTS { $$ = MEM(strlen($1)+2+strlen($3)); sprintf($$,"%s, %s",$1,$3); }
- ;
- VALUE: OBJECT { $$ = $1; }
- | ARRAY { $$ = $1; }
- | STRING { $$ = yylval.string; }
- | NUMBER {
- if (0 == strcmp(yylval.number.typeName, INT_TYPENAME)) {
- $$ = malloc(sizeof(int) * 1);
- sprintf($$, "%d", yylval.number.numData.numInt);
- } else {
- $$ = malloc(sizeof(float) * 1);
- sprintf($$, "%f", yylval.number.numData.numFloat);
- }
- }
- | VAL_TRUE { $$ = "true"; }
- | VAL_FALSE { $$ = "false"; }
- | VAL_NULL { $$ = "null"; }
- ;
- %%
- #define INPUT_JSON \
- "{ \
- \"versionFloat\": 13.37, \
- \"versionInt\": 13, \
- \"background\": \
- { \
- \"scripts\": [\"jquery214.js\", \"background.js\"], \
- \"persistent\": false \
- }, \
- \"content_scripts\": \
- { \
- \"matches\": \
- { \
- \"all_urls\": true \
- }, \
- \"js\": [], \
- \"run_at\": \"document_end\" \
- } \
- }"
- int main()
- {
- yyscan_t scanner;
- struct Extra extra;
- long env[26];
- init_scanner(INPUT_JSON, &scanner, &extra);
- yyparse(scanner, env);
- destroy_scanner(scanner);
- return 0;
- }
- #ifndef _LEXER_H_INCLUDED
- #define _LEXER_H_INCLUDED
- #ifndef YY_TYPEDEF_YY_SCANNER_T
- #define YY_TYPEDEF_YY_SCANNER_T
- typedef void *yyscan_t;
- #endif
- struct Extra {
- int continued;
- int cur_line;
- int cur_column;
- };
- void init_scanner(char *program, yyscan_t *scanner, struct Extra *extra);
- void destroy_scanner(yyscan_t scanner);
- #endif
Advertisement
Add Comment
Please, Sign In to add comment