|
|
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.