Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- lexer.l
- %option reentrant noyywrap bison-bridge bison-locations
- %option extra-type="struct Extra *"
- %{
- #include <stdio.h>
- #include <stdlib.h>
- #include "lexer.h"
- #include "parser.tab.h"
- #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);
- }
- %}
- QUOTE ["]
- CHAR [a-zA-Z0-9_\/\\.]
- CHARS {CHAR}+
- STRING {QUOTE}{QUOTE}|{QUOTE}{CHARS}{QUOTE}
- DIGIT [0-9]
- DIGIT1TO9 [1-9]
- DIGITS {DIGIT}+
- INT {DIGIT}|{DIGIT1TO9}{DIGITS}|-{DIGIT}|-{DIGIT1TO9}{DIGITS}
- FRAC [.]{DIGITS}
- E [eE][+-]?
- EXP [E]{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->ident = yytext; return STRING; }
- {NUMBER} { yylval->ident = 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);
- }
- parser.y
- %{
- #include <stdio.h>
- #include "lexer.h"
- %}
- %define api.pure
- %locations
- %lex-param {yyscan_t scanner}
- %parse-param {yyscan_t scanner}
- %parse-param {long env[26]}
- %union {
- char ident;
- long num;
- }
- %token NUMBER
- %token <ident> STRING
- %token VAL_TRUE VAL_FALSE VAL_NULL
- %left OBJ_BEG OBJ_END ARR_BEG ARR_END
- %left SYM_COMMA
- %left SYM_COLON
- %type<ident> 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: ARRAY { printf("%s\n", $1); }
- | OBJECT { printf("%s\n", $1); }
- ;
- OBJECT: OBJ_BEG OBJ_END { $$ = $1; }
- | OBJ_BEG MEMBERS OBJ_END { printf("{%s}\n", $2); }
- ;
- MEMBERS: PAIR { $$ = $1; }
- | PAIR SYM_COMMA MEMBERS { printf("%s,%s\n", $1, $3); }
- ;
- PAIR: STRING SYM_COLON VALUE { printf("%s:%s\n", $1, $3); }
- ;
- ARRAY: ARR_BEG ARR_END { $$ = (char*)malloc(sizeof(char)*(2+1)); }
- | ARR_BEG ELEMENTS ARR_END { printf("[%s]\n", $2); }
- ;
- ELEMENTS: VALUE { $$ = $1; }
- | VALUE SYM_COMMA ELEMENTS { printf("%s,%s\n", $1, $3); }
- ;
- VALUE: STRING { $$ = yylval.ident; }
- | NUMBER { $$ = yylval.ident; }
- | OBJECT { $$ = $1; }
- | ARRAY { $$ = $1; }
- | VAL_TRUE { $$ = "true"; }
- | VAL_FALSE { $$ = "false"; }
- | VAL_NULL { $$ = "null"; }
- ;
- %%
- #define PROG "{ \"param\":\"yes\", \"da\":true}"
- int main()
- {
- yyscan_t scanner;
- struct Extra extra;
- long env[26];
- init_scanner(PROG, &scanner, &extra);
- yyparse(scanner, env);
- destroy_scanner(scanner);
- return 0;
- }
- lexer.h
- #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