Annotation of parser3/src/main/compile.y, revision 1.45
1.24 paf 1: /*
1.45 ! paf 2: $Id: compile.y,v 1.44 2001/02/25 10:48:59 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.28 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;
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==';' ||
426: next_c=='(' || next_c==')' ||
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' ||
529: c==')' || c=='}') {
530: pop_LS(PC);
1.32 paf 531: PC->source--; if(--PC->col<0) { PC->line--; PC->col=-1; }
1.13 paf 532: result=EON;
1.1 paf 533: goto break2;
534: }
1.13 paf 535: if(begin==end && c=='{') { /* ${name}, no need of EON, switching LS */
1.1 paf 536: PC->ls=LS_VAR_NAME_CURLY;
537: result=c;
538: goto break2;
539: }
540: if(c=='(') {
541: PC->ls=LS_VAR_ROUND;
542: lexical_brackets_nestage=1;
543: result=c;
544: goto break2;
545: }
546: if(c=='{') {
547: PC->ls=LS_VAR_CURLY;
548: lexical_brackets_nestage=1;
549: result=c;
550: goto break2;
551: }
1.39 paf 552: if(c=='.'/* name part delim */ ||
553: c=='$'/* name part subvar */ ||
554: c==':'/* ':name' or 'class:name' */) {
1.1 paf 555: result=c;
556: goto break2;
557: }
558: break;
559: case LS_VAR_NAME_CURLY:
560: if(c=='}') { /* ${name} finished, restoring LS */
561: pop_LS(PC);
562: result=c;
563: goto break2;
564: }
1.39 paf 565: if(c=='.'/* name part delim */ ||
566: c=='$'/*name part subvar*/ ||
567: c==':'/* ':name' or 'class:name' */) {
1.1 paf 568: result=c;
569: goto break2;
570: }
571: break;
572: case LS_VAR_ROUND:
573: if(c=='$') {
1.10 paf 574: push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1 paf 575: result=c;
576: goto break2;
577: }
578: if(c=='^') {
1.10 paf 579: push_LS(PC, LS_METHOD_NAME);
1.1 paf 580: result=c;
581: goto break2;
582: }
583: if(c==')') {
584: if(--lexical_brackets_nestage==0) {
585: pop_LS(PC);
586: result=c;
587: goto break2;
588: }
589: }
590: if(c==';'/* operator_or_fmt;value delim */) {
591: result=c;
592: goto break2;
593: }
594: if(c=='(')
595: lexical_brackets_nestage++;
596: break;
597: case LS_VAR_CURLY:
598: if(c=='$') {
1.10 paf 599: push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1 paf 600: result=c;
601: goto break2;
602: }
603: if(c=='^') {
1.10 paf 604: push_LS(PC, LS_METHOD_NAME);
1.1 paf 605: result=c;
606: goto break2;
607: }
608: if(c=='}')
609: if(--lexical_brackets_nestage==0) {
610: pop_LS(PC);
611: result=c;
612: goto break2;
613: }
614: if(c=='{')
615: lexical_brackets_nestage++;
616: break;
617:
1.10 paf 618: // METHOD CALL
1.1 paf 619: case LS_METHOD_NAME:
620: if(c=='(') {
621: PC->ls=LS_METHOD_ROUND;
622: lexical_brackets_nestage=1;
623: result=c;
624: goto break2;
625: }
626: if(c=='{') {
627: PC->ls=LS_METHOD_CURLY;
628: lexical_brackets_nestage=1;
629: result=c;
630: goto break2;
631: }
1.39 paf 632: if(c=='.'/* name part delim */ ||
633: c=='$'/* name part subvar */ ||
634: c==':'/* ':name' or 'class:name' */) {
1.1 paf 635: result=c;
636: goto break2;
637: }
638: break;
639: case LS_METHOD_ROUND:
640: if(c=='$') {
1.10 paf 641: push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1 paf 642: result=c;
643: goto break2;
644: }
645: if(c=='^') {
1.10 paf 646: push_LS(PC, LS_METHOD_NAME);
1.1 paf 647: result=c;
648: goto break2;
649: }
650: if(c==';'/* param delim */) {
651: result=c;
652: goto break2;
653: }
654: if(c==')')
655: if(--lexical_brackets_nestage==0) {
656: PC->ls=LS_METHOD_AFTER;
657: result=c;
658: goto break2;
659: }
660: if(c=='(')
661: lexical_brackets_nestage++;
662: break;
663: case LS_METHOD_CURLY:
664: if(c=='$') {
1.10 paf 665: push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1 paf 666: result=c;
667: goto break2;
668: }
669: if(c=='^') {
1.10 paf 670: push_LS(PC, LS_METHOD_NAME);
1.1 paf 671: result=c;
672: goto break2;
673: }
674: if(c=='}')
675: if(--lexical_brackets_nestage==0) {
676: PC->ls=LS_METHOD_AFTER;
677: result=c;
678: goto break2;
679: }
680: if(c=='{')
681: lexical_brackets_nestage++;
682: break;
683: case LS_METHOD_AFTER:
684: if(c=='(') {/* )( }( */
685: PC->ls=LS_METHOD_ROUND;
686: lexical_brackets_nestage=1;
687: result=c;
688: goto break2;
689: }
690: if(c=='{') {/* ){ }{ */
691: PC->ls=LS_METHOD_CURLY;
692: lexical_brackets_nestage=1;
693: result=c;
694: goto break2;
695: }
696: pop_LS(PC);
1.32 paf 697: PC->source--; if(--PC->col<0) { PC->line--; PC->col=-1; }
1.13 paf 698: result=EON;
1.1 paf 699: goto break2;
700: }
1.9 paf 701: if(c==0) {
1.1 paf 702: result=-1;
703: break;
704: }
705: }
706:
707: break2:
1.9 paf 708: if(begin==end)
1.1 paf 709: return result;
710: else {
711: PC->pending_state=result;
1.10 paf 712: // strip last \n before LS_DEF_NAME or EOF
713: if((c=='@' || c==0) && end[-1]=='\n')
714: end--;
1.30 paf 715: if(end!=begin) {
716: // append last piece
717: PC->string->APPEND(begin, end-begin, PC->file, begin_line/*, start_col*/);
718: }
1.17 paf 719: // create STRING value: array of OP_VALUE+vstring
1.45 ! paf 720: *lvalp=SL(NEW VString(*PC->string));
1.10 paf 721: // new pieces storage
1.25 paf 722: PC->string=NEW String(POOL);
1.10 paf 723: // go!
1.4 paf 724: return STRING;
1.1 paf 725: }
726: }
727:
1.9 paf 728: int real_yyerror(parse_control *pc, char *s) /* Called by yyparse on error */
1.1 paf 729: {
1.16 paf 730: //fprintf(stderr, "[%s]\n", s);
1.6 paf 731:
732: s[MAX_STRING-1]=0; strcpy(pc->error, s);
1.1 paf 733: return 1;
734: }
735:
736: static void
1.9 paf 737: yyprint(
1.1 paf 738: FILE *file,
739: int type,
740: YYSTYPE value)
741: {
1.9 paf 742: if(type==STRING)
1.38 paf 743: fprintf(file, " \"%s\"", SLA2S(value)->cstr());
1.1 paf 744: }
745:
E-mail: