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