📄 parse.y
字号:
/* $Id: parse.y,v 1.26 2003/05/14 19:08:41 n8gray Exp $ */%{#ifdef HAVE_CONFIG_H#include "../config.h"#endif#include "parse.h"#include "textBuf.h"#include "nedit.h"#include "rbTree.h"#include "interpret.h"#include <stdlib.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include <X11/Intrinsic.h>#include <Xm/Xm.h>#ifdef VMS#include "../util/VMSparam.h"#else#ifndef __MVS__#include <sys/param.h>#endif#endif /*VMS*/#ifdef HAVE_DEBUG_H#include "../debug.h"#endif/* Macros to add error processing to AddOp and AddSym calls */#define ADD_OP(op) if (!AddOp(op, &ErrMsg)) return 1#define ADD_SYM(sym) if (!AddSym(sym, &ErrMsg)) return 1#define ADD_IMMED(val) if (!AddImmediate(val, &ErrMsg)) return 1#define ADD_BR_OFF(to) if (!AddBranchOffset(to, &ErrMsg)) return 1#define SET_BR_OFF(from, to) *((int *)(from)) = ((Inst *)(to)) - ((Inst *)(from))/* Max. length for a string constant (... there shouldn't be a maximum) */#define MAX_STRING_CONST_LEN 5000static const char CVSID[] = "$Id: parse.y,v 1.26 2003/05/14 19:08:41 n8gray Exp $";static int yyerror(char *s);static int yylex(void);int yyparse(void);static int follow(char expect, int yes, int no);static int follow2(char expect1, int yes1, char expect2, int yes2, int no);static int follow_non_whitespace(char expect, int yes, int no);static Symbol *matchesActionRoutine(char **inPtr);static char *ErrMsg;static char *InPtr;extern Inst *LoopStack[]; /* addresses of break, cont stmts */extern Inst **LoopStackPtr; /* to fill at the end of a loop */%}%union { Symbol *sym; Inst *inst; int nArgs;}%token <sym> NUMBER STRING SYMBOL%token IF WHILE ELSE FOR BREAK CONTINUE RETURN%type <nArgs> arglist%type <inst> cond comastmts for while else and or arrayexpr%type <sym> evalsym%nonassoc IF_NO_ELSE%nonassoc ELSE%nonassoc SYMBOL%right '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ%left CONCAT%left OR%left AND%left '|'%left '&'%left GT GE LT LE EQ NE IN%left '+' '-'%left '*' '/' '%'%nonassoc UNARY_MINUS NOT%nonassoc DELETE%nonassoc INCR DECR%right POW%nonassoc '['%nonassoc '('%% /* Rules */program: blank stmts { ADD_OP(OP_RETURN_NO_VAL); return 0; } | blank '{' blank stmts '}' { ADD_OP(OP_RETURN_NO_VAL); return 0; } | blank '{' blank '}' { ADD_OP(OP_RETURN_NO_VAL); return 0; } | error { return 1; } ;block: '{' blank stmts '}' blank | '{' blank '}' blank | stmt ;stmts: stmt | stmts stmt ;stmt: simpstmt '\n' blank | IF '(' cond ')' blank block %prec IF_NO_ELSE { SET_BR_OFF($3, GetPC()); } | IF '(' cond ')' blank block else blank block %prec ELSE { SET_BR_OFF($3, ($7+1)); SET_BR_OFF($7, GetPC()); } | while '(' cond ')' blank block { ADD_OP(OP_BRANCH); ADD_BR_OFF($1); SET_BR_OFF($3, GetPC()); FillLoopAddrs(GetPC(), $1); } | for '(' comastmts ';' cond ';' comastmts ')' blank block { FillLoopAddrs(GetPC()+2+($7-($5+1)), GetPC()); SwapCode($5+1, $7, GetPC()); ADD_OP(OP_BRANCH); ADD_BR_OFF($3); SET_BR_OFF($5, GetPC()); } | for '(' SYMBOL IN arrayexpr ')' { Symbol *iterSym = InstallIteratorSymbol(); ADD_OP(OP_BEGIN_ARRAY_ITER); ADD_SYM(iterSym); ADD_OP(OP_ARRAY_ITER); ADD_SYM($3); ADD_SYM(iterSym); ADD_BR_OFF(0); } blank block { ADD_OP(OP_BRANCH); ADD_BR_OFF($5+2); SET_BR_OFF($5+5, GetPC()); FillLoopAddrs(GetPC(), $5+2); } | BREAK '\n' blank { ADD_OP(OP_BRANCH); ADD_BR_OFF(0); if (AddBreakAddr(GetPC()-1)) { yyerror("break outside loop"); YYERROR; } } | CONTINUE '\n' blank { ADD_OP(OP_BRANCH); ADD_BR_OFF(0); if (AddContinueAddr(GetPC()-1)) { yyerror("continue outside loop"); YYERROR; } } | RETURN expr '\n' blank { ADD_OP(OP_RETURN); } | RETURN '\n' blank { ADD_OP(OP_RETURN_NO_VAL); } ;simpstmt: SYMBOL '=' expr { ADD_OP(OP_ASSIGN); ADD_SYM($1); } | evalsym ADDEQ expr { ADD_OP(OP_ADD); ADD_OP(OP_ASSIGN); ADD_SYM($1); } | evalsym SUBEQ expr { ADD_OP(OP_SUB); ADD_OP(OP_ASSIGN); ADD_SYM($1); } | evalsym MULEQ expr { ADD_OP(OP_MUL); ADD_OP(OP_ASSIGN); ADD_SYM($1); } | evalsym DIVEQ expr { ADD_OP(OP_DIV); ADD_OP(OP_ASSIGN); ADD_SYM($1); } | evalsym MODEQ expr { ADD_OP(OP_MOD); ADD_OP(OP_ASSIGN); ADD_SYM($1); } | evalsym ANDEQ expr { ADD_OP(OP_BIT_AND); ADD_OP(OP_ASSIGN); ADD_SYM($1); } | evalsym OREQ expr { ADD_OP(OP_BIT_OR); ADD_OP(OP_ASSIGN); ADD_SYM($1); } | DELETE arraylv '[' arglist ']' { ADD_OP(OP_ARRAY_DELETE); ADD_IMMED((void *)$4); } | initarraylv '[' arglist ']' '=' expr { ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$3); } | initarraylv '[' arglist ']' ADDEQ expr { ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)$3); ADD_OP(OP_ADD); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$3); } | initarraylv '[' arglist ']' SUBEQ expr { ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)$3); ADD_OP(OP_SUB); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$3); } | initarraylv '[' arglist ']' MULEQ expr { ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)$3); ADD_OP(OP_MUL); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$3); } | initarraylv '[' arglist ']' DIVEQ expr { ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)$3); ADD_OP(OP_DIV); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$3); } | initarraylv '[' arglist ']' MODEQ expr { ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)$3); ADD_OP(OP_MOD); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$3); } | initarraylv '[' arglist ']' ANDEQ expr { ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)$3); ADD_OP(OP_BIT_AND); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$3); } | initarraylv '[' arglist ']' OREQ expr { ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)1); ADD_IMMED((void *)$3); ADD_OP(OP_BIT_OR); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$3); } | initarraylv '[' arglist ']' INCR { ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)0); ADD_IMMED((void *)$3); ADD_OP(OP_INCR); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$3); } | initarraylv '[' arglist ']' DECR { ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)0); ADD_IMMED((void *)$3); ADD_OP(OP_DECR); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$3); } | INCR initarraylv '[' arglist ']' { ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)0); ADD_IMMED((void *)$4); ADD_OP(OP_INCR); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$4); } | DECR initarraylv '[' arglist ']' { ADD_OP(OP_ARRAY_REF_ASSIGN_SETUP); ADD_IMMED((void *)0); ADD_IMMED((void *)$4); ADD_OP(OP_DECR); ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED((void *)$4); } | SYMBOL '(' arglist ')' { ADD_OP(OP_SUBR_CALL); ADD_SYM(PromoteToGlobal($1)); ADD_IMMED((void *)$3); } | INCR SYMBOL { ADD_OP(OP_PUSH_SYM); ADD_SYM($2); ADD_OP(OP_INCR); ADD_OP(OP_ASSIGN); ADD_SYM($2); } | SYMBOL INCR { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP(OP_INCR); ADD_OP(OP_ASSIGN); ADD_SYM($1); } | DECR SYMBOL { ADD_OP(OP_PUSH_SYM); ADD_SYM($2); ADD_OP(OP_DECR); ADD_OP(OP_ASSIGN); ADD_SYM($2); } | SYMBOL DECR { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); ADD_OP(OP_DECR); ADD_OP(OP_ASSIGN); ADD_SYM($1); } ;evalsym: SYMBOL { $$ = $1; ADD_OP(OP_PUSH_SYM); ADD_SYM($1); } ;comastmts: /* nothing */ { $$ = GetPC(); } | simpstmt { $$ = GetPC(); } | comastmts ',' simpstmt { $$ = GetPC(); } ;arglist: /* nothing */ { $$ = 0; } | expr { $$ = 1; } | arglist ',' expr { $$ = $1 + 1; } ;expr: numexpr %prec CONCAT | expr numexpr %prec CONCAT { ADD_OP(OP_CONCAT); } ;initarraylv: SYMBOL { ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED((void *)1); } | initarraylv '[' arglist ']' { ADD_OP(OP_ARRAY_REF); ADD_IMMED((void *)$3); } ;arraylv: SYMBOL { ADD_OP(OP_PUSH_ARRAY_SYM); ADD_SYM($1); ADD_IMMED((void *)0); } | arraylv '[' arglist ']' { ADD_OP(OP_ARRAY_REF); ADD_IMMED((void *)$3); } ;arrayexpr: numexpr { $$ = GetPC(); } ;numexpr: NUMBER { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); } | STRING { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); } | SYMBOL { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); } | SYMBOL '(' arglist ')' { ADD_OP(OP_SUBR_CALL); ADD_SYM(PromoteToGlobal($1)); ADD_IMMED((void *)$3); ADD_OP(OP_FETCH_RET_VAL); } | '(' expr ')' | numexpr '[' arglist ']' { ADD_OP(OP_ARRAY_REF); ADD_IMMED((void *)$3); } | numexpr '+' numexpr { ADD_OP(OP_ADD); } | numexpr '-' numexpr { ADD_OP(OP_SUB); } | numexpr '*' numexpr { ADD_OP(OP_MUL); } | numexpr '/' numexpr { ADD_OP(OP_DIV); } | numexpr '%' numexpr { ADD_OP(OP_MOD); } | numexpr POW numexpr { ADD_OP(OP_POWER); } | '-' numexpr %prec UNARY_MINUS { ADD_OP(OP_NEGATE); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -