parser.y

来自「a little DFA compiler.」· Y 代码 · 共 221 行

Y
221
字号
%{/* $Id: parser.y 674 2007-04-16 21:39:11Z helly $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <time.h>#include <string.h>#include <stdlib.h>#include <iostream>#include "globals.h"#include "parser.h"#include "basics.h"#define YYMALLOC malloc#define YYFREE freeusing namespace re2c;extern "C"{int yylex();void yyerror(const char*);}static re2c::uint accept;static RegExp *spec;static Scanner *in = NULL;/* Bison version 1.875 emits a definition that is not working * with several g++ version. Hence we disable it here. */#if defined(__GNUC__)#define __attribute__(x)#endif/* strdup() isn't standard C, so if we don't have it, we'll create our * own version */#if !defined(HAVE_STRDUP)static char* strdup(const char* s){	char* rv = (char*)malloc(strlen(s) + 1);	if (rv == NULL)		return NULL;	strcpy(rv, s);	return rv;}#endif%}%start	spec%union {    re2c::Symbol	*symbol;    re2c::RegExp	*regexp;    re2c::Token 	*token;    char        	op;    int         	number;    re2c::ExtOp 	extop;    re2c::Str   	*str;};%token		CLOSESIZE   CLOSE	ID	CODE	RANGE	STRING%token		CONFIG	VALUE	NUMBER%type	<op>		CLOSE%type	<op>		close%type	<extop>		CLOSESIZE%type	<symbol>	ID%type	<token>		CODE%type	<regexp>	RANGE	STRING%type	<regexp>	rule	look	expr	diff	term	factor	primary%type	<str>		CONFIG	VALUE%type	<number>	NUMBER%%spec	:		{ accept = 0;		  spec = NULL; }	|	spec rule		{ spec = spec? mkAlt(spec, $2) : $2; }	|	spec decl	;decl	:	ID '=' expr ';'		{ if($1->re)		      in->fatal("sym already defined");		  $1->re = $3; }	|	ID '=' expr '/'		{ in->fatal("trailing contexts are not allowed in named definitions"); }	|	CONFIG '=' VALUE ';'		{ in->config(*$1, *$3); delete $1; delete $3; }	|	CONFIG '=' NUMBER ';'		{ in->config(*$1, $3); delete $1; }	;rule	:	expr look CODE		{ $$ = new RuleOp($1, $2, $3, accept++); }	;look	:		{ $$ = new NullOp; }	|	'/' expr		{ $$ = $2; }	;expr	:	diff		{ $$ = $1; }	|	expr '|' diff		{ $$ =  mkAlt($1, $3); }	;diff	:	term		{ $$ = $1; }	|	diff '\\' term		{ $$ =  mkDiff($1, $3);		  if(!$$)		       in->fatal("can only difference char sets");		}	;term	:	factor		{ $$ = $1; }	|	term factor		{ $$ = new CatOp($1, $2); }	;factor	:	primary		{ $$ = $1; }	|	primary close		{		    switch($2){		    case '*':			$$ = mkAlt(new CloseOp($1), new NullOp());			break;		    case '+':			$$ = new CloseOp($1);			break;		    case '?':			$$ = mkAlt($1, new NullOp());			break;		    }		}	|	primary CLOSESIZE		{			$$ = new CloseVOp($1, $2.minsize, $2.maxsize);		}	;close	:	CLOSE		{ $$ = $1; }	|	close CLOSE		{ $$ = ($1 == $2) ? $1 : '*'; }	;primary	:	ID		{ if(!$1->re)		      in->fatal("can't find symbol");		  $$ = $1->re; }	|	RANGE		{ $$ = $1; }	|	STRING		{ $$ = $1; }	|	'(' expr ')'		{ $$ = $2; }	;%%extern "C" {void yyerror(const char* s){    in->fatal(s);}int yylex(){    return in ? in->scan() : 0;}} // end extern "C"namespace re2c{void parse(Scanner& i, std::ostream& o){	in = &i;	o << "/* Generated by re2c " PACKAGE_VERSION;	if (!bNoGenerationDate)	{		o << " on ";		time_t now = time(&now);		o.write(ctime(&now), 24);	}	o << " */\n";	o << sourceFileInfo;		while(i.echo())	{		yyparse();		if(spec)		{			genCode(o, topIndent, spec);		}		o << sourceFileInfo;	}	RegExp::vFreeList.clear();	Range::vFreeList.clear();	Symbol::ClearTable();	in = NULL;}} // end namespace re2c

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?