| 1059 | } |
| 1060 | |
| 1061 | static char *compile_arg(char **theptr, char *yyvaltag) |
| 1062 | { |
| 1063 | char *p = *theptr; |
| 1064 | struct mstring *c = msnew(); |
| 1065 | int i, j, n; |
| 1066 | Yshort *offsets=0, maxoffset; |
| 1067 | bucket **rhs; |
| 1068 | |
| 1069 | maxoffset = n = 0; |
| 1070 | for (i = nitems - 1; pitem[i]; --i) { |
| 1071 | n++; |
| 1072 | if (pitem[i]->class != ARGUMENT) |
| 1073 | maxoffset++; } |
| 1074 | if (maxoffset > 0) { |
| 1075 | offsets = NEW2(maxoffset+1, Yshort); |
| 1076 | if (offsets == 0) no_space(); } |
| 1077 | for (j=0, i++; i<nitems; i++) |
| 1078 | if (pitem[i]->class != ARGUMENT) |
| 1079 | offsets[++j] = i - nitems + 1; |
| 1080 | rhs = pitem + nitems - 1; |
| 1081 | |
| 1082 | if (yyvaltag) |
| 1083 | msprintf(c, "yyval.%s = ", yyvaltag); |
| 1084 | else |
| 1085 | msprintf(c, "yyval = "); |
| 1086 | while (*p) { |
| 1087 | if (*p == '$') { |
| 1088 | char *tag = 0; |
| 1089 | if (*++p == '<') |
| 1090 | if (!(p = parse_id(++p, &tag)) || *p++ != '>') |
| 1091 | illegal_tag(rescan_lineno, 0, 0); |
| 1092 | if (isdigit(*p) || *p == '-') { |
| 1093 | int val; |
| 1094 | if (!(p = parse_int(p, &val))) |
| 1095 | dollar_error(rescan_lineno, 0, 0); |
| 1096 | if (val <= 0) i = val - n; |
| 1097 | else if (val > maxoffset) { |
| 1098 | dollar_warning(rescan_lineno, val); |
| 1099 | i = val - maxoffset; |
| 1100 | } else { |
| 1101 | i = offsets[val]; |
| 1102 | if (!tag && !(tag = rhs[i]->tag) && havetags) |
| 1103 | untyped_rhs(val, rhs[i]->name); |
| 1104 | } |
| 1105 | msprintf(c, "yyvsp[%d]", i); |
| 1106 | if (tag) msprintf(c, ".%s", tag); |
| 1107 | else if (havetags) |
| 1108 | unknown_rhs(val); |
| 1109 | } else if (isalpha(*p) || *p == '_') { |
| 1110 | char *arg; |
| 1111 | if (!(p = parse_id(p, &arg))) |
| 1112 | dollar_error(rescan_lineno, 0, 0); |
| 1113 | for (i=plhs[nrules]->args-1; i>=0; i--) |
| 1114 | if (arg == plhs[nrules]->argnames[i]) break; |
| 1115 | if (i<0) |
| 1116 | error(rescan_lineno, 0, 0, "unknown argument $%s", arg); |
| 1117 | if (!tag) |
| 1118 | tag = plhs[nrules]->argtags[i]; |
no test coverage detected