picrin/src/parse.y

290 lines
4.3 KiB
Plaintext
Raw Normal View History

2013-10-11 02:18:37 -04:00
%{
#include <stdlib.h>
#include <stdio.h>
#include "picrin.h"
2013-10-19 23:34:57 -04:00
#include "picrin/pair.h"
2013-11-04 22:38:23 -05:00
#include "picrin/blob.h"
2013-10-11 02:18:37 -04:00
2013-10-17 04:57:12 -04:00
#define YYERROR_VERBOSE 1
2013-10-11 02:18:37 -04:00
struct parser_control {
pic_state *pic;
2013-10-22 14:45:57 -04:00
void *yyscanner;
2013-10-11 02:18:37 -04:00
pic_value value;
2013-10-17 07:48:50 -04:00
bool incomp;
2013-10-22 14:13:10 -04:00
int yynerrs;
2013-10-11 02:18:37 -04:00
};
void yyerror(struct parser_control *, const char *);
2013-10-22 14:45:57 -04:00
/* just for supressing warnings. a little bit evil */
int yylex();
int yylex_();
void yylex_init();
2013-10-27 05:38:41 -04:00
void yyset_in();
2013-10-22 14:45:57 -04:00
void yy_scan_string();
void yylex_destroy();
2013-10-11 02:18:37 -04:00
%}
2013-10-22 14:13:10 -04:00
%pure_parser
2013-10-11 02:18:37 -04:00
%parse-param {struct parser_control *p}
%lex-param {struct parser_control *p}
%union {
int i;
double f;
char *cstr;
2013-11-04 21:37:18 -05:00
char c;
2013-11-04 22:38:23 -05:00
struct {
char *dat;
int len, capa;
} blob;
2013-10-11 02:18:37 -04:00
pic_value datum;
}
2013-11-10 21:57:01 -05:00
%token tLPAREN tRPAREN tLBRACKET tRBRACKET tDOT tVPAREN
2013-10-22 23:39:48 -04:00
%token tQUOTE tQUASIQUOTE tUNQUOTE tUNQUOTE_SPLICING
%token <i> tINT tBOOLEAN
%token <f> tFLOAT
%token <cstr> tSYMBOL tSTRING
2013-11-04 21:37:18 -05:00
%token <c> tCHAR
2013-11-04 22:38:23 -05:00
%token <blob> tBYTEVECTOR
2013-10-11 02:18:37 -04:00
%type <datum> program_data
2013-10-20 21:48:03 -04:00
%type <datum> datum simple_datum compound_datum abbrev
2013-10-29 02:51:37 -04:00
%type <datum> list list_data vector vector_data
2013-10-11 02:18:37 -04:00
%%
program
: program_data
2013-10-11 02:18:37 -04:00
{
p->value = $1;
2013-10-11 02:18:37 -04:00
}
| incomplete_program_data
2013-10-17 07:48:50 -04:00
{
p->incomp = true;
p->value = pic_undef_value();
}
2013-11-13 03:37:05 -05:00
| /* empty line */
{
p->value = pic_nil_value();
}
2013-10-11 02:18:37 -04:00
;
program_data
: datum
{
$$ = pic_cons(p->pic, $1, pic_nil_value());
}
| datum program_data
{
$$ = pic_cons(p->pic, $1, $2);
}
;
incomplete_program_data
: incomplete_datum
| datum incomplete_program_data
;
2013-10-11 02:18:37 -04:00
datum
: simple_datum
| compound_datum
;
simple_datum
: tSYMBOL
{
2013-10-28 13:11:31 -04:00
$$ = pic_symbol_value(pic_intern_cstr(p->pic, $1));
free($1);
}
2013-10-20 21:48:03 -04:00
| tSTRING
{
$$ = pic_str_new_cstr(p->pic, $1);
free($1);
}
| tINT
{
$$ = pic_int_value($1);
}
| tFLOAT
{
$$ = pic_float_value($1);
}
| tBOOLEAN
{
$$ = pic_bool_value($1);
}
2013-11-04 21:37:18 -05:00
| tCHAR
{
$$ = pic_char_value($1);
}
2013-11-04 22:38:23 -05:00
| tBYTEVECTOR
{
$$ = pic_obj_value(pic_blob_new(p->pic, $1.dat, $1.len));
free($1.dat);
}
2013-10-16 00:17:01 -04:00
;
2013-10-11 02:18:37 -04:00
compound_datum
: list
2013-10-29 02:51:37 -04:00
| vector
2013-10-20 20:29:56 -04:00
| abbrev
2013-10-11 02:18:37 -04:00
;
list
2013-10-17 05:14:18 -04:00
: tLPAREN list_data tRPAREN
2013-10-11 02:18:37 -04:00
{
$$ = $2;
}
2013-11-10 21:57:01 -05:00
| tLBRACKET list_data tRBRACKET
{
$$ = $2;
}
2013-10-11 02:18:37 -04:00
;
2013-10-17 05:14:18 -04:00
list_data
: /* none */
2013-10-11 02:18:37 -04:00
{
$$ = pic_nil_value();
}
2013-10-17 05:14:18 -04:00
| datum tDOT datum
2013-10-11 02:18:37 -04:00
{
$$ = pic_cons(p->pic, $1, $3);
}
2013-10-17 05:14:18 -04:00
| datum list_data
2013-10-11 02:18:37 -04:00
{
$$ = pic_cons(p->pic, $1, $2);
}
;
2013-10-29 02:51:37 -04:00
vector
: tVPAREN vector_data tRPAREN
{
$$ = pic_obj_value(pic_vec_new_from_list(p->pic, $2));
}
;
vector_data
: /* none */
{
$$ = pic_nil_value();
}
| datum vector_data
{
$$ = pic_cons(p->pic, $1, $2);
}
;
2013-10-20 20:29:56 -04:00
abbrev
: tQUOTE datum
{
$$ = pic_list(p->pic, 2, pic_symbol_value(p->pic->sQUOTE), $2);
2013-10-22 23:39:48 -04:00
}
| tQUASIQUOTE datum
{
$$ = pic_list(p->pic, 2, pic_symbol_value(p->pic->sQUASIQUOTE), $2);
2013-10-22 23:39:48 -04:00
}
| tUNQUOTE datum
{
$$ = pic_list(p->pic, 2, pic_symbol_value(p->pic->sUNQUOTE), $2);
2013-10-22 23:39:48 -04:00
}
| tUNQUOTE_SPLICING datum
{
$$ = pic_list(p->pic, 2, pic_symbol_value(p->pic->sUNQUOTE_SPLICING), $2);
2013-10-20 20:29:56 -04:00
}
;
2013-10-17 07:48:50 -04:00
incomplete_datum
2013-10-26 13:06:59 -04:00
: tLPAREN incomplete_data
2013-11-10 21:57:01 -05:00
| tLBRACKET incomplete_data
2013-10-29 02:51:37 -04:00
| tVPAREN incomplete_data
2013-10-22 23:39:48 -04:00
| incomplete_abbrev
2013-10-17 07:48:50 -04:00
;
2013-10-26 13:06:59 -04:00
incomplete_tail
: /* none */
| incomplete_datum
;
2013-10-17 07:48:50 -04:00
incomplete_data
2013-10-26 13:06:59 -04:00
: incomplete_tail
| datum tDOT incomplete_tail
2013-10-17 07:48:50 -04:00
| datum incomplete_data
;
2013-10-22 23:39:48 -04:00
incomplete_abbrev
2013-10-26 13:06:59 -04:00
: tQUOTE incomplete_tail
| tQUASIQUOTE incomplete_tail
| tUNQUOTE incomplete_tail
| tUNQUOTE_SPLICING incomplete_tail
2013-10-22 23:39:48 -04:00
;
2013-10-11 02:18:37 -04:00
%%
2013-10-19 14:05:42 -04:00
void
2013-10-11 02:18:37 -04:00
yyerror(struct parser_control *p, const char *msg)
{
puts(msg);
2013-10-22 14:13:10 -04:00
p->yynerrs++;
2013-10-11 02:18:37 -04:00
}
2013-10-22 14:45:57 -04:00
int
yylex(YYSTYPE *yylvalp, struct parser_control *p)
{
return yylex_(yylvalp, p->yyscanner);
2013-10-22 14:45:57 -04:00
}
int
2013-10-27 05:38:41 -04:00
pic_parse_file(pic_state *pic, FILE *file, pic_value *v)
{
struct parser_control p;
p.pic = pic;
p.incomp = false;
p.yynerrs = 0;
yylex_init(&p.yyscanner);
yyset_in(file, p.yyscanner);
yyparse(&p);
yylex_destroy(p.yyscanner);
if (p.yynerrs > 0) {
p.value = pic_undef_value();
2013-11-13 03:37:05 -05:00
return PIC_PARSER_ERROR;
2013-10-27 05:38:41 -04:00
}
if (p.incomp) {
2013-11-13 03:37:05 -05:00
return PIC_PARSER_INCOMPLETE;
2013-10-27 05:38:41 -04:00
}
*v = p.value;
return pic_length(pic, p.value);
2013-10-27 05:38:41 -04:00
}
2013-11-13 03:37:05 -05:00
enum pic_parser_res
2013-10-27 05:38:41 -04:00
pic_parse_cstr(pic_state *pic, const char *str, pic_value *v)
2013-10-11 02:18:37 -04:00
{
struct parser_control p;
p.pic = pic;
2013-10-17 07:48:50 -04:00
p.incomp = false;
2013-10-22 14:13:10 -04:00
p.yynerrs = 0;
2013-10-11 02:18:37 -04:00
2013-10-22 14:45:57 -04:00
yylex_init(&p.yyscanner);
yy_scan_string(str, p.yyscanner);
2013-10-11 02:18:37 -04:00
yyparse(&p);
2013-10-22 14:45:57 -04:00
yylex_destroy(p.yyscanner);
2013-10-11 02:18:37 -04:00
2013-10-22 14:13:10 -04:00
if (p.yynerrs > 0) {
2013-11-13 03:37:05 -05:00
return PIC_PARSER_ERROR;
2013-10-17 04:57:12 -04:00
}
if (p.incomp) {
2013-11-13 03:37:05 -05:00
return PIC_PARSER_INCOMPLETE;
2013-10-17 07:48:50 -04:00
}
*v = p.value;
return pic_length(pic, p.value);
2013-10-11 02:18:37 -04:00
}