|
|
1.1 ! root 1: %{ ! 2: #include "gram.h" ! 3: #include "expr.pub" ! 4: #include "bpts.pub" ! 5: #include <ctype.h> ! 6: int LexIndex; ! 7: int LexGoal; ! 8: struct Expr *CurrentExpr; ! 9: char *LexString; ! 10: char *yyerr; /* yacc doesn't use this */ ! 11: long yyres; ! 12: char Token[128]; ! 13: int DotDot; ! 14: Expr *E_IConst(long), *E_DConst(double); ! 15: %} ! 16: ! 17: %union { ! 18: char cc; ! 19: long ll; ! 20: char ss[32]; ! 21: struct Expr *ee; ! 22: double dd; ! 23: } ! 24: ! 25: %token G_EXPR G_DOTEQ_CONEX G_DOLEQ_CONEX G_CONEX G_DOTDOT ! 26: %token ICONST, ID, PCENT, EQUAL, SLASH, DOLLAR, SIZEOF, TYPEOF, QMARK, SEMI ! 27: %token UNOP, STAR, PLUS, MINUS, AMPER, ARROW, DOT, LB, LP, COMMA, ERROR, RB, RP ! 28: %token PLUSPLUS, MINUSMINUS, EQUALEQUAL, GREATER, LESS, BAR, BARBAR ! 29: %token AMPERAMPER, HAT, TILDE, GREATEREQUAL, LESSEQUAL, FABS ! 30: %token GREATERGREATER, LESSLESS, BANG, BANGEQUAL, DCONST, LC, RC, DOTDOT ! 31: ! 32: %type <dd> DCONST ! 33: %type <ll> ICONST ! 34: %type <ss> ID ! 35: %type <ee> expr, list, conex ! 36: %type <cc> UNOP, STAR, PLUS, MINUS, AMPER, ARROW, DOT, LB, LP, COMMA, ERROR, SLASH ! 37: %type <cc> EQUAL, PCENT, QMARK, SEMI ! 38: %type <cc> PLUSPLUS, MINUSMINUS, EQUALEQUAL, GREATER, LESS, BAR, BARBAR ! 39: %type <cc> AMPERAMPER, HAT, TILDE, GREATEREQUAL, LESSEQUAL ! 40: %type <cc> GREATERGREATER, LESSLESS, BANG, BANGEQUAL, FABS, LC, RC, DOTDOT ! 41: ! 42: %left DOTDOT ! 43: %left COMMA ! 44: %right EQUAL ! 45: %left BARBAR ! 46: %left AMPERAMPER ! 47: %left BAR ! 48: %left HAT ! 49: %left AMPER ! 50: %left EQUALEQUAL BANGEQUAL ! 51: %left LESS GREATER LESSEQUAL GREATEREQUAL ! 52: %left LESSLESS GREATERGREATER ! 53: %left PLUS MINUS ! 54: %left STAR SLASH PCENT ! 55: %left SIZEOF TYPEOF BANG TILDE ! 56: %right UNOP ! 57: %left ARROW DOT LB LP ! 58: ! 59: %% ! 60: ! 61: start: G_EXPR { DotDot=0; } expr SEMI { yyres = (long) $3; } ! 62: | G_DOTDOT { DotDot=1; } expr SEMI { yyres = (long) $3; } ! 63: | G_DOTEQ_CONEX DOT EQUAL conex SEMI { yyres = (long) $4; } ! 64: | G_DOLEQ_CONEX DOLLAR EQUAL conex SEMI { yyres = (long) $4; } ! 65: | G_CONEX conex SEMI { yyres = (long) $2; } ! 66: ! 67: expr: DOLLAR { if( !CurrentExpr){ ! 68: yyerror("$ cannot be used here"); ! 69: YYACCEPT; ! 70: } ! 71: $$ = CurrentExpr; ! 72: } ! 73: | LC expr RC ID { $$ = E_Binary( $2, O_ENV, E_Id($4) ); } ! 74: | ID { $$ = E_Id( $1 ); } ! 75: | DCONST { $$ = E_DConst( $1 ); } ! 76: | ICONST { $$ = E_IConst( $1 ); } ! 77: | STAR expr %prec UNOP { $$ = E_Unary( O_DEREF, $2 ); } ! 78: | AMPER expr { $$ = E_Unary( O_REF, $2 ); } ! 79: | SIZEOF expr { $$ = E_Unary( O_SIZEOF, $2 ); } ! 80: | TYPEOF expr { $$ = E_Unary( O_TYPEOF, $2 ); } ! 81: | BANG expr { $$ = E_Unary( O_LOGNOT, $2 ); } ! 82: | MINUS expr %prec UNOP { $$ = E_Unary( O_MINUS, $2 ); } ! 83: | TILDE expr { $$ = E_Unary( O_1SCOMP, $2 ); } ! 84: | expr DOTDOT expr { if( !DotDot ){ ! 85: yyerror(".. cannot be used here"); ! 86: YYACCEPT; ! 87: } ! 88: $$ = E_Binary( $1, O_RANGE, $3 );} ! 89: | expr DOT ID { $$ = E_Binary( $1, O_DOT, E_Id($3)); } ! 90: | expr COMMA expr { $$ = E_Binary( $1, O_COMMA, $3 ); } ! 91: | expr EQUAL expr { $$ = E_Binary( $1, O_ASSIGN, $3 ); } ! 92: | expr BARBAR expr { $$ = E_Binary( $1, O_LOGOR, $3 ); } ! 93: | expr AMPERAMPER expr { $$ = E_Binary( $1, O_LOGAND, $3 ); } ! 94: | expr BAR expr { $$ = E_Binary( $1, O_BITOR, $3 ); } ! 95: | expr AMPER expr { $$ = E_Binary( $1, O_BITAND, $3 ); } ! 96: | expr HAT expr { $$ = E_Binary( $1, O_BITXOR, $3 ); } ! 97: | expr EQUALEQUAL expr { $$ = E_Binary( $1, O_EQ, $3 ); } ! 98: | expr BANGEQUAL expr { $$ = E_Binary( $1, O_NE, $3 ); } ! 99: | expr LESS expr { $$ = E_Binary( $1, O_LT, $3 ); } ! 100: | expr GREATER expr { $$ = E_Binary( $1, O_GT, $3 ); } ! 101: | expr LESSEQUAL expr { $$ = E_Binary( $1, O_LE, $3 ); } ! 102: | expr GREATEREQUAL expr { $$ = E_Binary( $1, O_GE, $3 ); } ! 103: | expr GREATERGREATER expr{ $$ = E_Binary( $1, O_RSHIFT, $3 ); } ! 104: | expr LESSLESS expr { $$ = E_Binary( $1, O_LSHIFT, $3 ); } ! 105: | expr MINUS expr { $$ = E_Binary( $1, O_MINUS, $3 ); } ! 106: | expr ARROW ID { $$ = E_Binary( $1, O_ARROW, E_Id($3)); } ! 107: | expr PCENT expr { $$ = E_Binary( $1, O_MOD, $3 ); } ! 108: | expr STAR expr { $$ = E_Binary( $1, O_MULT, $3 ); } ! 109: | expr SLASH expr { $$ = E_Binary( $1, O_DIV, $3 ); } ! 110: | expr PLUS expr { $$ = E_Binary( $1, O_PLUS, $3 ); } ! 111: | expr LB expr RB { $$ = E_Binary( $1, O_INDEX, $3 );} ! 112: | ID LP list RP { $$ = E_Binary( E_Id($1), O_CALL, $3 ); } ! 113: | ID LP RP { $$ = E_Binary( E_Id($1), O_CALL, 0 ); } ! 114: | LP expr RP { $$ = $2; } ! 115: | FABS LP expr RP { $$ = E_Unary( O_FABS, $3 ); } ! 116: ! 117: conex: DOLLAR { if( !CurrentExpr){ ! 118: yyerror("no current expression for $"); ! 119: YYACCEPT; ! 120: } ! 121: $$ = CurrentExpr; ! 122: } ! 123: | ID { $$ = E_Id( $1 ); } ! 124: | ICONST { $$ = E_IConst( $1 ); } ! 125: | AMPER conex %prec UNOP { $$ = E_Unary( O_REF, $2 ); } ! 126: | MINUS conex %prec UNOP { $$ = E_Unary( O_MINUS, $2 ); } ! 127: | conex MINUS conex { $$ = E_Binary( $1, O_MINUS, $3 ); } ! 128: | conex PCENT conex { $$ = E_Binary( $1, O_MOD, $3 ); } ! 129: | conex STAR conex { $$ = E_Binary( $1, O_MULT, $3 ); } ! 130: | conex SLASH conex { $$ = E_Binary( $1, O_DIV, $3 ); } ! 131: | conex PLUS conex { $$ = E_Binary( $1, O_PLUS, $3 ); } ! 132: | conex LB conex RB { $$ = E_Binary( $1, O_INDEX, $3 );} ! 133: | LP conex RP { $$ = $2; } ! 134: ! 135: list: expr %prec COMMA { $$ = $1; } ! 136: | list COMMA expr { $$ = E_Binary( $1, O_COMMA, $3 ); } ! 137: ! 138: %% ! 139: ! 140: #define LOOK (LexString[LexIndex ]) ! 141: #define TAKE (AddToken(), LexString[LexIndex++]) ! 142: #define MORE (LexString[LexIndex+1]) ! 143: #define yc (yylval.cc) ! 144: #define yd (yylval.dd) ! 145: #define yl (yylval.ll) ! 146: #define ys (yylval.ss) ! 147: #define ishex(x) (isdigit(x) || (x>='a'&&x<='f') || (x>='A'&&x<='F')) ! 148: #define isoct(x) ( x>='0' && x<='7' ) ! 149: int doyylex(); ! 150: int yyerror(char*); ! 151: ! 152: yylex() ! 153: { ! 154: int token = doyylex(); ! 155: ! 156: return token; ! 157: } ! 158: ! 159: void AddToken() ! 160: { ! 161: int l = strlen(Token); ! 162: ! 163: if( l < 64 ){ ! 164: Token[l] = LOOK; ! 165: Token[l+1] = '\0'; ! 166: } ! 167: } ! 168: ! 169: doyylex() ! 170: { ! 171: double atof(char*); ! 172: ! 173: if( LexIndex < 0 ){ ! 174: LexIndex = 0; ! 175: return LexGoal; ! 176: } ! 177: while( isspace(LOOK) ) TAKE; ! 178: Token[0] = '\0'; ! 179: if( isalpha(LOOK) || LOOK=='_' || LOOK=='$' ){ ! 180: TAKE; ! 181: while( isalnum(LOOK) || LOOK=='_' ) TAKE; ! 182: strcpy( ys, Token ); ! 183: if( !strcmp(ys,"sizeof") ) return SIZEOF; ! 184: if( !strcmp(ys,"typeof") ) return TYPEOF; ! 185: if( !strcmp(ys,"fabs") ) return FABS; ! 186: if( !strcmp(ys,"$") ) return DOLLAR; ! 187: return ID; ! 188: } ! 189: if( LOOK == '\'' ){ ! 190: TAKE; ! 191: if( LOOK == '\\' ){ ! 192: TAKE; ! 193: if( MORE != '\'' ) return 0; ! 194: char *trans = "bnftv", *late = "\b\n\f\t\v"; ! 195: yl = LOOK; ! 196: for( int i = 0; trans[i]; ++i ) ! 197: if( LOOK == trans[i] ) yl = late[i]; ! 198: TAKE; TAKE; return ICONST; ! 199: } ! 200: if( MORE != '\'' ) return 0; ! 201: yl = TAKE; ! 202: TAKE; ! 203: return ICONST; ! 204: } ! 205: if( LOOK=='0' && (MORE=='x' || MORE=='X') ){ ! 206: TAKE; TAKE; ! 207: if( !ishex(LOOK) ) return 0; ! 208: for( yl = 0; ishex(LOOK); TAKE ) ! 209: yl = (yl<<4) + (isalpha(LOOK) ? (LOOK|' ')+10-'a' : LOOK-'0'); ! 210: return ICONST; ! 211: } ! 212: if( LOOK=='0' ){ ! 213: for( TAKE, yl = 0; isoct(LOOK); TAKE ) yl = (yl<<3) + LOOK - '0'; ! 214: goto IorD; ! 215: } ! 216: if( isdigit(LOOK) ){ ! 217: for( yl = 0; isdigit(LOOK); TAKE ) yl = yl*10 + LOOK - '0'; ! 218: goto IorD; ! 219: } ! 220: if( LOOK == '.' && isdigit(MORE) ) goto Point; ! 221: #define EAT2(x) {TAKE; TAKE; return x;} ! 222: if( LOOK=='.' && MORE=='.' ) EAT2(DOTDOT) ! 223: if( LOOK=='-' && MORE=='>' ) EAT2(ARROW) ! 224: if( LOOK=='-' && MORE=='-' ) EAT2(MINUSMINUS) ! 225: if( LOOK=='+' && MORE=='+' ) EAT2(PLUSPLUS) ! 226: if( LOOK=='=' && MORE=='=' ) EAT2(EQUALEQUAL) ! 227: if( LOOK=='!' && MORE=='=' ) EAT2(BANGEQUAL) ! 228: if( LOOK==':' && MORE=='=' ) EAT2(EQUAL) ! 229: if( LOOK=='>' && MORE=='=' ) EAT2(GREATEREQUAL) ! 230: if( LOOK=='<' && MORE=='=' ) EAT2(LESSEQUAL) ! 231: if( LOOK=='&' && MORE=='&' ) EAT2(AMPERAMPER) ! 232: if( LOOK=='|' && MORE=='|' ) EAT2(BARBAR) ! 233: if( LOOK=='>' && MORE=='>' ) EAT2(GREATERGREATER) ! 234: if( LOOK=='<' && MORE=='<' ) EAT2(LESSLESS) ! 235: switch( TAKE ){ ! 236: case '>' : return GREATER; ! 237: case '<' : return LESS; ! 238: case '/' : return SLASH; ! 239: case '*' : return STAR; ! 240: case '+' : return PLUS; ! 241: case '-' : return MINUS; ! 242: case '.' : return DOT; ! 243: case '(' : return LP; ! 244: case ')' : return RP; ! 245: case '[' : return LB; ! 246: case ']' : return RB; ! 247: case '&' : return AMPER; ! 248: case ',' : return COMMA; ! 249: case '%' : return PCENT; ! 250: case '=' : return EQUAL; ! 251: case ';' : return SEMI; ! 252: case '|' : return BAR; ! 253: case '^' : return HAT; ! 254: case '~' : return TILDE; ! 255: case '!' : return BANG; ! 256: case '{' : return LC; ! 257: case '}' : return RC; ! 258: default : return 0; ! 259: } ! 260: IorD: ! 261: if( LOOK=='l' || LOOK=='L' ) return TAKE, ICONST; ! 262: if( LOOK=='.' && MORE=='.' ) return ICONST; ! 263: if( LOOK=='.' ) goto Point; ! 264: if( LOOK=='e' || LOOK=='E' ) goto Exp; ! 265: return ICONST; ! 266: Point: ! 267: for( TAKE; isdigit(LOOK); TAKE) {} ! 268: if( LOOK!='e' && LOOK!='E' ) goto Double; ! 269: Exp: ! 270: TAKE; ! 271: if( LOOK=='+' || LOOK=='-' ) TAKE; ! 272: if( !isdigit(LOOK) ) return 0; ! 273: while( isdigit(LOOK) ) TAKE; ! 274: Double: ! 275: yd = atof(Token); ! 276: return DCONST; ! 277: ! 278: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.