--- parser3/src/main/compile.y 2001/03/06 15:02:48 1.55 +++ parser3/src/main/compile.y 2001/03/06 17:03:18 1.58 @@ -1,5 +1,5 @@ /* - $Id: compile.y,v 1.55 2001/03/06 15:02:48 paf Exp $ + $Id: compile.y,v 1.58 2001/03/06 17:03:18 paf Exp $ */ %{ @@ -42,10 +42,38 @@ int yylex(YYSTYPE *lvalp, void *pc); %token STRING %token BOGUS +%token BAD_STRING_COMPARISON_OPERATOR + +%token LOR "||" +%token LAND "&&" + +%token NLE "<=" +%token NGE ">=" +%token NEQ "==" +%token NNE "!=" + +%token SLT "lt" +%token SGT "gt" +%token SLE "le" +%token SGE "ge" +%token SEQ "eq" +%token SNE "ne" + +/* logical */ +%left '<' '>' "<=" ">=" +%left "==" "!=" +%left "||" +%left "&&" +%left NOT /* not: unary ! */ + +/* bitwise */ +%left '&' '|' +%left INV /* invertion: unary ~ */ + +/* numerical */ %left '-' '+' -%left '*' '/' -%left NEG /* negation--unary minus */ -/*%right '^' /* exponentiation */ +%left '*' '/' '%' +%left NEG /* negation: unary - */ %% @@ -222,7 +250,7 @@ name_expr_wdive_class: class_prefix name constructor_value: '[' any_constructor_code_value ']' { $$=$2 } -| '(' any_expression ')' { $$=$2 } +| '(' any_expr ')' { $$=$2 } ; any_constructor_code_value: empty_string_value /* optimized $var[] case */ @@ -349,39 +377,110 @@ with: '$' name_without_curly_rdive '{' c O($$, OP_WRITE); }; -/* expression */ +/* expr */ -any_expression: +any_expr: empty_double_value /* optimized $var() case */ -/*| number /* optimized $var(number) case */ -| expression /* $var(something complex) */ +| expr /* $var(something) */ ; -expression: +expr: number -| expression '+' expression { +| '-' expr %prec NEG { + $$=$2; // stack: operand + O($$, OP_NEG); // value=-operand; stack: value +} +| '~' expr %prec INV { + $$=$2; // stack: operand + O($$, OP_INV); // value=~operand; stack: value +} +| '!' expr %prec NOT { + $$=$2; // stack: operand + O($$, OP_NOT); // value=!operand; stack: value +} +/*todo: def in fexists*/ +| expr '-' expr { $$=$1; // stack: first operand P($$, $3); // stack: first,second operands - O($$, OP_ADD); // value=first*second; stack: value + O($$, OP_SUB); // value=first-second; stack: value } -| expression '-' expression { +| expr '+' expr { $$=$1; // stack: first operand P($$, $3); // stack: first,second operands - O($$, OP_SUB); // value=first*second; stack: value + O($$, OP_ADD); // value=first+second; stack: value } -| expression '*' expression { +| expr '*' expr { $$=$1; // stack: first operand P($$, $3); // stack: first,second operands O($$, OP_MUL); // value=first*second; stack: value } -| expression '/' expression { +| expr '/' expr { $$=$1; // stack: first operand P($$, $3); // stack: first,second operands - O($$, OP_DIV); // value=first*second; stack: value -}; - + O($$, OP_DIV); // value=first/second; stack: value +} +| expr '%' expr { + $$=$1; // stack: first operand + P($$, $3); // stack: first,second operands + O($$, OP_MOD); // value=first%second; stack: value +} +| expr '&' expr { + $$=$1; // stack: first operand + P($$, $3); // stack: first,second operands + O($$, OP_BIN_AND); // value=first&second; stack: value +} +| expr '|' expr { + $$=$1; // stack: first operand + P($$, $3); // stack: first,second operands + O($$, OP_BIN_OR); // value=first|second; stack: value +} +| expr "&&" expr { + $$=$1; // stack: first operand + P($$, $3); // stack: first,second operands + O($$, OP_LOG_AND); // value=first&&second; stack: value +} +| expr "||" expr { + $$=$1; // stack: first operand + P($$, $3); // stack: first,second operands + O($$, OP_LOG_OR); // value=first||second; stack: value +} +| expr '<' expr { + $$=$1; // stack: first operand + P($$, $3); // stack: first,second operands + O($$, OP_NUM_LT); // value=first' expr { + $$=$1; // stack: first operand + P($$, $3); // stack: first,second operands + O($$, OP_NUM_GT); // value=first>second; stack: value +} +| expr "<=" expr { + $$=$1; // stack: first operand + P($$, $3); // stack: first,second operands + O($$, OP_NUM_LE); // value=first<=second; stack: value +} +| expr ">=" expr { + $$=$1; // stack: first operand + P($$, $3); // stack: first,second operands + O($$, OP_NUM_GE); // value=first>=second; stack: value +} +| expr "==" expr { + $$=$1; // stack: first operand + P($$, $3); // stack: first,second operands + O($$, OP_NUM_EQ); // value=first==second; stack: value +} +| expr "!=" expr { + $$=$1; // stack: first operand + P($$, $3); // stack: first,second operands + O($$, OP_NUM_NE); // value=first!=second; stack: value +} +/* + OP_STR_LT, OP_STR_GT, OP_STR_LE, OP_STR_GE, OP_STR_EQ, OP_STR_NE +*/ +| '(' expr ')' { $$ = $2; } +; /* -complex_expression_value: complex_expression { +complex_expr_value: complex_expr { $$=N(POOL); O($$, OP_CREATE_SWPOOL); /* stack: empty write context * / P($$, $1); /* some codes to that context * / @@ -442,6 +541,7 @@ int yylex(YYSTYPE *lvalp, void *pc) { char *begin=PC->source; char *end; int begin_line=PC->line; + bool skip_analized_char=false; while(true) { c=*(end=(PC->source++)); @@ -579,32 +679,53 @@ int yylex(YYSTYPE *lvalp, void *pc) { lexical_brackets_nestage++; RC; case '+': case '-': case '*': case '/': case '%': - case '&': case '|': - case '<': case '>': case '=': case '!': + case '~': case ';': RC; + case '&': case '|': + if(*PC->source==c) { // && || + result='&'?LAND:LOR; + skip_analized_char=true; + } else + result=c; + goto break2; + case '<': case '>': case '=': case '!': + if(*PC->source=='=') { // <= >= == != + skip_analized_char=true; + switch(c) { + case '<': result=NLE; break; + case '>': result=NGE; break; + case '=': result=NEQ; break; + case '!': result=NNE; break; + } + } else + result=c; + goto break2; case '"': push_LS(PC, LS_EXPRESSION_STRING); RC; case 'l': case 'g': case 'e': case 'n': if(end==begin) // right after whitespace - switch(char next_c=*PC->source) { + switch(*PC->source) { // case '?': // ok [and bad cases, yacc would bark at them] case 't': // lt gt [et nt] + result=c=='l'?SLT:c=='g'?SGT:BAD_STRING_COMPARISON_OPERATOR; + goto break2; case 'e': // le ge ne [ee] + result=c=='l'?SLE:c=='g'?SGE:c=='n'?SNE:BAD_STRING_COMPARISON_OPERATOR; + goto break2; case 'q': // eq [lq gq nq] - PC->source++; PC->col++; - PC->pending_state=next_c; - return c; + result=c=='e'?SEQ:BAD_STRING_COMPARISON_OPERATOR; + goto break2; } break; case ' ': case '\t': case '\n': if(end!=begin) { - // append piece till whitespace + // append piece till whitespace char PC->string->APPEND(begin, end-begin, PC->file, begin_line); } // reset piece 'start' position & line - begin=PC->source; // after whitespace + begin=PC->source; // after whitespace char begin_line=PC->line; continue; } @@ -614,7 +735,7 @@ int yylex(YYSTYPE *lvalp, void *pc) { case LS_VAR_NAME_SIMPLE: case LS_VAR_NAME_IN_EXPRESSION: if(PC->ls==LS_VAR_NAME_IN_EXPRESSION) { - // name in expression ends also before binary operators + // name in expr ends also before binary operators switch(c) { case '+': case '-': case '*': case '/': case '%': case '&': case '|': @@ -795,10 +916,7 @@ int yylex(YYSTYPE *lvalp, void *pc) { } break2: - if(begin==end) - return result; - else { - PC->pending_state=result; + if(end!=begin) { // strip last \n before LS_DEF_NAME or EOF if((c=='@' || c==0) && end[-1]=='\n') end--; @@ -810,9 +928,13 @@ break2: *lvalp=VL(NEW VString(*PC->string)); // new pieces storage PC->string=NEW String(POOL); - // go! - return STRING; + // make current result be pending for next call, return STRING for now + PC->pending_state=result; result=STRING; + } + if(skip_analized_char) { + PC->source++; PC->col++; } + return result; } int real_yyerror(parse_control *pc, char *s) /* Called by yyparse on error */