Annotation of parser3/src/main/compile.y, revision 1.47
1.24 paf 1: /*
1.47 ! paf 2: $Id: compile.y,v 1.46 2001/02/26 09:54:14 paf Exp $
1.24 paf 3: */
4:
1.1 paf 5: %{
1.9 paf 6: #define YYSTYPE Array/*<op>*/ *
7: #define YYPARSE_PARAM pc
8: #define YYLEX_PARAM pc
9: #define YYDEBUG 1
1.1 paf 10: #define YYERROR_VERBOSE
1.9 paf 11: #define yyerror(msg) real_yyerror((parse_control *)pc, msg)
12: #define YYPRINT(file, type, value) yyprint(file, type, value)
1.1 paf 13:
14: #include <stdio.h>
15: #include <string.h>
16: #include <stdlib.h>
17:
18: #include "compile_tools.h"
1.8 paf 19: #include "pa_value.h"
1.12 paf 20: #include "pa_request.h"
1.39 paf 21: #include "pa_vobject.h"
22:
23: #define SELF_NAME "self"
24: #define USES_NAME "USES"
1.1 paf 25:
1.9 paf 26: int real_yyerror(parse_control *pc, char *s);
27: static void yyprint(FILE *file, int type, YYSTYPE value);
1.1 paf 28: int yylex(YYSTYPE *lvalp, void *pc);
29:
30:
1.8 paf 31: // local convinient inplace typecast & var
1.9 paf 32: #define PC ((parse_control *)pc)
1.25 paf 33: #define POOL *PC->pool
34: #undef NEW
35: #define NEW new(POOL)
1.1 paf 36: %}
37:
38: %pure_parser
39:
1.13 paf 40: %token EON
1.4 paf 41: %token STRING
1.1 paf 42: %token BOGUS
43:
44: %%
45:
1.10 paf 46: all:
47: one_big_piece {
1.25 paf 48: String& name_main=*NEW String(POOL);
1.11 paf 49: name_main.APPEND_CONST(MAIN_METHOD_NAME);
1.25 paf 50: Array& param_names=*NEW Array(POOL);
51: Array& local_names=*NEW Array(POOL);
1.34 paf 52: Method& method=*NEW Method(POOL, name_main, param_names, local_names, *$1);
53: PC->vclass->add_method(name_main, method);
1.10 paf 54: }
55: | methods;
56:
57: methods: method | methods method;
58: one_big_piece: maybe_codes;
59:
1.34 paf 60: method: control_method | code_method;
61:
62: control_method: '@' STRING '\n'
63: control_strings {
1.38 paf 64: String& name=*SLA2S($2);
1.34 paf 65: YYSTYPE strings_code=$4;
1.37 paf 66: if(strings_code->size()<1*2) {
67: strcpy(PC->error, "@");
68: strcat(PC->error, name.cstr());
69: strcat(PC->error, " is empty");
70: YYERROR;
71: }
1.36 paf 72: if(name==CLASS_NAME) {
1.34 paf 73: if(strings_code->size()==1*2)
1.38 paf 74: PC->vclass->set_name(*SLA2S(strings_code));
1.34 paf 75: else {
76: strcpy(PC->error, "@"CLASS_NAME" must contain sole name");
77: YYERROR;
78: }
79: } else {
1.36 paf 80: if(name==USES_NAME) {
1.34 paf 81: for(int i=0; i<strings_code->size(); i+=2) {
1.38 paf 82: String *file=SLA2S(strings_code, i);
1.35 paf 83: file->APPEND_CONST(".p");
84: PC->request->use(file->cstr(), 0);
1.34 paf 85: }
1.45 paf 86: } else if(name==BASE_NAME) {
87: if(strings_code->size()==1*2) {
88: String& base_name=*SLA2S(strings_code);
89: VClass *base=static_cast<VClass *>(
90: PC->request->classes().get(base_name));
91: if(!base) {
92: strcpy(PC->error, base_name.cstr());
93: strcat(PC->error, ": undefined class in @"BASE_NAME);
1.34 paf 94: YYERROR;
95: }
1.45 paf 96: PC->vclass->set_base(*base);
97: } else {
98: strcpy(PC->error, "@"BASE_NAME" must contain sole name");
99: YYERROR;
1.34 paf 100: }
101: } else {
1.36 paf 102: strcpy(PC->error, name.cstr());
1.34 paf 103: strcat(PC->error, ": invalid special name. valid names are "
1.45 paf 104: CLASS_NAME", "USES_NAME" and "BASE_NAME);
1.34 paf 105: YYERROR;
106: }
107: }
108: };
1.37 paf 109: control_strings: control_string | control_strings control_string { $$=$1; P($$, $2) };
110: control_string: maybe_string '\n';
111: maybe_string: empty | STRING;
1.34 paf 112:
113: code_method: '@' STRING bracketed_maybe_strings maybe_bracketed_strings maybe_comment '\n'
1.10 paf 114: maybe_codes {
1.38 paf 115: const String *name=SLA2S($2);
1.10 paf 116:
117: YYSTYPE params_names_code=$3;
1.25 paf 118: Array& params_names=*NEW Array(POOL);
1.10 paf 119: for(int i=0; i<params_names_code->size(); i+=2)
1.38 paf 120: params_names+=SLA2S(params_names_code, i);
1.10 paf 121:
122: YYSTYPE locals_names_code=$4;
1.25 paf 123: Array& locals_names=*NEW Array(POOL);
1.10 paf 124: for(int i=0; i<locals_names_code->size(); i+=2)
1.38 paf 125: locals_names+=SLA2S(locals_names_code, i);
1.10 paf 126:
1.34 paf 127: Method& method=*NEW Method(POOL, *name, params_names, locals_names, *$7);
128: PC->vclass->add_method(*name, method);
1.8 paf 129: };
1.10 paf 130:
131: maybe_bracketed_strings: empty | bracketed_maybe_strings;
132: bracketed_maybe_strings: '[' maybe_strings ']' {$$=$2};
133: maybe_strings: empty | strings;
134: strings: STRING | strings ';' STRING { $$=$1; P($$, $3) };
135:
136: maybe_comment: empty | STRING;
1.1 paf 137:
138: /* codes */
139:
1.10 paf 140: maybe_codes: empty | codes;
141:
1.1 paf 142: codes: code | codes code {
143: $$=$1;
1.9 paf 144: P($$, $2);
1.1 paf 145: };
146: code: write_str_literal | action;
147: action: get | put | with | call;
148:
149: /* get */
150:
1.42 paf 151: get: '$' get_name {
1.1 paf 152: $$=$2; /* stack: resulting value */
1.17 paf 153: OP($$, OP_WRITE); /* value=pop; write(value) */
1.1 paf 154: };
1.43 paf 155: get_name: name_without_curly_rdive EON | name_in_curly_rdive;
1.1 paf 156: name_in_curly_rdive: '{' name_without_curly_rdive '}' { $$=$2 };
1.44 paf 157: name_without_curly_rdive:
158: name_without_curly_rdive_read
159: | name_without_curly_rdive_root
160: | name_without_curly_rdive_class;
1.19 paf 161: name_without_curly_rdive_read: name_without_curly_rdive_code {
1.25 paf 162: $$=N(POOL);
1.22 paf 163: Array *diving_code=$1;
1.38 paf 164: String *first_name=SLA2S(diving_code);
1.23 paf 165: if(first_name && *first_name==SELF_NAME) {
1.22 paf 166: OP($$, OP_WITH_SELF); /* stack: starting context */
167: P($$, diving_code,
168: /* skip over... */
169: diving_code->size()>2?3/*OP_+string+get_element*/:2/*OP_+string*/);
170: } else {
171: OP($$, OP_WITH_READ); /* stack: starting context */
172: P($$, diving_code);
173: }
174: /* diving code; stack: current context */
1.1 paf 175: };
1.19 paf 176: name_without_curly_rdive_root: ':' name_without_curly_rdive_code {
1.25 paf 177: $$=N(POOL);
1.19 paf 178: OP($$, OP_WITH_ROOT); /* stack: starting context */
179: P($$, $2); /* diving code; stack: current context */
180: };
1.44 paf 181: name_without_curly_rdive_class: class_prefix name_without_curly_rdive_code { $$=$1; P($$, $2) };
1.19 paf 182: name_without_curly_rdive_code: name_advance2 | name_path name_advance2 { $$=$1; P($$, $2) };
1.1 paf 183:
184: /* put */
185:
1.47 ! paf 186: put: '$' name_expr_wdive '[' constructor_value ']' {
1.20 paf 187: $$=$2; /* stack: context,name */
188: P($$, $4); /* stack: context,name,constructor_value */
189: OP($$, OP_CONSTRUCT); /* value=pop; name=pop; context=pop; construct(context,name,value) */
190: };
1.44 paf 191: name_expr_wdive:
192: name_expr_wdive_write
193: | name_expr_wdive_root
194: | name_expr_wdive_class;
1.28 paf 195: name_expr_wdive_write: name_expr_dive_code {
1.44 paf 196: $$=N(POOL);
1.23 paf 197: Array *diving_code=$1;
1.38 paf 198: String *first_name=SLA2S(diving_code);
1.23 paf 199: if(first_name && *first_name==SELF_NAME) {
200: OP($$, OP_WITH_SELF); /* stack: starting context */
201: P($$, diving_code,
202: /* skip over... */
203: diving_code->size()>2?3/*OP_+string+get_element*/:2/*OP_+string*/);
204: } else {
205: OP($$, OP_WITH_WRITE); /* stack: starting context */
206: P($$, diving_code);
207: }
208: /* diving code; stack: current context */
1.20 paf 209: };
1.28 paf 210: name_expr_wdive_root: ':' name_expr_dive_code {
1.25 paf 211: $$=N(POOL);
1.20 paf 212: OP($$, OP_WITH_ROOT); /* stack: starting context */
1.9 paf 213: P($$, $2); /* diving code; stack: context,name */
1.1 paf 214: };
1.44 paf 215: name_expr_wdive_class: class_prefix name_expr_dive_code { $$=$1; P($$, $2) };
1.20 paf 216:
1.1 paf 217: constructor_value:
1.32 paf 218: constructor_one_param_value
219: | constructor_two_params_value /* $var(=;2*2) $var(%d;2*2) $var(+;1) */
1.1 paf 220: ;
1.27 paf 221:
1.32 paf 222: constructor_one_param_value:
223: empty_value /* optimized $var() case */
224: | STRING /* optimized $var(STRING) case */
225: | complex_constructor_param_value /* $var(something complex) */
1.1 paf 226: ;
227: complex_constructor_param_value: complex_constructor_param_body {
1.25 paf 228: $$=N(POOL);
1.3 paf 229: OP($$, OP_CREATE_EWPOOL); /* stack: empty write context */
1.9 paf 230: P($$, $1); /* some codes to that context */
231: OP($$, OP_REDUCE_EWPOOL); /* context=pop; stack: context.value() */
1.1 paf 232: };
1.27 paf 233: complex_constructor_param_body: codes__excluding_sole_str_literal;
234: codes__excluding_sole_str_literal: action | code codes { $$=$1; P($$, $2) };
235:
1.32 paf 236: constructor_two_params_value: STRING ';' constructor_one_param_value {
1.38 paf 237: char *operator_or_fmt=SLA2S($1)->cstr();
1.25 paf 238: $$=N(POOL);
1.9 paf 239: P($$, $1); /* stack: ncontext name operator_or_fmt */
1.3 paf 240: P($$, $3); /* stack: ncontext name operator_or_fmt expr */
1.1 paf 241: switch(operator_or_fmt[0]) {
242: case '=': case '%':
1.3 paf 243: OP($$, OP_EXPRESSION_EVAL);
1.1 paf 244: break;
245: case '+': case '-': case '*': case '/':
1.3 paf 246: OP($$, OP_MODIFY_EVAL);
1.1 paf 247: break;
248: default:
1.6 paf 249: strcpy(PC->error, "invalid modification operator");
250: YYERROR;
1.1 paf 251: }
252: /* stack: ncontext name value */
253: };
254:
255: /* call */
256:
1.38 paf 257: call: '^' call_name store_params EON { /* ^field.$method{vasya} */
1.42 paf 258: $$=$2; /* with_xxx,diving code; stack: context,method_junction */
1.9 paf 259: OP($$, OP_GET_METHOD_FRAME); /* stack: context,method_frame */
260: P($$, $3); /* filling method_frame.store_params */
261: OP($$, OP_CALL); /* method_frame=pop; ncontext=pop; call(ncontext,method_frame) */
1.1 paf 262: };
263:
1.43 paf 264: call_name: name_without_curly_rdive;
1.38 paf 265:
1.9 paf 266: store_params: store_param | store_params store_param { $$=$1; P($$, $2) };
1.1 paf 267: store_param: store_round_param | store_curly_param;
1.47 ! paf 268: store_round_param: '[' store_param_parts ']' {$$=$2};
1.31 paf 269: store_param_parts:
1.32 paf 270: store_param_part
271: | store_param_parts ';' store_param_part { $$=$1; P($$, $3) }
1.31 paf 272: ;
1.10 paf 273: store_curly_param: '{' maybe_codes '}' {
1.25 paf 274: $$=N(POOL);
1.29 paf 275: PCA($$, $2);
1.9 paf 276: OP($$, OP_STORE_PARAM);
1.1 paf 277: };
1.32 paf 278: store_param_part:
1.33 paf 279: empty /* optimized () case */
280: | STRING { /* optimized (STRING) case */
1.32 paf 281: $$=$1;
282: OP($$, OP_STORE_PARAM);
283: }
1.33 paf 284: | complex_constructor_param_value { /* (something complex) */
1.32 paf 285: $$=$1;
286: OP($$, OP_STORE_PARAM);
287: }
288: ;
1.1 paf 289:
290: /* name */
291:
1.20 paf 292: name_expr_dive_code: name_expr_value | name_path name_expr_value { $$=$1; P($$, $2) };
1.1 paf 293:
1.9 paf 294: name_path: name_step | name_path name_step { $$=$1; P($$, $2) };
1.1 paf 295: name_step: name_advance1 '.';
296: name_advance1: name_expr_value {
297: /* stack: context */
298: $$=$1; /* stack: context,name */
1.9 paf 299: OP($$, OP_GET_ELEMENT); /* name=pop; context=pop; stack: context.get_element(name) */
1.1 paf 300: };
301: name_advance2: name_expr_value {
302: /* stack: context */
303: $$=$1; /* stack: context,name */
1.9 paf 304: OP($$, OP_GET_ELEMENT); /* name=pop; context=pop; stack: context.get_element(name) */
1.1 paf 305: }
1.4 paf 306: | STRING BOGUS
1.1 paf 307: ;
308: name_expr_value:
1.4 paf 309: STRING /* subname_is_const */
1.1 paf 310: | name_expr_subvar_value /* $subname_is_var_value */
311: | name_expr_with_subvar_value /* xxx$part_of_subname_is_var_value[$...] */
312: ;
313: name_expr_subvar_value: '$' subvar_ref_name_rdive {
314: $$=$2;
1.9 paf 315: OP($$, OP_GET_ELEMENT);
1.1 paf 316: };
1.4 paf 317: name_expr_with_subvar_value: STRING subvar_get_writes {
1.25 paf 318: $$=N(POOL);
1.3 paf 319: OP($$, OP_CREATE_EWPOOL);
1.9 paf 320: P($$, $1);
1.17 paf 321: OP($$, OP_WRITE);
1.9 paf 322: P($$, $2);
323: OP($$, OP_REDUCE_EWPOOL);
1.1 paf 324: };
1.18 paf 325: subvar_ref_name_rdive: subvar_ref_name_rdive_read | subvar_ref_name_rdive_root;
326: subvar_ref_name_rdive_read: STRING {
1.25 paf 327: $$=N(POOL);
1.18 paf 328: OP($$, OP_WITH_READ);
1.9 paf 329: P($$, $1);
1.1 paf 330: };
1.18 paf 331: subvar_ref_name_rdive_root: ':' STRING {
1.25 paf 332: $$=N(POOL);
1.18 paf 333: OP($$, OP_WITH_ROOT);
334: P($$, $2);
335: };
1.9 paf 336: subvar_get_writes: subvar__get_write | subvar_get_writes subvar__get_write { $$=$1; P($$, $2) };
1.1 paf 337: subvar__get_write: '$' subvar_ref_name_rdive {
338: $$=$2;
1.17 paf 339: OP($$, OP_GET_ELEMENT__WRITE);
1.42 paf 340: };
341:
1.44 paf 342: class_prefix: STRING ':' {
1.42 paf 343: String& name=*SLA2S($1);
344: VClass *vclass=static_cast<VClass *>(PC->request->classes().get(name));
345: if(!vclass) {
346: strcpy(PC->error, "'");
347: strcat(PC->error, name.cstr());
348: strcat(PC->error, "' class is undefined in call");
349: YYERROR;
350: }
351: $$=CL(vclass); // vclass
1.1 paf 352: };
353:
354:
355: /* with */
356:
357: with: '$' name_without_curly_rdive '{' codes '}' {
358: $$=$2;
1.9 paf 359: OP($$, OP_CREATE_RWPOOL);
360: P($$, $4);
361: OP($$, OP_REDUCE_RWPOOL);
1.17 paf 362: OP($$, OP_WRITE);
1.1 paf 363: };
364:
1.27 paf 365: /* basics */
1.1 paf 366:
1.4 paf 367: write_str_literal: STRING {
1.38 paf 368: if(SLA2S($1)->size()) {
1.30 paf 369: $$=$1;
370: OP($$, OP_WRITE);
371: } else {
372: // optimized case of special end of macro. see yylex
373: $$=N(POOL);
374: }
1.26 paf 375: };
1.38 paf 376: empty_value: /* empty */ { $$=SL(NEW VString(POOL)) };
1.25 paf 377: empty: /* empty */ { $$=N(POOL) };
1.1 paf 378:
379: %%
380:
381: /*
382: 000$111(2222)00
383: 000$111{3333}00
1.9 paf 384: $,^: push,=0
1.1 paf 385: 1:( { break=pop
386: 2:( ) pop
387: 3:{ } pop
388:
389: 000^111(2222)4444{33333}4000
1.9 paf 390: $,^: push,=0
1.1 paf 391: 1:( { break=pop
392: 2:( )=4
393: 3:{ }=4
394: 4:[^({]=pop
395: */
396:
397: int yylex(YYSTYPE *lvalp, void *pc) {
398: #define lexical_brackets_nestage PC->brackets_nestages[PC->sp]
399:
400: register int c;
401: int result;
402:
403: if(PC->pending_state) {
404: result=PC->pending_state;
405: PC->pending_state=0;
406: return result;
407: }
408:
1.9 paf 409: char *begin=PC->source;
410: char *end;
411: int begin_line=PC->line;
1.1 paf 412: while(1) {
1.9 paf 413: c=*(end=(PC->source++));
1.1 paf 414:
1.4 paf 415: if(c=='\n') {
1.1 paf 416: PC->line++;
1.8 paf 417: PC->col=0;
1.10 paf 418: } else
1.4 paf 419: PC->col++;
1.1 paf 420:
1.40 paf 421: // escaping: ^^ ^$ ^; ^) ^} ^( ^{
1.1 paf 422: if(c=='^') {
1.40 paf 423: char next_c=*PC->source;
1.1 paf 424:
1.40 paf 425: if(next_c=='^' || next_c=='$' || next_c==';' ||
1.47 ! paf 426: next_c=='[' || next_c==']' ||
1.40 paf 427: next_c=='{' || next_c=='}') {
428: if(end!=begin) {
429: // append piece till ^
430: PC->string->APPEND(begin, end-begin, PC->file, begin_line);
431: }
432: // reset piece 'start' position & line
433: begin=PC->source; // ^
1.9 paf 434: begin_line=PC->line;
1.40 paf 435: // skip over ^ and _
436: PC->source++;
437: // skip analysis = forced literal
1.1 paf 438: continue;
439: }
440: }
441: switch(PC->ls) {
1.10 paf 442:
443: // USER'S = NOT OURS
1.1 paf 444: case LS_USER:
445: if(c=='$') {
1.10 paf 446: push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1 paf 447: result=c;
448: goto break2;
449: }
450: if(c=='^') {
1.10 paf 451: push_LS(PC, LS_METHOD_NAME);
452: result=c;
453: goto break2;
454: }
455: if(c=='@' && PC->col==0+1) {
1.1 paf 456: result=c;
1.10 paf 457: push_LS(PC, LS_DEF_NAME);
458: goto break2;
459: }
460:
461: break;
462:
463: // METHOD DEFINITION
464: case LS_DEF_NAME:
465: if(c=='[') {
466: result=c;
467: PC->ls=LS_DEF_PARAMS;
468: goto break2;
469: }
1.37 paf 470: if(c=='\n') {
1.10 paf 471: result=c;
1.37 paf 472: PC->ls=LS_SPEC_CODE;
1.10 paf 473: goto break2;
474: }
475: break;
476: case LS_DEF_PARAMS:
477: if(c==';') {
478: result=c;
479: goto break2;
480: }
481: if(c==']') {
482: result=c;
483: PC->ls=*PC->source=='['?LS_DEF_LOCALS:LS_DEF_COMMENT;
484: goto break2;
485: }
486: if(c=='\n') { // wrong. bailing out
487: result=c;
488: pop_LS(PC);
489: goto break2;
490: }
491: break;
492: case LS_DEF_LOCALS:
493: if(c=='[' || c==';') {
494: result=c;
495: goto break2;
496: }
497: if(c==']') {
498: result=c;
499: PC->ls=LS_DEF_COMMENT;
500: goto break2;
501: }
502: if(c=='\n') { // wrong. bailing out
503: result=c;
504: pop_LS(PC);
505: goto break2;
506: }
507: break;
508: case LS_DEF_COMMENT:
509: if(c=='\n') {
510: result=c;
511: pop_LS(PC);
1.37 paf 512: goto break2;
513: }
514: break;
515:
516: case LS_SPEC_CODE:
517: if(c=='\n') {
518: result=c;
519: if(*PC->source=='@' || *PC->source==0) // end of special_code
520: pop_LS(PC);
1.1 paf 521: goto break2;
522: }
523: break;
524:
1.10 paf 525: // VARIABLE GET/PUT/WITH
1.1 paf 526: case LS_VAR_NAME_SIMPLE:
527: if(c==0 ||
528: c==' '|| c=='\t' || c=='\n' ||
1.47 ! paf 529: c==';' ||
! 530: c==']' || c=='}') {
1.1 paf 531: pop_LS(PC);
1.32 paf 532: PC->source--; if(--PC->col<0) { PC->line--; PC->col=-1; }
1.13 paf 533: result=EON;
1.1 paf 534: goto break2;
535: }
1.13 paf 536: if(begin==end && c=='{') { /* ${name}, no need of EON, switching LS */
1.1 paf 537: PC->ls=LS_VAR_NAME_CURLY;
538: result=c;
539: goto break2;
540: }
1.47 ! paf 541: if(c=='[') {
1.1 paf 542: PC->ls=LS_VAR_ROUND;
543: lexical_brackets_nestage=1;
544: result=c;
545: goto break2;
546: }
547: if(c=='{') {
548: PC->ls=LS_VAR_CURLY;
549: lexical_brackets_nestage=1;
550: result=c;
551: goto break2;
552: }
1.39 paf 553: if(c=='.'/* name part delim */ ||
554: c=='$'/* name part subvar */ ||
555: c==':'/* ':name' or 'class:name' */) {
1.1 paf 556: result=c;
557: goto break2;
558: }
559: break;
560: case LS_VAR_NAME_CURLY:
561: if(c=='}') { /* ${name} finished, restoring LS */
562: pop_LS(PC);
563: result=c;
564: goto break2;
565: }
1.39 paf 566: if(c=='.'/* name part delim */ ||
567: c=='$'/*name part subvar*/ ||
568: c==':'/* ':name' or 'class:name' */) {
1.1 paf 569: result=c;
570: goto break2;
571: }
572: break;
573: case LS_VAR_ROUND:
574: if(c=='$') {
1.10 paf 575: push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1 paf 576: result=c;
577: goto break2;
578: }
579: if(c=='^') {
1.10 paf 580: push_LS(PC, LS_METHOD_NAME);
1.1 paf 581: result=c;
582: goto break2;
583: }
1.47 ! paf 584: if(c==']') {
1.1 paf 585: if(--lexical_brackets_nestage==0) {
586: pop_LS(PC);
587: result=c;
588: goto break2;
589: }
590: }
591: if(c==';'/* operator_or_fmt;value delim */) {
592: result=c;
593: goto break2;
594: }
1.47 ! paf 595: if(c=='[')
1.1 paf 596: lexical_brackets_nestage++;
597: break;
598: case LS_VAR_CURLY:
599: if(c=='$') {
1.10 paf 600: push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1 paf 601: result=c;
602: goto break2;
603: }
604: if(c=='^') {
1.10 paf 605: push_LS(PC, LS_METHOD_NAME);
1.1 paf 606: result=c;
607: goto break2;
608: }
609: if(c=='}')
610: if(--lexical_brackets_nestage==0) {
611: pop_LS(PC);
612: result=c;
613: goto break2;
614: }
615: if(c=='{')
616: lexical_brackets_nestage++;
617: break;
618:
1.10 paf 619: // METHOD CALL
1.1 paf 620: case LS_METHOD_NAME:
1.47 ! paf 621: if(c=='[') {
1.1 paf 622: PC->ls=LS_METHOD_ROUND;
623: lexical_brackets_nestage=1;
624: result=c;
625: goto break2;
626: }
627: if(c=='{') {
628: PC->ls=LS_METHOD_CURLY;
629: lexical_brackets_nestage=1;
630: result=c;
631: goto break2;
632: }
1.39 paf 633: if(c=='.'/* name part delim */ ||
634: c=='$'/* name part subvar */ ||
635: c==':'/* ':name' or 'class:name' */) {
1.1 paf 636: result=c;
637: goto break2;
638: }
639: break;
640: case LS_METHOD_ROUND:
641: if(c=='$') {
1.10 paf 642: push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1 paf 643: result=c;
644: goto break2;
645: }
646: if(c=='^') {
1.10 paf 647: push_LS(PC, LS_METHOD_NAME);
1.1 paf 648: result=c;
649: goto break2;
650: }
651: if(c==';'/* param delim */) {
652: result=c;
653: goto break2;
654: }
1.47 ! paf 655: if(c==']')
1.1 paf 656: if(--lexical_brackets_nestage==0) {
657: PC->ls=LS_METHOD_AFTER;
658: result=c;
659: goto break2;
660: }
1.47 ! paf 661: if(c=='[')
1.1 paf 662: lexical_brackets_nestage++;
663: break;
664: case LS_METHOD_CURLY:
665: if(c=='$') {
1.10 paf 666: push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1 paf 667: result=c;
668: goto break2;
669: }
670: if(c=='^') {
1.10 paf 671: push_LS(PC, LS_METHOD_NAME);
1.1 paf 672: result=c;
673: goto break2;
674: }
675: if(c=='}')
676: if(--lexical_brackets_nestage==0) {
677: PC->ls=LS_METHOD_AFTER;
678: result=c;
679: goto break2;
680: }
681: if(c=='{')
682: lexical_brackets_nestage++;
683: break;
684: case LS_METHOD_AFTER:
1.47 ! paf 685: if(c=='[') {/* )( }( */
1.1 paf 686: PC->ls=LS_METHOD_ROUND;
687: lexical_brackets_nestage=1;
688: result=c;
689: goto break2;
690: }
691: if(c=='{') {/* ){ }{ */
692: PC->ls=LS_METHOD_CURLY;
693: lexical_brackets_nestage=1;
694: result=c;
695: goto break2;
696: }
697: pop_LS(PC);
1.32 paf 698: PC->source--; if(--PC->col<0) { PC->line--; PC->col=-1; }
1.13 paf 699: result=EON;
1.1 paf 700: goto break2;
701: }
1.9 paf 702: if(c==0) {
1.1 paf 703: result=-1;
704: break;
705: }
706: }
707:
708: break2:
1.9 paf 709: if(begin==end)
1.1 paf 710: return result;
711: else {
712: PC->pending_state=result;
1.10 paf 713: // strip last \n before LS_DEF_NAME or EOF
714: if((c=='@' || c==0) && end[-1]=='\n')
715: end--;
1.30 paf 716: if(end!=begin) {
717: // append last piece
718: PC->string->APPEND(begin, end-begin, PC->file, begin_line/*, start_col*/);
719: }
1.17 paf 720: // create STRING value: array of OP_VALUE+vstring
1.45 paf 721: *lvalp=SL(NEW VString(*PC->string));
1.10 paf 722: // new pieces storage
1.25 paf 723: PC->string=NEW String(POOL);
1.10 paf 724: // go!
1.4 paf 725: return STRING;
1.1 paf 726: }
727: }
728:
1.9 paf 729: int real_yyerror(parse_control *pc, char *s) /* Called by yyparse on error */
1.1 paf 730: {
1.16 paf 731: //fprintf(stderr, "[%s]\n", s);
1.6 paf 732:
1.46 paf 733: strncpy(pc->error, s, MAX_STRING); // TODO: перепроверить с треклятым последним байтом
1.1 paf 734: return 1;
735: }
736:
737: static void
1.9 paf 738: yyprint(
1.1 paf 739: FILE *file,
740: int type,
741: YYSTYPE value)
742: {
1.9 paf 743: if(type==STRING)
1.38 paf 744: fprintf(file, " \"%s\"", SLA2S(value)->cstr());
1.1 paf 745: }
746:
E-mail: