17c478bd9Sstevel@tonic-gate %{ 27c478bd9Sstevel@tonic-gate /* 37c478bd9Sstevel@tonic-gate * CDDL HEADER START 47c478bd9Sstevel@tonic-gate * 57c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 67c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 77c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 87c478bd9Sstevel@tonic-gate * with the License. 97c478bd9Sstevel@tonic-gate * 107c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 117c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 127c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 137c478bd9Sstevel@tonic-gate * and limitations under the License. 147c478bd9Sstevel@tonic-gate * 157c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 167c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 177c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 187c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 197c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 207c478bd9Sstevel@tonic-gate * 217c478bd9Sstevel@tonic-gate * CDDL HEADER END 227c478bd9Sstevel@tonic-gate */ 237c478bd9Sstevel@tonic-gate %} 24*1ee2e5faSnakanon /* 25*1ee2e5faSnakanon * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 26*1ee2e5faSnakanon * Use is subject to license terms. 27*1ee2e5faSnakanon */ 28*1ee2e5faSnakanon 297c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 307c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate %{ 337c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.10 */ 347c478bd9Sstevel@tonic-gate %} 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate %{ 377c478bd9Sstevel@tonic-gate #include "awk.h" 38*1ee2e5faSnakanon int yywrap(void) { return(1); } 397c478bd9Sstevel@tonic-gate #ifndef DEBUG 407c478bd9Sstevel@tonic-gate # define PUTS(x) 417c478bd9Sstevel@tonic-gate #endif 427c478bd9Sstevel@tonic-gate Node *beginloc = 0, *endloc = 0; 437c478bd9Sstevel@tonic-gate int infunc = 0; /* = 1 if in arglist or body of func */ 447c478bd9Sstevel@tonic-gate uchar *curfname = 0; 457c478bd9Sstevel@tonic-gate Node *arglist = 0; /* list of args for current function */ 46*1ee2e5faSnakanon static void setfname(Cell *); 47*1ee2e5faSnakanon static int constnode(Node *); 48*1ee2e5faSnakanon static uchar *strnode(Node *); 49*1ee2e5faSnakanon static Node *notnull(); 507c478bd9Sstevel@tonic-gate %} 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate %union { 537c478bd9Sstevel@tonic-gate Node *p; 547c478bd9Sstevel@tonic-gate Cell *cp; 557c478bd9Sstevel@tonic-gate int i; 567c478bd9Sstevel@tonic-gate uchar *s; 577c478bd9Sstevel@tonic-gate } 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate %token <i> FIRSTTOKEN /* must be first */ 607c478bd9Sstevel@tonic-gate %token <p> PROGRAM PASTAT PASTAT2 XBEGIN XEND 617c478bd9Sstevel@tonic-gate %token <i> NL ',' '{' '(' '|' ';' '/' ')' '}' '[' ']' 627c478bd9Sstevel@tonic-gate %token <i> ARRAY 637c478bd9Sstevel@tonic-gate %token <i> MATCH NOTMATCH MATCHOP 647c478bd9Sstevel@tonic-gate %token <i> FINAL DOT ALL CCL NCCL CHAR OR STAR QUEST PLUS 657c478bd9Sstevel@tonic-gate %token <i> AND BOR APPEND EQ GE GT LE LT NE IN 667c478bd9Sstevel@tonic-gate %token <i> ARG BLTIN BREAK CLOSE CONTINUE DELETE DO EXIT FOR FUNC 677c478bd9Sstevel@tonic-gate %token <i> SUB GSUB IF INDEX LSUBSTR MATCHFCN NEXT 687c478bd9Sstevel@tonic-gate %token <i> ADD MINUS MULT DIVIDE MOD 697c478bd9Sstevel@tonic-gate %token <i> ASSIGN ASGNOP ADDEQ SUBEQ MULTEQ DIVEQ MODEQ POWEQ 707c478bd9Sstevel@tonic-gate %token <i> PRINT PRINTF SPRINTF 717c478bd9Sstevel@tonic-gate %token <p> ELSE INTEST CONDEXPR 727c478bd9Sstevel@tonic-gate %token <i> POSTINCR PREINCR POSTDECR PREDECR 737c478bd9Sstevel@tonic-gate %token <cp> VAR IVAR VARNF CALL NUMBER STRING FIELD 747c478bd9Sstevel@tonic-gate %token <s> REGEXPR 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate %type <p> pas pattern ppattern plist pplist patlist prarg term 777c478bd9Sstevel@tonic-gate %type <p> pa_pat pa_stat pa_stats 787c478bd9Sstevel@tonic-gate %type <s> reg_expr 797c478bd9Sstevel@tonic-gate %type <p> simple_stmt opt_simple_stmt stmt stmtlist 807c478bd9Sstevel@tonic-gate %type <p> var varname funcname varlist 817c478bd9Sstevel@tonic-gate %type <p> for if while 827c478bd9Sstevel@tonic-gate %type <i> pst opt_pst lbrace rparen comma nl opt_nl and bor 837c478bd9Sstevel@tonic-gate %type <i> subop print 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate %right ASGNOP 867c478bd9Sstevel@tonic-gate %right '?' 877c478bd9Sstevel@tonic-gate %right ':' 887c478bd9Sstevel@tonic-gate %left BOR 897c478bd9Sstevel@tonic-gate %left AND 907c478bd9Sstevel@tonic-gate %left GETLINE 917c478bd9Sstevel@tonic-gate %nonassoc APPEND EQ GE GT LE LT NE MATCHOP IN '|' 927c478bd9Sstevel@tonic-gate %left ARG BLTIN BREAK CALL CLOSE CONTINUE DELETE DO EXIT FOR FIELD FUNC 937c478bd9Sstevel@tonic-gate %left GSUB IF INDEX LSUBSTR MATCHFCN NEXT NUMBER 947c478bd9Sstevel@tonic-gate %left PRINT PRINTF RETURN SPLIT SPRINTF STRING SUB SUBSTR 957c478bd9Sstevel@tonic-gate %left REGEXPR VAR VARNF IVAR WHILE '(' 967c478bd9Sstevel@tonic-gate %left CAT 977c478bd9Sstevel@tonic-gate %left '+' '-' 987c478bd9Sstevel@tonic-gate %left '*' '/' '%' 997c478bd9Sstevel@tonic-gate %left NOT UMINUS 1007c478bd9Sstevel@tonic-gate %right POWER 1017c478bd9Sstevel@tonic-gate %right DECR INCR 1027c478bd9Sstevel@tonic-gate %left INDIRECT 1037c478bd9Sstevel@tonic-gate %token LASTTOKEN /* must be last */ 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate %% 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate program: 1087c478bd9Sstevel@tonic-gate pas { if (errorflag==0) 1097c478bd9Sstevel@tonic-gate winner = (Node *)stat3(PROGRAM, beginloc, $1, endloc); } 1107c478bd9Sstevel@tonic-gate | error { yyclearin; bracecheck(); ERROR "bailing out" SYNTAX; } 1117c478bd9Sstevel@tonic-gate ; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate and: 1147c478bd9Sstevel@tonic-gate AND | and NL 1157c478bd9Sstevel@tonic-gate ; 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate bor: 1187c478bd9Sstevel@tonic-gate BOR | bor NL 1197c478bd9Sstevel@tonic-gate ; 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate comma: 1227c478bd9Sstevel@tonic-gate ',' | comma NL 1237c478bd9Sstevel@tonic-gate ; 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate do: 1267c478bd9Sstevel@tonic-gate DO | do NL 1277c478bd9Sstevel@tonic-gate ; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate else: 1307c478bd9Sstevel@tonic-gate ELSE | else NL 1317c478bd9Sstevel@tonic-gate ; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate for: 1347c478bd9Sstevel@tonic-gate FOR '(' opt_simple_stmt ';' pattern ';' opt_simple_stmt rparen stmt 1357c478bd9Sstevel@tonic-gate { $$ = stat4(FOR, $3, notnull($5), $7, $9); } 1367c478bd9Sstevel@tonic-gate | FOR '(' opt_simple_stmt ';' ';' opt_simple_stmt rparen stmt 1377c478bd9Sstevel@tonic-gate { $$ = stat4(FOR, $3, NIL, $6, $8); } 1387c478bd9Sstevel@tonic-gate | FOR '(' varname IN varname rparen stmt 1397c478bd9Sstevel@tonic-gate { $$ = stat3(IN, $3, makearr($5), $7); } 1407c478bd9Sstevel@tonic-gate ; 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate funcname: 1437c478bd9Sstevel@tonic-gate VAR { setfname($1); } 1447c478bd9Sstevel@tonic-gate | CALL { setfname($1); } 1457c478bd9Sstevel@tonic-gate ; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate if: 1487c478bd9Sstevel@tonic-gate IF '(' pattern rparen { $$ = notnull($3); } 1497c478bd9Sstevel@tonic-gate ; 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate lbrace: 1527c478bd9Sstevel@tonic-gate '{' | lbrace NL 1537c478bd9Sstevel@tonic-gate ; 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate nl: 1567c478bd9Sstevel@tonic-gate NL | nl NL 1577c478bd9Sstevel@tonic-gate ; 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate opt_nl: 1607c478bd9Sstevel@tonic-gate /* empty */ { $$ = 0; } 1617c478bd9Sstevel@tonic-gate | nl 1627c478bd9Sstevel@tonic-gate ; 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate opt_pst: 1657c478bd9Sstevel@tonic-gate /* empty */ { $$ = 0; } 1667c478bd9Sstevel@tonic-gate | pst 1677c478bd9Sstevel@tonic-gate ; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate opt_simple_stmt: 1717c478bd9Sstevel@tonic-gate /* empty */ { $$ = 0; } 1727c478bd9Sstevel@tonic-gate | simple_stmt 1737c478bd9Sstevel@tonic-gate ; 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate pas: 1767c478bd9Sstevel@tonic-gate opt_pst { $$ = 0; } 1777c478bd9Sstevel@tonic-gate | opt_pst pa_stats opt_pst { $$ = $2; } 1787c478bd9Sstevel@tonic-gate ; 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate pa_pat: 1817c478bd9Sstevel@tonic-gate pattern { $$ = notnull($1); } 1827c478bd9Sstevel@tonic-gate ; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate pa_stat: 1857c478bd9Sstevel@tonic-gate pa_pat { $$ = stat2(PASTAT, $1, stat2(PRINT, rectonode(), NIL)); } 1867c478bd9Sstevel@tonic-gate | pa_pat lbrace stmtlist '}' { $$ = stat2(PASTAT, $1, $3); } 1877c478bd9Sstevel@tonic-gate | pa_pat ',' pa_pat { $$ = pa2stat($1, $3, stat2(PRINT, rectonode(), NIL)); } 1887c478bd9Sstevel@tonic-gate | pa_pat ',' pa_pat lbrace stmtlist '}' { $$ = pa2stat($1, $3, $5); } 1897c478bd9Sstevel@tonic-gate | lbrace stmtlist '}' { $$ = stat2(PASTAT, NIL, $2); } 1907c478bd9Sstevel@tonic-gate | XBEGIN lbrace stmtlist '}' 1917c478bd9Sstevel@tonic-gate { beginloc = linkum(beginloc, $3); $$ = 0; } 1927c478bd9Sstevel@tonic-gate | XEND lbrace stmtlist '}' 1937c478bd9Sstevel@tonic-gate { endloc = linkum(endloc, $3); $$ = 0; } 1947c478bd9Sstevel@tonic-gate | FUNC funcname '(' varlist rparen {infunc++;} lbrace stmtlist '}' 1957c478bd9Sstevel@tonic-gate { infunc--; curfname=0; defn((Cell *)$2, $4, $8); $$ = 0; } 1967c478bd9Sstevel@tonic-gate ; 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate pa_stats: 1997c478bd9Sstevel@tonic-gate pa_stat 2007c478bd9Sstevel@tonic-gate | pa_stats opt_pst pa_stat { $$ = linkum($1, $3); } 2017c478bd9Sstevel@tonic-gate ; 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate patlist: 2047c478bd9Sstevel@tonic-gate pattern 2057c478bd9Sstevel@tonic-gate | patlist comma pattern { $$ = linkum($1, $3); } 2067c478bd9Sstevel@tonic-gate ; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate ppattern: 2097c478bd9Sstevel@tonic-gate var ASGNOP ppattern { $$ = op2($2, $1, $3); } 2107c478bd9Sstevel@tonic-gate | ppattern '?' ppattern ':' ppattern %prec '?' 2117c478bd9Sstevel@tonic-gate { $$ = op3(CONDEXPR, notnull($1), $3, $5); } 2127c478bd9Sstevel@tonic-gate | ppattern bor ppattern %prec BOR 2137c478bd9Sstevel@tonic-gate { $$ = op2(BOR, notnull($1), notnull($3)); } 2147c478bd9Sstevel@tonic-gate | ppattern and ppattern %prec AND 2157c478bd9Sstevel@tonic-gate { $$ = op2(AND, notnull($1), notnull($3)); } 2167c478bd9Sstevel@tonic-gate | NOT ppattern 2177c478bd9Sstevel@tonic-gate { $$ = op1(NOT, notnull($2)); } 2187c478bd9Sstevel@tonic-gate | ppattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); } 2197c478bd9Sstevel@tonic-gate | ppattern MATCHOP ppattern 2207c478bd9Sstevel@tonic-gate { if (constnode($3)) 2217c478bd9Sstevel@tonic-gate $$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0)); 2227c478bd9Sstevel@tonic-gate else 2237c478bd9Sstevel@tonic-gate $$ = op3($2, (Node *)1, $1, $3); } 2247c478bd9Sstevel@tonic-gate | ppattern IN varname { $$ = op2(INTEST, $1, makearr($3)); } 2257c478bd9Sstevel@tonic-gate | '(' plist ')' IN varname { $$ = op2(INTEST, $2, makearr($5)); } 2267c478bd9Sstevel@tonic-gate | ppattern term %prec CAT { $$ = op2(CAT, $1, $2); } 2277c478bd9Sstevel@tonic-gate | reg_expr 2287c478bd9Sstevel@tonic-gate { $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); } 2297c478bd9Sstevel@tonic-gate | term 2307c478bd9Sstevel@tonic-gate ; 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate pattern: 2337c478bd9Sstevel@tonic-gate var ASGNOP pattern { $$ = op2($2, $1, $3); } 2347c478bd9Sstevel@tonic-gate | pattern '?' pattern ':' pattern %prec '?' 2357c478bd9Sstevel@tonic-gate { $$ = op3(CONDEXPR, notnull($1), $3, $5); } 2367c478bd9Sstevel@tonic-gate | pattern bor pattern %prec BOR 2377c478bd9Sstevel@tonic-gate { $$ = op2(BOR, notnull($1), notnull($3)); } 2387c478bd9Sstevel@tonic-gate | pattern and pattern %prec AND 2397c478bd9Sstevel@tonic-gate { $$ = op2(AND, notnull($1), notnull($3)); } 2407c478bd9Sstevel@tonic-gate | NOT pattern 241*1ee2e5faSnakanon { $$ = op1(NOT, op2(NE,$2,valtonode(lookup((uchar *)"$zero&null",symtab),CCON))); } 2427c478bd9Sstevel@tonic-gate | pattern EQ pattern { $$ = op2($2, $1, $3); } 2437c478bd9Sstevel@tonic-gate | pattern GE pattern { $$ = op2($2, $1, $3); } 2447c478bd9Sstevel@tonic-gate | pattern GT pattern { $$ = op2($2, $1, $3); } 2457c478bd9Sstevel@tonic-gate | pattern LE pattern { $$ = op2($2, $1, $3); } 2467c478bd9Sstevel@tonic-gate | pattern LT pattern { $$ = op2($2, $1, $3); } 2477c478bd9Sstevel@tonic-gate | pattern NE pattern { $$ = op2($2, $1, $3); } 2487c478bd9Sstevel@tonic-gate | pattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); } 2497c478bd9Sstevel@tonic-gate | pattern MATCHOP pattern 2507c478bd9Sstevel@tonic-gate { if (constnode($3)) 2517c478bd9Sstevel@tonic-gate $$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0)); 2527c478bd9Sstevel@tonic-gate else 2537c478bd9Sstevel@tonic-gate $$ = op3($2, (Node *)1, $1, $3); } 2547c478bd9Sstevel@tonic-gate | pattern IN varname { $$ = op2(INTEST, $1, makearr($3)); } 2557c478bd9Sstevel@tonic-gate | '(' plist ')' IN varname { $$ = op2(INTEST, $2, makearr($5)); } 2567c478bd9Sstevel@tonic-gate | pattern '|' GETLINE var { $$ = op3(GETLINE, $4, (Node*)$2, $1); } 2577c478bd9Sstevel@tonic-gate | pattern '|' GETLINE { $$ = op3(GETLINE, (Node*)0, (Node*)$2, $1); } 2587c478bd9Sstevel@tonic-gate | pattern term %prec CAT { $$ = op2(CAT, $1, $2); } 2597c478bd9Sstevel@tonic-gate | reg_expr 2607c478bd9Sstevel@tonic-gate { $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); } 2617c478bd9Sstevel@tonic-gate | term 2627c478bd9Sstevel@tonic-gate ; 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate plist: 2657c478bd9Sstevel@tonic-gate pattern comma pattern { $$ = linkum($1, $3); } 2667c478bd9Sstevel@tonic-gate | plist comma pattern { $$ = linkum($1, $3); } 2677c478bd9Sstevel@tonic-gate ; 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate pplist: 2707c478bd9Sstevel@tonic-gate ppattern 2717c478bd9Sstevel@tonic-gate | pplist comma ppattern { $$ = linkum($1, $3); } 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate prarg: 2747c478bd9Sstevel@tonic-gate /* empty */ { $$ = rectonode(); } 2757c478bd9Sstevel@tonic-gate | pplist 2767c478bd9Sstevel@tonic-gate | '(' plist ')' { $$ = $2; } 2777c478bd9Sstevel@tonic-gate ; 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate print: 2807c478bd9Sstevel@tonic-gate PRINT | PRINTF 2817c478bd9Sstevel@tonic-gate ; 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate pst: 2847c478bd9Sstevel@tonic-gate NL | ';' | pst NL | pst ';' 2857c478bd9Sstevel@tonic-gate ; 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate rbrace: 2887c478bd9Sstevel@tonic-gate '}' | rbrace NL 2897c478bd9Sstevel@tonic-gate ; 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate reg_expr: 2927c478bd9Sstevel@tonic-gate '/' {startreg();} REGEXPR '/' { $$ = $3; } 2937c478bd9Sstevel@tonic-gate ; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate rparen: 2967c478bd9Sstevel@tonic-gate ')' | rparen NL 2977c478bd9Sstevel@tonic-gate ; 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate simple_stmt: 3007c478bd9Sstevel@tonic-gate print prarg '|' term { $$ = stat3($1, $2, (Node *) $3, $4); } 3017c478bd9Sstevel@tonic-gate | print prarg APPEND term { $$ = stat3($1, $2, (Node *) $3, $4); } 3027c478bd9Sstevel@tonic-gate | print prarg GT term { $$ = stat3($1, $2, (Node *) $3, $4); } 3037c478bd9Sstevel@tonic-gate | print prarg { $$ = stat3($1, $2, NIL, NIL); } 3047c478bd9Sstevel@tonic-gate | DELETE varname '[' patlist ']' { $$ = stat2(DELETE, makearr($2), $4); } 3057c478bd9Sstevel@tonic-gate | DELETE varname { yyclearin; ERROR "you can only delete array[element]" SYNTAX; $$ = stat1(DELETE, $2); } 3067c478bd9Sstevel@tonic-gate | pattern { $$ = exptostat($1); } 3077c478bd9Sstevel@tonic-gate | error { yyclearin; ERROR "illegal statement" SYNTAX; } 3087c478bd9Sstevel@tonic-gate ; 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate st: 3117c478bd9Sstevel@tonic-gate nl | ';' opt_nl 3127c478bd9Sstevel@tonic-gate ; 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate stmt: 3157c478bd9Sstevel@tonic-gate BREAK st { $$ = stat1(BREAK, NIL); } 3167c478bd9Sstevel@tonic-gate | CLOSE pattern st { $$ = stat1(CLOSE, $2); } 3177c478bd9Sstevel@tonic-gate | CONTINUE st { $$ = stat1(CONTINUE, NIL); } 3187c478bd9Sstevel@tonic-gate | do stmt WHILE '(' pattern ')' st 3197c478bd9Sstevel@tonic-gate { $$ = stat2(DO, $2, notnull($5)); } 3207c478bd9Sstevel@tonic-gate | EXIT pattern st { $$ = stat1(EXIT, $2); } 3217c478bd9Sstevel@tonic-gate | EXIT st { $$ = stat1(EXIT, NIL); } 3227c478bd9Sstevel@tonic-gate | for 3237c478bd9Sstevel@tonic-gate | if stmt else stmt { $$ = stat3(IF, $1, $2, $4); } 3247c478bd9Sstevel@tonic-gate | if stmt { $$ = stat3(IF, $1, $2, NIL); } 3257c478bd9Sstevel@tonic-gate | lbrace stmtlist rbrace { $$ = $2; } 3267c478bd9Sstevel@tonic-gate | NEXT st { if (infunc) 3277c478bd9Sstevel@tonic-gate ERROR "next is illegal inside a function" SYNTAX; 3287c478bd9Sstevel@tonic-gate $$ = stat1(NEXT, NIL); } 3297c478bd9Sstevel@tonic-gate | RETURN pattern st { $$ = stat1(RETURN, $2); } 3307c478bd9Sstevel@tonic-gate | RETURN st { $$ = stat1(RETURN, NIL); } 3317c478bd9Sstevel@tonic-gate | simple_stmt st 3327c478bd9Sstevel@tonic-gate | while stmt { $$ = stat2(WHILE, $1, $2); } 3337c478bd9Sstevel@tonic-gate | ';' opt_nl { $$ = 0; } 3347c478bd9Sstevel@tonic-gate ; 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate stmtlist: 3377c478bd9Sstevel@tonic-gate stmt 3387c478bd9Sstevel@tonic-gate | stmtlist stmt { $$ = linkum($1, $2); } 3397c478bd9Sstevel@tonic-gate ; 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate subop: 3427c478bd9Sstevel@tonic-gate SUB | GSUB 3437c478bd9Sstevel@tonic-gate ; 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate term: 3467c478bd9Sstevel@tonic-gate term '+' term { $$ = op2(ADD, $1, $3); } 3477c478bd9Sstevel@tonic-gate | term '-' term { $$ = op2(MINUS, $1, $3); } 3487c478bd9Sstevel@tonic-gate | term '*' term { $$ = op2(MULT, $1, $3); } 3497c478bd9Sstevel@tonic-gate | term '/' term { $$ = op2(DIVIDE, $1, $3); } 3507c478bd9Sstevel@tonic-gate | term '%' term { $$ = op2(MOD, $1, $3); } 3517c478bd9Sstevel@tonic-gate | term POWER term { $$ = op2(POWER, $1, $3); } 3527c478bd9Sstevel@tonic-gate | '-' term %prec UMINUS { $$ = op1(UMINUS, $2); } 3537c478bd9Sstevel@tonic-gate | '+' term %prec UMINUS { $$ = $2; } 3547c478bd9Sstevel@tonic-gate | BLTIN '(' ')' { $$ = op2(BLTIN, (Node *) $1, rectonode()); } 3557c478bd9Sstevel@tonic-gate | BLTIN '(' patlist ')' { $$ = op2(BLTIN, (Node *) $1, $3); } 3567c478bd9Sstevel@tonic-gate | BLTIN { $$ = op2(BLTIN, (Node *) $1, rectonode()); } 3577c478bd9Sstevel@tonic-gate | CALL '(' ')' { $$ = op2(CALL, valtonode($1,CVAR), NIL); } 3587c478bd9Sstevel@tonic-gate | CALL '(' patlist ')' { $$ = op2(CALL, valtonode($1,CVAR), $3); } 3597c478bd9Sstevel@tonic-gate | DECR var { $$ = op1(PREDECR, $2); } 3607c478bd9Sstevel@tonic-gate | INCR var { $$ = op1(PREINCR, $2); } 3617c478bd9Sstevel@tonic-gate | var DECR { $$ = op1(POSTDECR, $1); } 3627c478bd9Sstevel@tonic-gate | var INCR { $$ = op1(POSTINCR, $1); } 3637c478bd9Sstevel@tonic-gate | GETLINE var LT term { $$ = op3(GETLINE, $2, (Node *)$3, $4); } 3647c478bd9Sstevel@tonic-gate | GETLINE LT term { $$ = op3(GETLINE, NIL, (Node *)$2, $3); } 3657c478bd9Sstevel@tonic-gate | GETLINE var { $$ = op3(GETLINE, $2, NIL, NIL); } 3667c478bd9Sstevel@tonic-gate | GETLINE { $$ = op3(GETLINE, NIL, NIL, NIL); } 3677c478bd9Sstevel@tonic-gate | INDEX '(' pattern comma pattern ')' 3687c478bd9Sstevel@tonic-gate { $$ = op2(INDEX, $3, $5); } 3697c478bd9Sstevel@tonic-gate | INDEX '(' pattern comma reg_expr ')' 3707c478bd9Sstevel@tonic-gate { ERROR "index() doesn't permit regular expressions" SYNTAX; 3717c478bd9Sstevel@tonic-gate $$ = op2(INDEX, $3, (Node*)$5); } 3727c478bd9Sstevel@tonic-gate | '(' pattern ')' { $$ = $2; } 3737c478bd9Sstevel@tonic-gate | MATCHFCN '(' pattern comma reg_expr ')' 3747c478bd9Sstevel@tonic-gate { $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa($5, 1)); } 3757c478bd9Sstevel@tonic-gate | MATCHFCN '(' pattern comma pattern ')' 3767c478bd9Sstevel@tonic-gate { if (constnode($5)) 3777c478bd9Sstevel@tonic-gate $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa(strnode($5), 1)); 3787c478bd9Sstevel@tonic-gate else 3797c478bd9Sstevel@tonic-gate $$ = op3(MATCHFCN, (Node *)1, $3, $5); } 3807c478bd9Sstevel@tonic-gate | NUMBER { $$ = valtonode($1, CCON); } 3817c478bd9Sstevel@tonic-gate | SPLIT '(' pattern comma varname comma pattern ')' /* string */ 3827c478bd9Sstevel@tonic-gate { $$ = op4(SPLIT, $3, makearr($5), $7, (Node*)STRING); } 3837c478bd9Sstevel@tonic-gate | SPLIT '(' pattern comma varname comma reg_expr ')' /* const /regexp/ */ 3847c478bd9Sstevel@tonic-gate { $$ = op4(SPLIT, $3, makearr($5), (Node*)makedfa($7, 1), (Node *)REGEXPR); } 3857c478bd9Sstevel@tonic-gate | SPLIT '(' pattern comma varname ')' 3867c478bd9Sstevel@tonic-gate { $$ = op4(SPLIT, $3, makearr($5), NIL, (Node*)STRING); } /* default */ 3877c478bd9Sstevel@tonic-gate | SPRINTF '(' patlist ')' { $$ = op1($1, $3); } 3887c478bd9Sstevel@tonic-gate | STRING { $$ = valtonode($1, CCON); } 3897c478bd9Sstevel@tonic-gate | subop '(' reg_expr comma pattern ')' 3907c478bd9Sstevel@tonic-gate { $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, rectonode()); } 3917c478bd9Sstevel@tonic-gate | subop '(' pattern comma pattern ')' 3927c478bd9Sstevel@tonic-gate { if (constnode($3)) 3937c478bd9Sstevel@tonic-gate $$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, rectonode()); 3947c478bd9Sstevel@tonic-gate else 3957c478bd9Sstevel@tonic-gate $$ = op4($1, (Node *)1, $3, $5, rectonode()); } 3967c478bd9Sstevel@tonic-gate | subop '(' reg_expr comma pattern comma var ')' 3977c478bd9Sstevel@tonic-gate { $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, $7); } 3987c478bd9Sstevel@tonic-gate | subop '(' pattern comma pattern comma var ')' 3997c478bd9Sstevel@tonic-gate { if (constnode($3)) 4007c478bd9Sstevel@tonic-gate $$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, $7); 4017c478bd9Sstevel@tonic-gate else 4027c478bd9Sstevel@tonic-gate $$ = op4($1, (Node *)1, $3, $5, $7); } 4037c478bd9Sstevel@tonic-gate | SUBSTR '(' pattern comma pattern comma pattern ')' 4047c478bd9Sstevel@tonic-gate { $$ = op3(SUBSTR, $3, $5, $7); } 4057c478bd9Sstevel@tonic-gate | SUBSTR '(' pattern comma pattern ')' 4067c478bd9Sstevel@tonic-gate { $$ = op3(SUBSTR, $3, $5, NIL); } 4077c478bd9Sstevel@tonic-gate | var 4087c478bd9Sstevel@tonic-gate ; 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate var: 4117c478bd9Sstevel@tonic-gate varname 4127c478bd9Sstevel@tonic-gate | varname '[' patlist ']' { $$ = op2(ARRAY, makearr($1), $3); } 4137c478bd9Sstevel@tonic-gate | FIELD { $$ = valtonode($1, CFLD); } 4147c478bd9Sstevel@tonic-gate | IVAR { $$ = op1(INDIRECT, valtonode($1, CVAR)); } 4157c478bd9Sstevel@tonic-gate | INDIRECT term { $$ = op1(INDIRECT, $2); } 4167c478bd9Sstevel@tonic-gate ; 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate varlist: 4197c478bd9Sstevel@tonic-gate /* nothing */ { arglist = $$ = 0; } 4207c478bd9Sstevel@tonic-gate | VAR { arglist = $$ = valtonode($1,CVAR); } 4217c478bd9Sstevel@tonic-gate | varlist comma VAR { arglist = $$ = linkum($1,valtonode($3,CVAR)); } 4227c478bd9Sstevel@tonic-gate ; 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate varname: 4257c478bd9Sstevel@tonic-gate VAR { $$ = valtonode($1, CVAR); } 4267c478bd9Sstevel@tonic-gate | ARG { $$ = op1(ARG, (Node *) $1); } 4277c478bd9Sstevel@tonic-gate | VARNF { $$ = op1(VARNF, (Node *) $1); } 4287c478bd9Sstevel@tonic-gate ; 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate while: 4327c478bd9Sstevel@tonic-gate WHILE '(' pattern rparen { $$ = notnull($3); } 4337c478bd9Sstevel@tonic-gate ; 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate %% 4367c478bd9Sstevel@tonic-gate 437*1ee2e5faSnakanon static void 438*1ee2e5faSnakanon setfname(Cell *p) 4397c478bd9Sstevel@tonic-gate { 4407c478bd9Sstevel@tonic-gate if (isarr(p)) 4417c478bd9Sstevel@tonic-gate ERROR "%s is an array, not a function", p->nval SYNTAX; 4427c478bd9Sstevel@tonic-gate else if (isfunc(p)) 4437c478bd9Sstevel@tonic-gate ERROR "you can't define function %s more than once", p->nval SYNTAX; 4447c478bd9Sstevel@tonic-gate curfname = p->nval; 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate 447*1ee2e5faSnakanon 448*1ee2e5faSnakanon static int 449*1ee2e5faSnakanon constnode(Node *p) 4507c478bd9Sstevel@tonic-gate { 4517c478bd9Sstevel@tonic-gate return p->ntype == NVALUE && ((Cell *) (p->narg[0]))->csub == CCON; 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate 454*1ee2e5faSnakanon static uchar * 455*1ee2e5faSnakanon strnode(Node *p) 4567c478bd9Sstevel@tonic-gate { 4577c478bd9Sstevel@tonic-gate return ((Cell *)(p->narg[0]))->sval; 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate 460*1ee2e5faSnakanon static Node * 461*1ee2e5faSnakanon notnull(Node *n) 4627c478bd9Sstevel@tonic-gate { 4637c478bd9Sstevel@tonic-gate switch (n->nobj) { 4647c478bd9Sstevel@tonic-gate case LE: case LT: case EQ: case NE: case GT: case GE: 4657c478bd9Sstevel@tonic-gate case BOR: case AND: case NOT: 4667c478bd9Sstevel@tonic-gate return n; 4677c478bd9Sstevel@tonic-gate default: 4687c478bd9Sstevel@tonic-gate return op2(NE, n, nullnode); 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate } 471