⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vbs_grammar.y

📁 vb script子集解释器 Makefile.vb用于生成解释器的c代码 可执行程序需要自己写main函数
💻 Y
字号:
%{// the grammar descript for the subset of VBScript language// written by me.xinxin@gmail.com%}%name-prefix="vbs_"%pure-parser%locations%debug%error-verbose%parse-param { Cvbs_context* cnt }%lex-param { Cvbs_context* cnt }%{#include <string>#include <iostream>#include "../inc/tracelog.h"#include "vbs_context.h"#include "vbs_lex.h"#include "vbs_grammar.tab.h"#ifndef Statementtypedef struct Statement_struct *Statement;#endif#ifndef Expressiontypedef struct Expression_struct *Expression;#endif#ifndef CaseListtypedef struct CaseList_struct *CaseList;#endif#include "ast.h"extern "C" void  execute(Statement s, Cvbs_context& c);extern "C" string evaluate(Expression e, Cvbs_context& c);int yylex(YYSTYPE* str, YYLTYPE * yyloc, Cvbs_context* pcnt);int yyerror(YYLTYPE *locp,Cvbs_context* pcnt,const char* msg);%}	%union {  char* szVal;  struct Statement_struct*  stmt;  struct Expression_struct*  exp;  struct CaseList_struct*    caselist;}%start ROOT%token EQ%token NE%token LT%token LE%token GT%token GE%token XOR%token OR%token PLUS%token MINUS%token MULT%token DIVIDE%token RPAREN%token LPAREN%token ASSIGN%token SEMICOLON%token IF%token THEN%token ELSE%token ELSEIF%token ENDIF%token WHILE%token WEND%token LOOP%token EXIT%token UNTIL%token FOR%token TO%token NEXT%token STEP%token DO%token END%token SELECT%token CASE%token PRINT%token DIM%token TYPE%token SUB%token <szVal> SUB_BODY%token <szVal> FUNC_BODY%token FUNCTION%token ENDFUNC%token AS%token COMMA%token BYVAL%token BYREF%token PRIVATE%token PUBLIC%token EXITSUB%token EXITFUNC%token DEFAULT%token <szVal> NUMBER%token <szVal> STRING%token <szVal> NAME%token <szVal> NAME_SUB%token <szVal> TRUE%token <szVal> FALSE%token COLON%token CALL%token EVAL%token AND%token AMD%token NOT%token LBOUND%token UBOUND%token CLNG%token DATE%token GETSTRING%token CSTR%token INSTR%token INSTRREV%token JOIN%token LEN%token RANDOMIZE %token RND%token TIME%token YEAR%token MONTH%token DAY%token WEEKDAY%token HOUR%token MINUTE%token SECOND%type <stmt> ROOT stmtseq statement declare declare_var declare_sub declare_func elseif_seq%type <exp> expression expr2 expr3 expr4 designator arg func%type <caselist> case_seq arglist argref_list  subscript  upper //%destructor { free($$);} NUMBER STRING TRUE FALSE%%ROOT: stmtseq 	{  execute($1,*cnt); } ;statement:  designator EQ expression 			{ $$ = assignment($1, $3,cnt);} | PRINT expression 				{ $$ = print($2,cnt); } | IF expression THEN stmtseq ELSE stmtseq END IF { $$ = ifstmt($2, $4, $6,cnt); }| IF expression THEN stmtseq END IF		{ $$ = ifstmt($2, $4, empty(cnt),cnt); }| IF expression THEN stmtseq elseif_seq END IF  { $$ = ifstmt($2,$4,$5,cnt);}| SELECT CASE expression case_seq CASE ELSE stmtseq END SELECT  {$$ = select_case($3,$4,$7,cnt);}| SELECT CASE expression case_seq END SELECT			{$$ = select_case($3,$4,empty(cnt),cnt);} | WHILE expression  stmtseq  WEND  		{ $$ = whilestmt($2, $3,cnt); }| DO WHILE expression stmtseq LOOP 		{ $$ = dowhileloop($3,$4,cnt);}| DO UNTIL expression stmtseq LOOP 		{ $$ = dountilloop($3,$4,cnt);}| DO stmtseq LOOP WHILE expression 		{ $$ = doloopwhile($2,$5,cnt);}| DO stmtseq LOOP UNTIL expression 		{ $$ = doloopuntil($2,$5,cnt);}| EXIT DO 			   		{ $$ = exitdo(cnt); }| EXIT FOR					{ $$ = exitfor(cnt);}| FOR NAME EQ expression TO expression STEP expression stmtseq NEXT { $$=fornext(name($2,cnt),$4,$6,$8,$9,cnt);}| FOR NAME EQ expression TO expression stmtseq NEXT { $$=fornext(name($2,cnt),$4,$6,value("#1",cnt),$7,cnt);}| declare			 | EXIT SUB			 { $$ = exitsub(cnt); }| EXIT FUNCTION			 { $$ = exitsub(cnt); }| CALL NAME_SUB LPAREN argref_list RPAREN { $$ = callsub($2,$4,cnt);}| CALL NAME_SUB			  { $$ = callsub($2,null(cnt),cnt);}| NAME_SUB argref_list 		  { $$ = callsub($1,$2,cnt);}| EVAL expression		  { $$ = eval($2,cnt);}| NAME_SUB			  { $$ = callsub($1,null(cnt),cnt);}| RANDOMIZE LPAREN  expression RPAREN 		  { $$ = randomize($3,cnt);}| RANDOMIZE 			  { $$ = randomize0(cnt);} ;stmtseq:  stmtseq  statement { $$ = seq($1, $2,cnt); }| stmtseq COLON statement {$$ = seq($1,$3,cnt);}| statement { $$ = $1; };case_seq:  CASE expression stmtseq		{$$ = case_node($2,$3,null(cnt),cnt);}| case_seq CASE expression stmtseq	{$$ = case_node($3,$4,$1,cnt);};elseif_seq:  ELSEIF expression THEN stmtseq 		{$$ = ifstmt($2,$4,empty(cnt),cnt);}| elseif_seq ELSEIF expression THEN stmtseq 	{$$ = seq($1,ifstmt($3,$5,empty(cnt),cnt),cnt);}| elseif_seq ELSEIF expression THEN stmtseq ELSE stmtseq {$$ = seq($1,ifstmt($3,$5,$7,cnt),cnt);};argref_list:  expression	{$$=argreflist($1,null(cnt),cnt);}| argref_list COMMA expression {$$=argreflist($3,$1,cnt); }expression:  expr2 { $$ = $1; } | expr2 EQ expr2 { $$ = eq($1,$3,cnt); }| expr2 NE expr2 { $$ = ne($1,$3,cnt); }| expr2 LT expr2 { $$ = lt($1,$3,cnt); }| expr2 LE expr2 { $$ = le($1,$3,cnt); }| expr2 GT expr2 { $$ = gt($1,$3,cnt); }| expr2 GE expr2 { $$ = ge($1,$3,cnt); }| expression AND expression { $$ = vband($1,$3,cnt);}| expression OR expression  { $$ = vbor($1,$3,cnt);}| expression XOR expression { $$ = vbxor($1,$3,cnt);};expr2:  expr3 		{ $$ = $1; }| expr2 PLUS expr3 	{ $$ = splus($1,$3,cnt);  }| expr2 MINUS expr3 	{ $$ = sminus($1,$3,cnt);  }| expr2 AMD expr3	{ $$ = amd($1,$3,cnt);};expr3:  expr4 		{ $$ = $1; }| expr3 MULT expr4 	{ $$ = mult($1, $3,cnt); }| expr3 DIVIDE expr4 	{ $$ = divide ($1, $3,cnt); };expr4:  PLUS expr4 { $$ = $2; }| MINUS expr4 { $$ = neg($2,cnt); }| NOT	expr4 { $$ = vbnot($2,cnt);}| LPAREN expression RPAREN { $$ = $2; }| NUMBER { $$ = value($1,cnt)}| STRING { $$ = value($1,cnt)}| TRUE	 { $$ = value($1,cnt)}| FALSE  { $$ = value($1,cnt)}| designator { $$ = $1; }| func		{ $$ = $1;};func:  LBOUND LPAREN NAME RPAREN { $$ = lbound($3,1,cnt);}| UBOUND LPAREN NAME RPAREN { $$ = ubound($3,1,cnt);}| CLNG LPAREN expression RPAREN { $$ = clng($3,cnt);}| DATE				{ $$ = date(cnt); }| GETSTRING LPAREN expression COMMA expression COMMA expression RPAREN {$$ = getstring($3,$5,$7,cnt);}| INSTR LPAREN  expression COMMA expression  RPAREN { $$ = instr(value("#0",cnt),$3,$5,value("#0",cnt),cnt);}| INSTR LPAREN  expression COMMA expression  COMMA expression RPAREN {$$ = instr($3,$5,$7,value("#0",cnt),cnt);}| INSTR LPAREN  expression COMMA expression  COMMA expression COMMA expression RPAREN {$$ = instr($3,$5,$7,$9,cnt);}| CSTR LPAREN expression RPAREN { $$ = cstr($3,cnt);}| LEN LPAREN expression RPAREN  { $$ = len($3,cnt);}| RND  LPAREN expression RPAREN { $$ = rnd($3,cnt);}| RND				{ $$ = rnd0(cnt); } | TIME				{ $$ = vbtime(cnt); }| YEAR LPAREN expression RPAREN { $$ = vyear($3,cnt);}| MONTH	LPAREN expression RPAREN { $$ = vmonth($3,cnt);}| DAY LPAREN expression RPAREN  { $$ = vday($3,cnt);}| WEEKDAY LPAREN expression RPAREN {$$ = vweekday($3,cnt);}| HOUR LPAREN expression RPAREN { $$ = vhour($3,cnt);}| MINUTE LPAREN expression RPAREN {$$ = vminute($3,cnt);}| SECOND LPAREN expression RPAREN {$$ = vsecond($3,cnt);};designator:  NAME LPAREN argref_list RPAREN {$$ = name_array($1,$3,cnt);}| NAME { $$ = name($1,cnt);  };declare:  declare_var			| declare_sub			| declare_func  		;declare_var:  DIM NAME					{$$ = decl($2,cnt); } | DIM NAME subscript				{$$ = declarray($2,$3,cnt);	}| DIM NAME AS TYPE				{$$ = decl($2,cnt); }| DIM NAME subscript AS TYPE			{$$ = declarray($2,$3,cnt); }| PRIVATE NAME					{$$ = decl($2,cnt); }| PRIVATE NAME subscript			{$$ = declarray($2,$3,cnt); }| PRIVATE NAME AS TYPE				{$$ = decl($2,cnt); }| PRIVATE NAME subscript AS TYPE		{$$ = declarray($2,$3,cnt); }| PUBLIC NAME					{$$ = decl($2,cnt); }| PUBLIC NAME subscript				{$$ = declarray($2,$3,cnt); }| PUBLIC NAME AS TYPE				{$$ = decl($2,cnt); }| PUBLIC NAME subscript AS TYPE			{$$ = declarray($2,$3,cnt); }| declare_var COMMA NAME			{$$ = decl($3,cnt); }| declare_var COMMA NAME subscript		{$$ = declarray($3,$4,cnt); }| declare_var COMMA NAME AS TYPE		{$$ = decl($3,cnt); }| declare_var COMMA NAME subscript AS TYPE	{$$ = declarray($3,$4,cnt); };declare_sub:  SUB NAME LPAREN arglist RPAREN SUB_BODY   	{$$ = declsub($2,$4,$6,cnt);cnt->save_func($2);}| SUB NAME LPAREN RPAREN SUB_BODY 		{$$ = declsub($2,null(cnt),$5,cnt);cnt->save_func($2);}| PUBLIC SUB NAME LPAREN arglist RPAREN SUB_BODY	{$$ = declsub($3,$5,$7,cnt);cnt->save_func($3);}| PUBLIC SUB NAME LPAREN RPAREN SUB_BODY	{$$ = declsub($3,null(cnt),$6,cnt);cnt->save_func($3);}| PUBLIC DEFAULT SUB NAME LPAREN arglist RPAREN SUB_BODY {$$ = declsub($4,$6,$8,cnt);cnt->save_func($4);}| PUBLIC DEFAULT SUB NAME LPAREN RPAREN SUB_BODY {$$ = declsub($4,null(cnt),$7,cnt);cnt->save_func($4);}| PRIVATE SUB NAME LPAREN arglist RPAREN SUB_BODY {$$ = declsub($3,$5,$7,cnt);cnt->save_func($3);}| PRIVATE SUB NAME LPAREN RPAREN SUB_BODY	  {$$ = declsub($3,null(cnt),$6,cnt);cnt->save_func($3);};declare_func:  FUNCTION NAME LPAREN arglist RPAREN FUNC_BODY		{$$ = declsub($2,$4,$6,cnt);cnt->save_func($2);}     | FUNCTION NAME LPAREN RPAREN FUNC_BODY			{$$ = declsub($2,null(cnt),$5,cnt);cnt->save_func($2);}| PUBLIC FUNCTION NAME LPAREN arglist RPAREN FUNC_BODY	{$$ = declsub($3,$5,$7,cnt);cnt->save_func($3);}| PUBLIC FUNCTION NAME LPAREN RPAREN FUNC_BODY		{$$ = declsub($3,null(cnt),$6,cnt);cnt->save_func($3);}| PUBLIC DEFAULT FUNCTION NAME LPAREN arglist RPAREN FUNC_BODY	{$$ = declsub($4,$6,$8,cnt);cnt->save_func($4);}| PUBLIC DEFAULT FUNCTION NAME LPAREN RPAREN FUNC_BODY	{$$ = declsub($4,null(cnt),$7,cnt);cnt->save_func($4);}| PRIVATE FUNCTION NAME LPAREN arglist RPAREN FUNC_BODY {$$ = declsub($3,$5,$7,cnt);cnt->save_func($3);}| PRIVATE FUNCTION NAME LPAREN RPAREN FUNC_BODY 	{$$ = declsub($3,null(cnt),$6,cnt);cnt->save_func($3);};arg:  NAME		{$$=name($1,cnt);}| BYVAL NAME    {$$=name($2,cnt);}| BYREF NAME    {$$=name((string($2)+string("*")).c_str(),cnt);};arglist:  arg 			{$$ = arglist($1,null(cnt),cnt); }| arglist COMMA arg	{$$ = arglist($3,$1,cnt); };   subscript:  LPAREN upper RPAREN	{$$ = $2;};upper:  NUMBER		{ $$=subs(atoi($1+1),null(cnt),cnt);}| upper COMMA NUMBER	{ $$=subs(atoi($3+1),$1,cnt);};%%int yylex(YYSTYPE* str, YYLTYPE * yyloc, Cvbs_context* pcnt){    pcnt->strValue.clear();    pcnt->szValue = NULL;    register int n=vbslex(pcnt->get_scanner());    if (pcnt->szValue || n == TRUE || n == FALSE)     {        string sTmp;	switch(n)	{		case NUMBER:			sTmp = "#";//number prefix			sTmp += pcnt->szValue;			pcnt->szValue = sTmp.c_str();			break;		case STRING:			sTmp = "$";//string prefix			sTmp += pcnt->szValue;			pcnt->szValue = sTmp.c_str();			break;		case TRUE:			sTmp = "True";			pcnt->szValue = sTmp.c_str();			break;		case FALSE:			sTmp = "False";			pcnt->szValue = sTmp.c_str();			break;		default:			//sTmp = pcnt->strValue;			break;	}	    	//str->szVal = strdup(pcnt->szValue);	int len = strlen(pcnt->szValue)+1;	str->szVal = (char*)pcnt->Alloc(len);	memcpy(str->szVal,pcnt->szValue,len);	pcnt->strValue.clear();    }         yyloc->first_line=yyloc->last_line = vbsget_lineno(pcnt->get_scanner());    yyloc->first_column=pcnt->nlastCol  - vbsget_leng(pcnt->get_scanner());    yyloc->last_column=pcnt->nlastCol - 1;    return n;} int yyerror(YYLTYPE *locp,Cvbs_context* pcnt,const char* msg){        if (!locp) TRACE(0,"VBS ERROR:null locp");        TRACE(0,"PARSE ERROR on line %d:%d-%d error:%s",  locp->first_line,locp->first_column,locp->last_column,msg);}

⌨️ 快捷键说明

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