2014-01-17 06:58:31 -05:00
|
|
|
/**
|
|
|
|
* See Copyright Notice in picrin.h
|
|
|
|
*/
|
|
|
|
|
2013-10-11 02:18:37 -04:00
|
|
|
%{
|
2013-10-11 23:07:28 -04:00
|
|
|
#include <stdlib.h>
|
2013-10-20 21:48:03 -04:00
|
|
|
#include <string.h>
|
2013-10-11 23:07:28 -04:00
|
|
|
|
2013-10-11 02:18:37 -04:00
|
|
|
#include "picrin.h"
|
2013-11-18 06:47:20 -05:00
|
|
|
#include "picrin/parse.h"
|
2013-10-11 02:18:37 -04:00
|
|
|
#include "y.tab.h"
|
|
|
|
|
2013-10-28 09:55:15 -04:00
|
|
|
#define YY_DECL int yylex_(YYSTYPE *yylvalp, yyscan_t yyscanner)
|
2014-01-30 04:10:56 -05:00
|
|
|
|
|
|
|
/* NOTE:
|
|
|
|
* An internal function `yy_fatal_error` takes yyscanner for its second
|
|
|
|
* argument but doesn't use it. This invokes a `unused variable` compiler
|
|
|
|
* warning and it became super unusable if `-Werror` is turned on the system.
|
|
|
|
* Since there's no flag to switch `yy_fatal_error` off and replace it with
|
|
|
|
* a user-defined function, we modify this macro constant to use yyscanner
|
|
|
|
* at least once avoiding get flex affected in any condition.
|
|
|
|
*/
|
|
|
|
#define YY_EXIT_FAILURE ( (void)yyscanner, 2 )
|
2013-10-11 02:18:37 -04:00
|
|
|
%}
|
|
|
|
|
2014-02-28 08:35:38 -05:00
|
|
|
%option noyyalloc
|
|
|
|
%option noyyrealloc
|
|
|
|
%option noyyfree
|
2013-10-22 14:45:57 -04:00
|
|
|
%option reentrant
|
2013-10-19 14:05:42 -04:00
|
|
|
%option noinput
|
2013-10-12 05:46:41 -04:00
|
|
|
%option nounput
|
2014-02-01 05:33:23 -05:00
|
|
|
%option extra-type="struct parser_control *"
|
2014-02-28 08:38:12 -05:00
|
|
|
%option header-file="lex.yy.h"
|
2014-01-19 03:31:03 -05:00
|
|
|
%option never-interactive
|
2013-10-12 05:46:41 -04:00
|
|
|
|
2013-10-28 00:04:24 -04:00
|
|
|
/* comment */
|
|
|
|
comment ;.*$
|
|
|
|
|
2013-10-16 00:17:01 -04:00
|
|
|
/* boolean */
|
|
|
|
boolean #t|#f|#true|#false
|
|
|
|
|
2013-10-15 21:19:16 -04:00
|
|
|
/* symbol */
|
2013-10-22 23:39:48 -04:00
|
|
|
identifier [a-z0-9A-Z+/*!$%&:@^~?<=>_.-]+
|
2013-10-15 21:19:16 -04:00
|
|
|
|
|
|
|
/* number */
|
|
|
|
digit [0-9]
|
|
|
|
real {sign}{ureal}|{infnan}
|
2013-10-27 11:21:24 -04:00
|
|
|
ureal {uinteger}|\.{digit}+|{digit}+\.{digit}*
|
|
|
|
integer {sign}{uinteger}
|
|
|
|
uinteger {digit}+
|
2013-10-15 21:19:16 -04:00
|
|
|
sign [+-]?
|
2013-10-16 00:17:01 -04:00
|
|
|
infnan "+inf.0"|"-inf.0"|"+nan.0"|"-nan.0"
|
2013-10-15 21:19:16 -04:00
|
|
|
|
2013-11-14 05:45:38 -05:00
|
|
|
/* char */
|
|
|
|
%x CHAR
|
|
|
|
|
2013-10-20 21:48:03 -04:00
|
|
|
/* string */
|
2013-10-23 00:44:45 -04:00
|
|
|
%x STRING
|
2013-10-20 21:48:03 -04:00
|
|
|
|
2013-11-04 22:38:23 -05:00
|
|
|
/* bytevector */
|
|
|
|
%x BYTEVECTOR
|
|
|
|
|
2014-02-18 03:24:08 -05:00
|
|
|
/* block comment */
|
|
|
|
%x BLOCK_COMMENT
|
|
|
|
|
2013-10-11 02:18:37 -04:00
|
|
|
%%
|
|
|
|
|
2013-10-12 05:46:11 -04:00
|
|
|
[ \t\n\r] /* skip whitespace */
|
2013-10-28 00:04:24 -04:00
|
|
|
{comment} /* skip comment */
|
2013-10-28 09:49:15 -04:00
|
|
|
|
2014-02-18 03:24:08 -05:00
|
|
|
"#|" {
|
|
|
|
BEGIN(BLOCK_COMMENT);
|
|
|
|
yylvalp->i = 0;
|
|
|
|
}
|
|
|
|
<BLOCK_COMMENT>"#|" {
|
|
|
|
yylvalp->i++;
|
|
|
|
}
|
|
|
|
<BLOCK_COMMENT>"|#" {
|
|
|
|
if (yylvalp->i == 0)
|
|
|
|
BEGIN(INITIAL);
|
|
|
|
else
|
|
|
|
yylvalp->i--;
|
|
|
|
}
|
2014-02-18 11:58:40 -05:00
|
|
|
<BLOCK_COMMENT>.|\n {
|
2014-02-18 11:53:47 -05:00
|
|
|
/* skip block comment */
|
2014-02-18 03:24:08 -05:00
|
|
|
}
|
|
|
|
|
2013-11-14 03:31:40 -05:00
|
|
|
"#;" return tDATUM_COMMENT;
|
2013-10-17 05:14:18 -04:00
|
|
|
"." return tDOT;
|
2013-10-15 10:25:31 -04:00
|
|
|
"(" return tLPAREN;
|
|
|
|
")" return tRPAREN;
|
2013-11-10 21:57:01 -05:00
|
|
|
"[" return tLBRACKET;
|
|
|
|
"]" return tRBRACKET;
|
2013-10-29 02:51:37 -04:00
|
|
|
"#(" return tVPAREN;
|
2013-10-20 20:29:56 -04:00
|
|
|
"'" return tQUOTE;
|
2013-10-22 23:39:48 -04:00
|
|
|
"`" return tQUASIQUOTE;
|
|
|
|
"," return tUNQUOTE;
|
|
|
|
",@" return tUNQUOTE_SPLICING;
|
2013-10-28 09:49:15 -04:00
|
|
|
|
|
|
|
{boolean} {
|
|
|
|
yylvalp->i = (yytext[1] == 't');
|
|
|
|
return tBOOLEAN;
|
|
|
|
}
|
|
|
|
|
|
|
|
{integer} {
|
|
|
|
yylvalp->i = atoi(yytext);
|
|
|
|
return tINT;
|
|
|
|
}
|
|
|
|
|
|
|
|
{real} {
|
|
|
|
yylvalp->f = atof(yytext);
|
|
|
|
return tFLOAT;
|
|
|
|
}
|
|
|
|
|
|
|
|
{identifier} {
|
2014-02-01 05:33:23 -05:00
|
|
|
yylvalp->cstr = pic_strdup(yyextra->pic, yytext);
|
2013-10-28 09:49:15 -04:00
|
|
|
return tSYMBOL;
|
|
|
|
}
|
|
|
|
|
2014-02-28 08:35:38 -05:00
|
|
|
"\"" {
|
|
|
|
BEGIN(STRING);
|
|
|
|
}
|
|
|
|
<STRING>[^\\"]* {
|
|
|
|
yymore();
|
|
|
|
}
|
|
|
|
<STRING>"\"" {
|
|
|
|
yytext[yyleng-1] = '\0';
|
|
|
|
yylvalp->cstr = pic_strdup(yyextra->pic, yytext);
|
|
|
|
BEGIN(INITIAL);
|
|
|
|
return tSTRING;
|
2013-10-23 00:44:45 -04:00
|
|
|
}
|
2013-10-11 02:18:37 -04:00
|
|
|
|
2013-11-14 05:45:38 -05:00
|
|
|
#\\ {
|
|
|
|
BEGIN(CHAR);
|
2013-11-04 21:37:18 -05:00
|
|
|
}
|
2013-11-14 05:45:38 -05:00
|
|
|
<CHAR>alarm { yylvalp->c = '\a'; BEGIN(INITIAL); return tCHAR; }
|
|
|
|
<CHAR>backspace { yylvalp->c = '\b'; BEGIN(INITIAL); return tCHAR; }
|
|
|
|
<CHAR>delete { yylvalp->c = 0x7f; BEGIN(INITIAL); return tCHAR; }
|
2014-01-05 03:53:14 -05:00
|
|
|
<CHAR>escape { yylvalp->c = 0x1b; BEGIN(INITIAL); return tCHAR; }
|
2013-11-14 05:45:38 -05:00
|
|
|
<CHAR>newline { yylvalp->c = '\n'; BEGIN(INITIAL); return tCHAR; }
|
|
|
|
<CHAR>null { yylvalp->c = '\0'; BEGIN(INITIAL); return tCHAR; }
|
|
|
|
<CHAR>return { yylvalp->c = '\r'; BEGIN(INITIAL); return tCHAR; }
|
2014-02-28 08:35:38 -05:00
|
|
|
<CHAR>space { yylvalp->c = ' '; BEGIN(INITIAL); return tCHAR; }
|
2013-11-14 05:45:38 -05:00
|
|
|
<CHAR>tab { yylvalp->c = '\t'; BEGIN(INITIAL); return tCHAR; }
|
|
|
|
<CHAR>. { yylvalp->c = yytext[0]; BEGIN(INITIAL); return tCHAR; }
|
2013-11-04 21:37:18 -05:00
|
|
|
|
2013-11-04 22:38:23 -05:00
|
|
|
"#u8(" {
|
|
|
|
BEGIN(BYTEVECTOR);
|
|
|
|
yylvalp->blob.len = 0;
|
|
|
|
yylvalp->blob.capa = 10;
|
|
|
|
yylvalp->blob.dat = calloc(10, 1);
|
|
|
|
}
|
2014-02-28 08:35:38 -05:00
|
|
|
<BYTEVECTOR>[ \r\n\t] {
|
|
|
|
/* skip whitespace */
|
|
|
|
}
|
2013-11-04 22:38:23 -05:00
|
|
|
<BYTEVECTOR>{uinteger} {
|
|
|
|
int i = atoi(yytext);
|
|
|
|
if (0 > i || i > 255)
|
|
|
|
REJECT;
|
|
|
|
yylvalp->blob.dat[yylvalp->blob.len++] = (char)i;
|
|
|
|
if (yylvalp->blob.len > yylvalp->blob.capa) {
|
|
|
|
yylvalp->blob.capa *= 2;
|
|
|
|
yylvalp->blob.dat = realloc(yylvalp->blob.dat, yylvalp->blob.capa);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
<BYTEVECTOR>")" {
|
|
|
|
BEGIN(INITIAL);
|
|
|
|
return tBYTEVECTOR;
|
|
|
|
}
|
|
|
|
|
2013-10-11 02:18:37 -04:00
|
|
|
%%
|
|
|
|
|
2014-02-01 05:33:38 -05:00
|
|
|
#undef yyextra
|
|
|
|
#define yyextra ((struct yyguts_t *)yyscanner)->yyextra_r
|
2014-01-30 04:10:56 -05:00
|
|
|
|
|
|
|
void *
|
|
|
|
yyalloc(size_t bytes, yyscan_t yyscanner)
|
|
|
|
{
|
2014-02-01 05:33:38 -05:00
|
|
|
return pic_alloc(yyextra->pic, bytes);
|
2014-01-30 04:10:56 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
yyrealloc(void *ptr, size_t bytes, yyscan_t yyscanner)
|
|
|
|
{
|
2014-02-01 05:33:38 -05:00
|
|
|
return pic_realloc(yyextra->pic, ptr, bytes);
|
2014-01-30 04:10:56 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
yyfree(void * ptr, yyscan_t yyscanner)
|
|
|
|
{
|
2014-02-01 05:33:38 -05:00
|
|
|
return pic_free(yyextra->pic, ptr);
|
2014-01-30 04:10:56 -05:00
|
|
|
}
|
|
|
|
|
2014-02-01 05:33:38 -05:00
|
|
|
#define UNUSED(v) ((void)(v))
|
|
|
|
|
2013-10-11 02:18:37 -04:00
|
|
|
int
|
2013-10-22 14:45:57 -04:00
|
|
|
yywrap(yyscan_t yyscanner)
|
2013-10-11 02:18:37 -04:00
|
|
|
{
|
2014-01-30 04:10:56 -05:00
|
|
|
UNUSED(yyscanner);
|
|
|
|
|
2013-10-11 02:18:37 -04:00
|
|
|
return 1;
|
|
|
|
}
|