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

📄 parser.y

📁 Shorthand是一个强大的脚本语言
💻 Y
字号:
%{///////////////////////////////////////////////////////////////////////////////// $Header: $//-----------------------------------------------------------------------------// Project: ShortHand interpreter// Author: Andrei Remenchuk <andrei@remenchuk.com>//-----------------------------------------------------------------------------// parsery.y: ShortHand grammar///////////////////////////////////////////////////////////////////////////////#include <stdlib.h>#include <stdio.h>#include <string.h>#include <ctype.h>#ifdef WIN32#include <windows.h>#endif#include "shorthand.h"#include "yydef.h"#include "module.h"#include "nodes.h"//// parser_module is a pointer to the ShhModule object passed as parameter// to yyparse() function//#define MODULE ((ShhModule*)parser_module)// we redefined yylex() as module's method instead of stanalone function#define yylex   MODULE->module_yylex#define yyerror MODULE->module_yyerror// this defines lexer object#define LEXER   MODULE->m_lexer// macros for constructing AST nodes#define NEW0(T)                     (T*) MODULE->include(new T())#define NEW(T,arg1)                 (T*) MODULE->include(new T(arg1))#define NEW2(T,arg1,arg2)           (T*) MODULE->include(new T(arg1,arg2))#define NEW3(T,arg1,arg2,arg3)      (T*) MODULE->include(new T(arg1,arg2,arg3))#define NEW4(T,arg1,arg2,arg3,arg4) (T*) MODULE->include(new T(arg1,arg2,arg3,arg4))%}%pure_parser%token_table%union {     int           num;     double        fnum;     const char*   str;     ShhVariable*   var;     ShhExecutable* exec;     ShhExpression* exp;     ShhPredicate*  pred;     ShhBatch*      batch;     ShhQualifier*  qualifier;     ShhExpressionList* explist;     ShhFunctionCall* call;     ShhParameterList*  params;
};%token LEX_ERROR%token FOO%token <str> BARE_HTML%token <str> BARE_HTML_EOF%token <str> HTML_AND_PRINT%token <str> IDENT OBJECT_IDENT%token <num> NUMBER%token <fnum> _FLOAT%token <str> STRING%token IF THEN ELSE ALL END PRINT PRINTLN%token GRID WHILE BREAK CONTINUE FOR TO%token K_RETURN FUNCTION K_NULL%token INCLUDE JUMP LOCAL
%token AS FOREACH%token MIN MAX %type <exp> expression %type <exec> statement super_statement  subst%type <batch> statements content locals%type <exec> loop%type <exec> if_block else_block%type <exec> local%type <pred> condition%type <explist> arguments arglist%type <call> call%type <params> paramlist params%nonassoc LOWER_THAN_ELSE%nonassoc ELSE%nonassoc ELSEIF%nonassoc EQL
%left     OR%left     AND%nonassoc EQ NE LE GE '<' '>'%right	NOT UNOT %nonassoc '=' COMPARE%nonassoc HIGHER_THAN_EXPRESSION%left     '&'%left     '+' '-'%nonassoc '%'%left     '*' '/'%right    '!' UMINUS%left     '.'%nonassoc K_NEW 
%left     '[' ']' '{' '}' 
%left     '('%%input		: content                {  const char* html = LEXER->flush_html();                   if (html != NULL && *html != '\0') 		       while(*html && strchr(" \t\r\n", *html) != 0) html++;		   if (html != NULL && *html != '\0')                   {                       if (yydebug) printf("input: OOB html found\n");                       TRACE((5, "input(%s): OOB html found (%d characters):\n---oob start---\n%s\n--oob end-----\n",                               MODULE->getName(), strlen(html), html));                        ShhBatch* batch = NEW(ShhBatch, $1);                       batch->add( NEW(ShhHTML, html) );                       MODULE->setEntry(batch);                   } else {                       MODULE->setEntry($1);                   }                   if (yydebug) printf("got input\n");                   TRACE((5, "input is block of stamements\n"));                 }                                ;content     : /* empty */                { $$ = NEW0(ShhBatch); }            | statements                 { $$ = $1; }            ;subst       : newlines              { $$ = NEW0(ShhNOP); }            | statement               { $$ = $1; }            | super_statement               { $$ = $1; }

	    | ';'
	       { $$ = NEW0(ShhNOP); }
            ;statements  : subst                { $$ = NEW(ShhBatch,$1); }            | statements subst                 { $$ = $1; $$->add($2); }                        ;super_statement : BARE_HTML                { $$ = NEW(ShhHTML,$1); }            | HTML_AND_PRINT expression                {                   ShhBatch* batch = NEW(ShhBatch, NEW(ShhHTML,$1));                  batch->add(NEW(ShhPrint,$2));                  $$ = batch; }            ;statement   : if_block                { $$ = $1; }	    | loop		{ $$ = $1; }	    | BREAK		{ $$ = NEW0(ShhBreak); }	    | CONTINUE		{ $$ = NEW0(ShhContinue); }					    | expression '=' expression		{ $$ = NEW2(ShhAssignment, $1, $3); }	    /*| IDENT '.' IDENT 		{ $$ = NEW3(ShhVoidMethodCall, $1, $3, NULL); }*/	    | expression '.' IDENT '(' arguments ')'		{ $$ = NEW3(ShhVoidMethodCall, $1, $3, $5); }

	    | PRINT expression		{ $$ = NEW(ShhPrint, $2); }	    | PRINTLN expression		{ $$ = NEW2(ShhPrint, $2, true); }				    | INCLUDE expression		{ $$ = NEW(ShhInclude, $2); }	    | JUMP expression		{ $$ = NEW(ShhJump, $2); }	    | call		{ $$ = NEW(ShhVoid, $1); }	    | FUNCTION IDENT '(' params ')' statements END FUNCTION		{ $$ = NEW3(ShhDefun, $2, $4, $6); }	    | K_RETURN expression	        { $$ = NEW(ShhReturn, $2); }	    | K_RETURN 	        { $$ = NEW(ShhReturn, NEW(ShhConstant, "")); }	    | LOCAL locals		{ $$ = $2; }	    ;

newlines    : '\n'            | newlines '\n'            ;local   : IDENT         { $$ = NEW(ShhLocalDecl, $1); }	    
		| IDENT '=' expression        { $$ = NEW2(ShhLocalDecl, $1, $3); }	    ;locals  : local	    { $$ = NEW(ShhBatch, $1); }	    | locals ',' local	    { $$ = $1; $$->add($3); }	    ;call    : IDENT '(' arguments ')'          { $$ = NEW2(ShhFunctionCall, $1, $3); }		;loop    : GRID '(' IDENT ')' statements END GRID        { $$ = NEW2(ShhGrid, $3, $5); }                    | GRID '(' IDENT ',' expression ')' statements END GRID        { $$ = NEW3(ShhGrid, $3, $7, $5); }        | GRID '(' IDENT ',' expression ',' expression ')' statements END GRID        { $$ = NEW4(ShhGrid, $3, $9, $5, $7); }        | WHILE condition statements END WHILE        { $$ = NEW2(ShhWhileLoop, $2, $3); }        | FOR IDENT '=' expression TO expression statements END FOR        { $$ = NEW4(ShhForLoop, $2, $4, $6, $7); }

        | FOREACH expression AS expression statements END FOR
        { $$ = NEW4(ShhForeachLoop, $2, NULL, $4, $5); }
        | FOREACH expression AS expression EQL expression statements END FOR
        { $$ = NEW4(ShhForeachLoop, $2, $4, $6, $7); }
        ;arguments   : /* empty */				{ $$ = ShhExpressionList::null; }  	    | arglist		{ $$ = $1; }	    ;			paramlist   : IDENT		{ $$ = NEW0(ShhParameterList); $$->add(new ShhParameter($1)); }	    | paramlist ',' IDENT		{ $$ = $1; $$->add(new ShhParameter($3)); }	    ;params      : /* empty */		{ $$ = NEW0(ShhParameterList); }	    | paramlist	        { $$ = $1; }	    ;arglist     : expression                { $$ = NEW(ShhExpressionList, $1); }            | arglist ',' expression                { $$ = $1; $1->add($3); }            ;expression  : NUMBER                { $$ = NEW(ShhConstant, $1); }            | _FLOAT                { $$ = NEW(ShhConstant, $1); }            | K_NULL	        { $$ = NEW(ShhConstant, ShhValue::null()); }                        | STRING                { $$ = NEW(ShhConstant, $1); }  	        | IDENT '(' arguments ')'                { $$ = NEW2(ShhFunctionCall, $1, $3); }            | IDENT                { $$ = NEW(ShhVariableRef, $1); }                        | expression '.' IDENT                 { $$ = NEW2(ShhPropertyRef, $1, $3 ); }            | expression '.' IDENT '(' arguments ')' %prec UMINUS                { $$ = NEW3(ShhValueMethodCall, $1, $3, $5); }            | '(' expression ')'                { $$ = $2; }                        | expression '+' expression                { $$ = NEW3(ShhArithmetic, '+', $1, $3); }                        | expression '-' expression                { $$ = NEW3(ShhArithmetic, '-', $1, $3); }                        | expression '*' expression                { $$ = NEW3(ShhArithmetic, '*', $1, $3); }                        | expression '/' expression                { $$ = NEW3(ShhArithmetic, '/', $1, $3); }                        | expression '%' expression                { $$ = NEW3(ShhArithmetic, '%', $1, $3); }            | '-' expression %prec UMINUS                { $$ = NEW3(ShhArithmetic, '-', NEW(ShhConstant, 0), $2); }                        | expression '&' expression                 { $$ = NEW2(ShhConcat, $1, $3); }            | K_NEW OBJECT_IDENT                { $$ = NEW2(ShhObjectCtor, $2, NULL); }            | K_NEW call                { $$ = NEW2(ShhObjectCtor, $2->name(), $2->args()); }

            | expression '[' expression ']'
                { $$ = NEW2(ShhArrayElement, $1, $3); }

            | expression '{' expression '}'
                { $$ = NEW2(ShhHashElement, $1, $3); }
            ;condition   : expression '<' expression            { $$ = NEW3(ShhComparison, '<', $1, $3); }
            | expression '>' expression            { $$ = NEW3(ShhComparison, '>', $1, $3); }
            | expression '=' expression            { $$ = NEW3(ShhComparison, '=', $1, $3); }
            | expression LE expression            { $$ = NEW3(ShhComparison, LE, $1, $3); }
            | expression GE expression            { $$ = NEW3(ShhComparison, GE, $1, $3); }
            | expression NE expression            { $$ = NEW3(ShhComparison, NE, $1, $3); }
            | '(' condition ')'            { $$ = $2; }
            | condition AND condition            { $$ = NEW3(ShhBooleanArithmetic, AND, $1, $3); }
            | condition OR condition            { $$ = NEW3(ShhBooleanArithmetic, OR,  $1, $3); }
            | NOT condition            { $$ = NEW3(ShhBooleanArithmetic, NOT, $2, NULL); }
            | expression            { $$ = NEW3(ShhComparison, NE, NEW(ShhConstant, 0), $1); }            ;if_block    : IF condition THEN statements else_block                { $$ = NEW3(ShhConditionBlock, $2, $4, $5); }            | IF condition THEN else_block                { $$ = NEW3(ShhConditionBlock, $2, NULL, $4); }            ;else_block  : END IF                { $$ = NEW0(ShhNOP); }            | ELSE statements END IF                { $$ = $2; }            | ELSEIF condition THEN statements else_block                { $$ = NEW3(ShhConditionBlock, $2, $4, $5); }            ;%%

⌨️ 快捷键说明

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