Annotation of parser3/src/main/compile.y, revision 1.16

1.1       paf         1: %{
1.9       paf         2: #define YYSTYPE  Array/*<op>*/ *
                      3: #define YYPARSE_PARAM  pc
                      4: #define YYLEX_PARAM  pc
                      5: #define YYDEBUG  1
1.1       paf         6: #define YYERROR_VERBOSE
1.9       paf         7: #define yyerror(msg)  real_yyerror((parse_control *)pc, msg)
                      8: #define YYPRINT(file, type, value)  yyprint(file, type, value)
1.1       paf         9: 
                     10: #include <stdio.h>
                     11: #include <string.h>
                     12: #include <stdlib.h>
                     13: 
                     14: #include "compile_tools.h"
1.8       paf        15: #include "pa_value.h"
1.12      paf        16: #include "pa_request.h"
1.1       paf        17: 
1.9       paf        18: int real_yyerror(parse_control *pc, char *s);
                     19: static void yyprint(FILE *file, int type, YYSTYPE value);
1.1       paf        20: int yylex(YYSTYPE *lvalp, void *pc);
                     21: 
                     22: 
1.8       paf        23: // local convinient inplace typecast & var
1.9       paf        24: #define PC  ((parse_control *)pc)
                     25: #define pool  *PC->pool
1.1       paf        26: %}
                     27: 
                     28: %pure_parser
                     29: 
1.13      paf        30: %token EON
1.4       paf        31: %token STRING
1.1       paf        32: %token BOGUS
                     33: 
                     34: %%
                     35: 
1.10      paf        36: all:
                     37:        one_big_piece {
1.8       paf        38:        String& name_main=*new(pool) String(pool);
1.11      paf        39:        name_main.APPEND_CONST(MAIN_METHOD_NAME);
1.8       paf        40:        Array& param_names=*new(pool) Array(pool);
                     41:        Array& local_names=*new(pool) Array(pool);
                     42:        Method *method=new(pool) Method(pool, name_main, param_names, local_names, *$1);
                     43:        *PC->methods+=method;
1.10      paf        44: }
                     45: |      methods;
                     46: 
                     47: methods: method | methods method;
                     48: one_big_piece: maybe_codes;
                     49: 
                     50: method: '@' STRING bracketed_maybe_strings maybe_bracketed_strings maybe_comment '\n' 
                     51:                        maybe_codes {
                     52:        const String *name=LA2S($2);
                     53: 
                     54:        YYSTYPE params_names_code=$3;
                     55:        Array& params_names=*new(pool) Array(pool);
                     56:        for(int i=0; i<params_names_code->size(); i+=2)
                     57:                params_names+=LA2S(params_names_code, i);
                     58: 
                     59:        YYSTYPE locals_names_code=$4;
                     60:        Array& locals_names=*new(pool) Array(pool);
                     61:        for(int i=0; i<locals_names_code->size(); i+=2)
                     62:                locals_names+=LA2S(locals_names_code, i);
                     63: 
                     64:        Method *method=new(pool) Method(pool, *name, params_names, locals_names, *$7);
                     65:        *PC->methods+=method;
1.8       paf        66: };
1.10      paf        67: 
                     68: maybe_bracketed_strings: empty | bracketed_maybe_strings;
                     69: bracketed_maybe_strings: '[' maybe_strings ']' {$$=$2};
                     70: maybe_strings: empty | strings;
                     71: strings: STRING | strings ';' STRING { $$=$1; P($$, $3) };
                     72: 
                     73: maybe_comment: empty | STRING;
1.1       paf        74: 
                     75: /* codes */
                     76: 
1.10      paf        77: maybe_codes: empty | codes;
                     78: 
1.1       paf        79: codes: code | codes code { 
                     80:        $$=$1; 
1.9       paf        81:        P($$, $2);
1.1       paf        82: };
                     83: code: write_str_literal | action;
                     84: action: get | put | with | call;
                     85: 
                     86: /* get */
                     87: 
                     88: get: '$' any_name {
                     89:        $$=$2; /* stack: resulting value */
1.14      paf        90:        OP($$, OP_WRITE_VALUE); /* value=pop; write(value) */
1.1       paf        91: };
                     92: 
1.13      paf        93: any_name: name_without_curly_rdive EON | name_in_curly_rdive;
1.1       paf        94: 
                     95: name_in_curly_rdive: '{' name_without_curly_rdive '}' { $$=$2 };
                     96: name_without_curly_rdive: name_rdive {
                     97:        /* 
                     98:        TODO: подсмотреть в $1, и если там в первом элементе первая буква ":"
                     99:                то выкинуть её и делать не OP_WITH_READ, а WITH_ROOT
                    100:        TODO: подсмотреть в $1, и если там первым элементом self,
                    101:                то выкинуть его и делать не OP_WITH_READ, а WITH_SELF
                    102:        */ 
1.8       paf       103:        $$=N(pool); OP($$, OP_WITH_READ); /* stack: starting context */
1.9       paf       104:        P($$, $1); /* diving code; stack: current context */
1.1       paf       105: };
1.10      paf       106: name_rdive: name_advance2 | name_path name_advance2 { $$=$1; P($$, $2) };
1.1       paf       107: 
                    108: /* put */
                    109: 
                    110: put: '$' name_expr_dive '(' constructor_value ')' {
                    111: /*
                    112:        TODO: подсмотреть в $3, и если там в первом элементе первая буква ":"
                    113:                то выкинуть её и делать не OP_WITH_OP_WRITE, а WITH_ROOT
                    114:        TODO: подсмотреть в $3, и если там первым элементом self,
                    115:                то выкинуть его и делать не OP_WITH_OP_WRITE, а WITH_SELF
                    116:                если ничего не осталось - $self(xxx)
                    117:                        обругать
                    118: */
1.8       paf       119:        $$=N(pool); 
1.3       paf       120:        OP($$, OP_WITH_WRITE); /* stack: starting context */
1.9       paf       121:        P($$, $2); /* diving code; stack: context,name */
                    122:        P($$, $4); /* stack: context,name,constructor_value */
                    123:        OP($$, OP_CONSTRUCT); /* value=pop; name=pop; context=pop; construct(context,name,value) */
1.1       paf       124: };
                    125: constructor_value: 
                    126:        constructor_one_param_value
                    127: |      constructor_two_params_value /* $var(=;2*2) $var(%d;2*2) $var(+;1) */
                    128: ;
                    129: constructor_one_param_value: 
1.15      paf       130:        empty /* optimized $var() case */
                    131: |      string_value /* optimized $var(STRING) case */
1.1       paf       132: |      complex_constructor_param_value /* $var(something complex) */
                    133: ;
1.15      paf       134: string_value: STRING {
                    135:        $$=LAS2LAVS($1);
                    136: };
1.1       paf       137: complex_constructor_param_value: complex_constructor_param_body {
1.8       paf       138:        $$=N(pool); 
1.3       paf       139:        OP($$, OP_CREATE_EWPOOL); /* stack: empty write context */
1.9       paf       140:        P($$, $1); /* some codes to that context */
                    141:        OP($$, OP_REDUCE_EWPOOL); /* context=pop; stack: context.value() */
1.1       paf       142: };
                    143: complex_constructor_param_body:
                    144:        codes__excluding_sole_str_literal
                    145: |      codes__str__followed_by__excluding_sole_str_literal
                    146: ;
1.4       paf       147: constructor_two_params_value: STRING ';' constructor_one_param_value {
1.7       paf       148:        char *operator_or_fmt=LA2S($1)->cstr();
1.8       paf       149:        $$=N(pool);
1.9       paf       150:        P($$, $1); /* stack: ncontext name operator_or_fmt */
1.3       paf       151:        P($$, $3); /* stack: ncontext name operator_or_fmt expr */
1.1       paf       152:        switch(operator_or_fmt[0]) {
                    153:        case '=': case '%':
1.3       paf       154:                OP($$, OP_EXPRESSION_EVAL);
1.1       paf       155:                break;
                    156:        case '+': case '-': case '*': case '/':
1.3       paf       157:                OP($$, OP_MODIFY_EVAL);
1.1       paf       158:                break;
                    159:        default:
1.6       paf       160:                strcpy(PC->error, "invalid modification operator");
                    161:                YYERROR;
1.1       paf       162:        }
                    163:        /* stack: ncontext name value */
                    164: };
                    165: 
                    166: 
                    167: /* call */
                    168: 
1.13      paf       169: call: '^' name_expr_dive store_params EON { /* ^field.$method{vasya} */
1.1       paf       170: /*
                    171:        TODO: подсмотреть в $3, и если там в первом элементе первая буква ":"
                    172:                то выкинуть её и делать не OP_WITH_READ, а WITH_ROOT
                    173:        TODO: подсмотреть в $3, и если там первым элементом self,
                    174:                то выкинуть его и делать не OP_WITH_READ, а WITH_SELF
                    175:        TODO:
                    176:                если первым в $3 идёт result
                    177:                то
                    178:                        выкинуть его
                    179:                        если там ещё что-то осталось,
                    180:                        то
                    181:                                не OP_WITH_READ, а WITH_RESULT
                    182:                        иначе  // ^result(value)
                    183:                                обругать безобразие
                    184: */
1.8       paf       185:        $$=N(pool); 
1.3       paf       186:        OP($$, OP_WITH_READ); /* stack: starting context */
1.9       paf       187:        P($$, $2); /* diving code; stack: context,method_name */
                    188:        OP($$, OP_GET_METHOD_FRAME); /* stack: context,method_frame */
                    189:        P($$, $3); /* filling method_frame.store_params */
                    190:        OP($$, OP_CALL); /* method_frame=pop; ncontext=pop; call(ncontext,method_frame) */
1.1       paf       191: };
                    192: 
1.9       paf       193: store_params: store_param | store_params store_param { $$=$1; P($$, $2) };
1.1       paf       194: store_param: store_round_param | store_curly_param;
                    195: store_round_param: '(' store_param_parts ')' {$$=$2};
1.9       paf       196: store_param_parts: store_param_part | store_param_parts ';' store_param_part { $$=$1; P($$, $3) };
1.1       paf       197: store_param_part: constructor_one_param_value {
                    198:        $$=$1;
1.9       paf       199:        OP($$, OP_STORE_PARAM);
1.1       paf       200: }
1.10      paf       201: store_curly_param: '{' maybe_codes '}' {
1.8       paf       202:        $$=N(pool); 
1.3       paf       203:        OP($$, OP_CODE_ARRAY);
1.9       paf       204:        AA($$, $2);
                    205:        OP($$, OP_CREATE_JUNCTION);
                    206:        OP($$, OP_STORE_PARAM);
1.1       paf       207: };
                    208: 
                    209: /* name */
                    210: 
1.9       paf       211: name_expr_dive: name_expr_value | name_path name_expr_value { $$=$1; P($$, $2) };
1.1       paf       212: 
1.9       paf       213: name_path: name_step | name_path name_step { $$=$1; P($$, $2) };
1.1       paf       214: name_step: name_advance1 '.';
                    215: name_advance1: name_expr_value {
                    216:        /* stack: context */
                    217:        $$=$1; /* stack: context,name */
1.9       paf       218:        OP($$, OP_GET_ELEMENT); /* name=pop; context=pop; stack: context.get_element(name) */
1.1       paf       219: };
                    220: name_advance2: name_expr_value {
                    221:        /* stack: context */
                    222:        $$=$1; /* stack: context,name */
1.9       paf       223:        OP($$, OP_GET_ELEMENT); /* name=pop; context=pop; stack: context.get_element(name) */
1.1       paf       224: }
1.4       paf       225: |      STRING BOGUS
1.1       paf       226: ;
                    227: name_expr_value: 
1.4       paf       228:        STRING /* subname_is_const */
1.1       paf       229: |      name_expr_subvar_value /* $subname_is_var_value */
                    230: |      name_expr_with_subvar_value /* xxx$part_of_subname_is_var_value[$...] */
                    231: ;
                    232: name_expr_subvar_value: '$' subvar_ref_name_rdive {
                    233:        $$=$2;
1.9       paf       234:        OP($$, OP_GET_ELEMENT);
1.1       paf       235: };
1.4       paf       236: name_expr_with_subvar_value: STRING subvar_get_writes {
1.8       paf       237:        $$=N(pool); 
1.3       paf       238:        OP($$, OP_CREATE_EWPOOL);
1.9       paf       239:        P($$, $1);
1.14      paf       240:        OP($$, OP_WRITE_STRING);
1.9       paf       241:        P($$, $2);
                    242:        OP($$, OP_REDUCE_EWPOOL);
1.1       paf       243: };
1.4       paf       244: subvar_ref_name_rdive: STRING {
1.1       paf       245: /*
                    246:        TODO: подсмотреть в $1, и если там в первом элементе первая буква ":"
                    247:                то выкинуть её и делать не OP_WITH_READ, а WITH_ROOT
                    248: */
1.8       paf       249:        $$=N(pool); OP($$, OP_WITH_READ);
1.9       paf       250:        P($$, $1);
1.1       paf       251: };
1.9       paf       252: subvar_get_writes: subvar__get_write | subvar_get_writes subvar__get_write { $$=$1; P($$, $2) };
1.1       paf       253: subvar__get_write: '$' subvar_ref_name_rdive {
                    254:        $$=$2;
1.14      paf       255:        OP($$, OP_GET_ELEMENT__WRITE_VALUE);
1.1       paf       256: };
                    257: 
                    258: 
                    259: /* with */
                    260: 
                    261: with: '$' name_without_curly_rdive '{' codes '}' {
                    262:        $$=$2;
1.9       paf       263:        OP($$, OP_CREATE_RWPOOL);
                    264:        P($$, $4);
                    265:        OP($$, OP_REDUCE_RWPOOL);
1.14      paf       266:        OP($$, OP_WRITE_VALUE);
1.1       paf       267: };
                    268: 
                    269: /* codes_in_brackets */
                    270: 
                    271: codes__str__followed_by__excluding_sole_str_literal:
                    272:        write_str_literal codes__excluding_sole_str_literal {
                    273:                $$=$1;
1.9       paf       274:                P($$, $2);
1.1       paf       275: }
                    276: ;
                    277: codes__excluding_sole_str_literal:
                    278:        action
                    279: |      codes__excluding_sole_str_literal write_str_literal {
                    280:                $$=$1;
1.9       paf       281:                P($$, $2);
1.1       paf       282: }
                    283: ;
1.4       paf       284: write_str_literal: STRING {
1.1       paf       285:        $$=$1;
1.14      paf       286:        OP($$, OP_WRITE_STRING);
1.1       paf       287: };
                    288: 
                    289: /* */
                    290: 
1.8       paf       291: empty: /* empty */ { $$=N(pool) };
1.1       paf       292: 
                    293: %%
                    294: 
                    295: /*
                    296:        000$111(2222)00 
                    297:                000$111{3333}00
1.9       paf       298:        $,^: push,=0
1.1       paf       299:        1:( { break=pop
                    300:        2:( )  pop
                    301:        3:{ }  pop
                    302: 
                    303:        000^111(2222)4444{33333}4000
1.9       paf       304:        $,^: push,=0
1.1       paf       305:        1:( { break=pop
                    306:        2:( )=4
                    307:        3:{ }=4
                    308:                4:[^({]=pop
                    309: */
                    310: 
                    311: int yylex(YYSTYPE *lvalp, void *pc) {
                    312:        #define lexical_brackets_nestage PC->brackets_nestages[PC->sp]
                    313: 
                    314:     register int c;
                    315:     int result;
                    316:        
                    317:        if(PC->pending_state) {
                    318:                result=PC->pending_state;
                    319:                PC->pending_state=0;
                    320:                return result;
                    321:        }
                    322:        
1.9       paf       323:        char *begin=PC->source;
                    324:        char *end;
                    325:        int begin_line=PC->line;
1.1       paf       326:        while(1) {
1.9       paf       327:                c=*(end=(PC->source++));
1.1       paf       328: 
1.4       paf       329:                if(c=='\n') {
1.1       paf       330:                        PC->line++;
1.8       paf       331:                        PC->col=0;
1.10      paf       332:                } else
1.4       paf       333:                        PC->col++;
1.1       paf       334: 
                    335:                /* escaping: ^^ ^$ ^; ^) ^} ^( ^{ */
                    336:                if(c=='^') {
                    337:                        char pending_c=*PC->source;
                    338: 
1.9       paf       339:                        if(pending_c=='^' || pending_c=='$' || pending_c==';' ||
                    340:                                pending_c=='(' || pending_c==')' ||
                    341:                                pending_c=='{' || pending_c=='}') {
1.1       paf       342:                                /* append piece till ^ */
1.9       paf       343:                                PC->string->APPEND(begin, end-begin, PC->file, begin_line);
1.1       paf       344:                                /* reset piece 'start' position & line */
1.9       paf       345:                                begin=PC->source/*^*/;
                    346:                                begin_line=PC->line;
1.1       paf       347:                                /* skip over ^ and _ */
                    348:                                PC->source+=2;
                    349:                                /* skip analysis = forced literal */
                    350:                                continue;
                    351:                        }
                    352:                }
                    353:                switch(PC->ls) {
1.10      paf       354: 
                    355:                // USER'S = NOT OURS
1.1       paf       356:                case LS_USER:
                    357:                        if(c=='$') {
1.10      paf       358:                                push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1       paf       359:                                result=c;
                    360:                                goto break2;
                    361:                        }
                    362:                        if(c=='^') {
1.10      paf       363:                                push_LS(PC, LS_METHOD_NAME);
                    364:                                result=c;
                    365:                                goto break2;
                    366:                        }
                    367:                        if(c=='@' && PC->col==0+1) {
1.1       paf       368:                                result=c;
1.10      paf       369:                                push_LS(PC, LS_DEF_NAME);
                    370:                                goto break2;
                    371:                        }
                    372:                        
                    373:                        break;
                    374: 
                    375:                // METHOD DEFINITION
                    376:                case LS_DEF_NAME:
                    377:                        if(c=='[') {
                    378:                                result=c;
                    379:                                PC->ls=LS_DEF_PARAMS;
                    380:                                goto break2;
                    381:                        }
                    382:                        if(c=='\n') { // wrong. bailing out
                    383:                                result=c;
                    384:                                pop_LS(PC);
                    385:                                goto break2;
                    386:                        }
                    387:                        break;
                    388:                case LS_DEF_PARAMS:
                    389:                        if(c==';') {
                    390:                                result=c;
                    391:                                goto break2;
                    392:                        }
                    393:                        if(c==']') {
                    394:                                result=c;
                    395:                                PC->ls=*PC->source=='['?LS_DEF_LOCALS:LS_DEF_COMMENT;
                    396:                                goto break2;
                    397:                        }
                    398:                        if(c=='\n') { // wrong. bailing out
                    399:                                result=c;
                    400:                                pop_LS(PC);
                    401:                                goto break2;
                    402:                        }
                    403:                        break;
                    404:                case LS_DEF_LOCALS:
                    405:                        if(c=='[' || c==';') {
                    406:                                result=c;
                    407:                                goto break2;
                    408:                        }
                    409:                        if(c==']') {
                    410:                                result=c;
                    411:                                PC->ls=LS_DEF_COMMENT;
                    412:                                goto break2;
                    413:                        }
                    414:                        if(c=='\n') { // wrong. bailing out
                    415:                                result=c;
                    416:                                pop_LS(PC);
                    417:                                goto break2;
                    418:                        }
                    419:                        break;
                    420:                case LS_DEF_COMMENT:
                    421:                        if(c=='\n') {
                    422:                                result=c;
                    423:                                pop_LS(PC);
1.1       paf       424:                                goto break2;
                    425:                        }
                    426:                        break;
                    427: 
1.10      paf       428:                // VARIABLE GET/PUT/WITH
1.1       paf       429:                case LS_VAR_NAME_SIMPLE:
                    430:                        if(c==0 || 
                    431:                                c==' '|| c=='\t' || c=='\n' || 
                    432:                                c==')' || c=='}') {
                    433:                                pop_LS(PC);
1.4       paf       434:                                PC->source--;   PC->col--;
1.13      paf       435:                                result=EON;
1.1       paf       436:                                goto break2;
                    437:                        }
1.13      paf       438:                        if(begin==end && c=='{') { /* ${name}, no need of EON, switching LS */
1.1       paf       439:                                PC->ls=LS_VAR_NAME_CURLY; 
                    440:                                result=c;
                    441:                                goto break2;
                    442:                        }
                    443:                        if(c=='(') {
                    444:                                PC->ls=LS_VAR_ROUND;
                    445:                                lexical_brackets_nestage=1;
                    446:                                result=c;
                    447:                                goto break2;
                    448:                        }
                    449:                        if(c=='{') {
                    450:                                PC->ls=LS_VAR_CURLY;
                    451:                                lexical_brackets_nestage=1;
                    452:                                result=c;
                    453:                                goto break2;
                    454:                        }
                    455:                        if(c=='.'/* name part delim */ || c=='$'/* name part subvar */) {
                    456:                                result=c;
                    457:                                goto break2;
                    458:                        }
                    459:                        break;
                    460:                case LS_VAR_NAME_CURLY:
                    461:                        if(c=='}') {  /* ${name} finished, restoring LS */
                    462:                                pop_LS(PC);
                    463:                                result=c;
                    464:                                goto break2;
                    465:                        }
                    466:                        if(c=='.'/* name part delim */ || c=='$'/*name part subvar*/) {
                    467:                                result=c;
                    468:                                goto break2;
                    469:                        }
                    470:                        break;
                    471:                case LS_VAR_ROUND:
                    472:                        if(c=='$') {
1.10      paf       473:                                push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1       paf       474:                                result=c;
                    475:                                goto break2;
                    476:                        }
                    477:                        if(c=='^') {
1.10      paf       478:                                push_LS(PC, LS_METHOD_NAME);
1.1       paf       479:                                result=c;
                    480:                                goto break2;
                    481:                        }
                    482:                        if(c==')') {
                    483:                                if(--lexical_brackets_nestage==0) {
                    484:                                        pop_LS(PC);
                    485:                                        result=c;
                    486:                                        goto break2;
                    487:                                }
                    488:                        }
                    489:                        if(c==';'/* operator_or_fmt;value delim */) {
                    490:                                result=c;
                    491:                                goto break2;
                    492:                        }
                    493:                        if(c=='(')
                    494:                                lexical_brackets_nestage++;
                    495:                        break;
                    496:                case LS_VAR_CURLY:
                    497:                        if(c=='$') {
1.10      paf       498:                                push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1       paf       499:                                result=c;
                    500:                                goto break2;
                    501:                        }
                    502:                        if(c=='^') {
1.10      paf       503:                                push_LS(PC, LS_METHOD_NAME);
1.1       paf       504:                                result=c;
                    505:                                goto break2;
                    506:                        }
                    507:                        if(c=='}')
                    508:                                if(--lexical_brackets_nestage==0) {
                    509:                                        pop_LS(PC);
                    510:                                        result=c;
                    511:                                        goto break2;
                    512:                                }
                    513:                        if(c=='{')
                    514:                                lexical_brackets_nestage++;
                    515:                        break;
                    516: 
1.10      paf       517:                // METHOD CALL
1.1       paf       518:                case LS_METHOD_NAME:
                    519:                        if(c=='(') {
                    520:                                PC->ls=LS_METHOD_ROUND;
                    521:                                lexical_brackets_nestage=1;
                    522:                                result=c;
                    523:                                goto break2;
                    524:                        }
                    525:                        if(c=='{') {
                    526:                                PC->ls=LS_METHOD_CURLY;
                    527:                                lexical_brackets_nestage=1;
                    528:                                result=c;
                    529:                                goto break2;
                    530:                        }
                    531:                        if(c=='.'/* name part delim */ || c=='$'/* name part subvar */) {
                    532:                                result=c;
                    533:                                goto break2;
                    534:                        }
                    535:                        break;
                    536:                case LS_METHOD_ROUND:
                    537:                        if(c=='$') {
1.10      paf       538:                                push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1       paf       539:                                result=c;
                    540:                                goto break2;
                    541:                        }
                    542:                        if(c=='^') {
1.10      paf       543:                                push_LS(PC, LS_METHOD_NAME);
1.1       paf       544:                                result=c;
                    545:                                goto break2;
                    546:                        }
                    547:                        if(c==';'/* param delim */) {
                    548:                                result=c;
                    549:                                goto break2;
                    550:                        }
                    551:                        if(c==')')
                    552:                                if(--lexical_brackets_nestage==0) {
                    553:                                        PC->ls=LS_METHOD_AFTER;
                    554:                                        result=c;
                    555:                                        goto break2;
                    556:                                }
                    557:                        if(c=='(')
                    558:                                lexical_brackets_nestage++;
                    559:                        break;
                    560:                case LS_METHOD_CURLY:
                    561:                        if(c=='$') {
1.10      paf       562:                                push_LS(PC, LS_VAR_NAME_SIMPLE);
1.1       paf       563:                                result=c;
                    564:                                goto break2;
                    565:                        }
                    566:                        if(c=='^') {
1.10      paf       567:                                push_LS(PC, LS_METHOD_NAME);
1.1       paf       568:                                result=c;
                    569:                                goto break2;
                    570:                        }
                    571:                        if(c=='}')
                    572:                                if(--lexical_brackets_nestage==0) {
                    573:                                        PC->ls=LS_METHOD_AFTER;
                    574:                                        result=c;
                    575:                                        goto break2;
                    576:                                }
                    577:                        if(c=='{')
                    578:                                lexical_brackets_nestage++;
                    579:                        break;
                    580:                case LS_METHOD_AFTER:
                    581:                        if(c=='(') {/* )( }( */
                    582:                                PC->ls=LS_METHOD_ROUND;
                    583:                                lexical_brackets_nestage=1;
                    584:                                result=c;
                    585:                                goto break2;
                    586:                        }                                          
                    587:                        if(c=='{') {/* ){ }{ */
                    588:                                PC->ls=LS_METHOD_CURLY;
                    589:                                lexical_brackets_nestage=1;
                    590:                                result=c;
                    591:                                goto break2;
                    592:                        }                                          
                    593:                        pop_LS(PC);
1.4       paf       594:                        PC->source--;  PC->col--;
1.13      paf       595:                        result=EON;
1.1       paf       596:                        goto break2;
                    597:                }
1.9       paf       598:                if(c==0) {
1.1       paf       599:                        result=-1;
1.4       paf       600:                        PC->source--;  PC->col--;
1.1       paf       601:                        break;
                    602:                }
                    603:        }
                    604: 
                    605: break2:
1.9       paf       606:        if(begin==end)
1.1       paf       607:                return result;
                    608:        else {
                    609:                PC->pending_state=result;
1.10      paf       610:                // strip last \n before LS_DEF_NAME or EOF
                    611:                if((c=='@' || c==0) && end[-1]=='\n')
                    612:                        end--;
                    613:                // append last piece
1.9       paf       614:                PC->string->APPEND(begin, end-begin, PC->file, begin_line/*, start_col*/);
1.10      paf       615:                // create STRING value: array of OP_STRING+string
1.1       paf       616:                *lvalp=L(PC->string);
1.10      paf       617:                // new pieces storage
1.8       paf       618:                PC->string=new(pool) String(pool);
1.10      paf       619:                // go!
1.4       paf       620:                return STRING;
1.1       paf       621:        }
                    622: }
                    623: 
1.9       paf       624: int real_yyerror(parse_control *pc, char *s)  /* Called by yyparse on error */
1.1       paf       625:      {
1.16    ! paf       626:        //fprintf(stderr, "[%s]\n", s);
1.6       paf       627: 
                    628:           s[MAX_STRING-1]=0; strcpy(pc->error, s);
1.1       paf       629:           return 1;
                    630:      }
                    631: 
                    632: static void
1.9       paf       633:      yyprint(
1.1       paf       634:           FILE *file,
                    635:           int type,
                    636:           YYSTYPE value)
                    637:      {
1.9       paf       638:        if(type==STRING)
                    639:          fprintf(file, " \"%s\"", LA2S(value)->cstr());
1.1       paf       640:      }
                    641: 

E-mail: