1080 |
| matching `}' into the actions file. STACK_OFFSET is the number of | |
| matching `}' into the actions file. STACK_OFFSET is the number of | |
1081 |
| values in the current rule so far, which says where to find `$0' | |
| values in the current rule so far, which says where to find `$0' | |
1082 |
| with respect to the top of the stack. | |
| with respect to the top of the stack. | |
1083 |
|
| | |
1084 |
|
| This routine is used both for actions and guards. Only the | |
1085 |
|
| actions_obstack is used, but this is fine, since we use only | |
1086 |
|
| pointers to relevant portions inside this obstack. | |
1087 |
`-------------------------------------------------------------------*/ |
`-------------------------------------------------------------------*/ |
1088 |
|
|
1089 |
static void |
static void |
1090 |
copy_action (symbol_list *rule, int stack_offset) |
parse_braces (symbol_list *rule, int stack_offset) |
1091 |
{ |
{ |
1092 |
int c; |
int c; |
1093 |
int count; |
int count; |
1097 |
stack_offset = 0; |
stack_offset = 0; |
1098 |
|
|
1099 |
count = 1; |
count = 1; |
|
c = getc (finput); |
|
|
|
|
|
rule->action_line = lineno; |
|
|
|
|
1100 |
while (count > 0) |
while (count > 0) |
1101 |
{ |
{ |
1102 |
while (c != '}') |
while ((c = getc (finput)) != '}') |
1103 |
{ |
switch (c) |
1104 |
switch (c) |
{ |
1105 |
{ |
case '\n': |
1106 |
case '\n': |
obstack_1grow (&action_obstack, c); |
1107 |
obstack_1grow (&action_obstack, c); |
lineno++; |
1108 |
lineno++; |
break; |
1109 |
break; |
|
1110 |
|
case '{': |
1111 |
case '{': |
obstack_1grow (&action_obstack, c); |
1112 |
obstack_1grow (&action_obstack, c); |
count++; |
1113 |
count++; |
break; |
1114 |
break; |
|
1115 |
|
case '\'': |
1116 |
case '\'': |
case '"': |
1117 |
case '"': |
copy_string (finput, &action_obstack, c); |
1118 |
copy_string (finput, &action_obstack, c); |
break; |
1119 |
break; |
|
1120 |
|
case '/': |
1121 |
case '/': |
copy_comment (finput, &action_obstack); |
1122 |
copy_comment (finput, &action_obstack); |
break; |
1123 |
break; |
|
1124 |
|
case '$': |
1125 |
case '$': |
copy_dollar (finput, &action_obstack, |
1126 |
copy_dollar (finput, &action_obstack, |
rule, stack_offset); |
1127 |
rule, stack_offset); |
break; |
1128 |
break; |
|
1129 |
|
case '@': |
1130 |
case '@': |
copy_at (finput, &action_obstack, |
1131 |
copy_at (finput, &action_obstack, |
stack_offset); |
1132 |
stack_offset); |
break; |
|
break; |
|
|
|
|
|
case EOF: |
|
|
fatal (_("unmatched %s"), "`{'"); |
|
1133 |
|
|
1134 |
default: |
case EOF: |
1135 |
obstack_1grow (&action_obstack, c); |
fatal (_("unmatched %s"), "`{'"); |
|
} |
|
1136 |
|
|
1137 |
c = getc (finput); |
default: |
1138 |
} |
obstack_1grow (&action_obstack, c); |
1139 |
|
} |
|
/* above loop exits when c is '}' */ |
|
1140 |
|
|
1141 |
|
/* Above loop exits when C is '}'. */ |
1142 |
if (--count) |
if (--count) |
1143 |
{ |
{ |
1144 |
obstack_1grow (&action_obstack, c); |
obstack_1grow (&action_obstack, c); |
1147 |
} |
} |
1148 |
|
|
1149 |
obstack_1grow (&action_obstack, '\0'); |
obstack_1grow (&action_obstack, '\0'); |
|
rule->action = obstack_finish (&action_obstack); |
|
1150 |
} |
} |
1151 |
|
|
|
/*-------------------------------------------------------------------. |
|
|
| After `%guard' is seen in the input file, copy the actual guard | |
|
|
| into the guards file. If the guard is followed by an action, copy | |
|
|
| that into the actions file. STACK_OFFSET is the number of values | |
|
|
| in the current rule so far, which says where to find `$0' with | |
|
|
| respect to the top of the stack, for the simple parser in which | |
|
|
| the stack is not popped until after the guard is run. | |
|
|
`-------------------------------------------------------------------*/ |
|
1152 |
|
|
1153 |
static void |
static void |
1154 |
copy_guard (symbol_list *rule, int stack_offset) |
parse_action (symbol_list *rule, int stack_offset) |
1155 |
{ |
{ |
1156 |
int c; |
rule->action_line = lineno; |
1157 |
int count; |
parse_braces (rule, stack_offset); |
1158 |
int brace_flag = 0; |
rule->action = obstack_finish (&action_obstack); |
1159 |
|
} |
1160 |
|
|
|
/* offset is always 0 if parser has already popped the stack pointer */ |
|
|
if (semantic_parser) |
|
|
stack_offset = 0; |
|
1161 |
|
|
1162 |
|
static void |
1163 |
|
parse_guard (symbol_list *rule, int stack_offset) |
1164 |
|
{ |
1165 |
|
token_t t = lex (); |
1166 |
|
if (t != tok_left_curly) |
1167 |
|
complain (_("invalid %s declaration"), "%guard"); |
1168 |
rule->guard_line = lineno; |
rule->guard_line = lineno; |
1169 |
|
parse_braces (rule, stack_offset); |
1170 |
count = 0; |
rule->guard = obstack_finish (&action_obstack); |
|
c = getc (finput); |
|
|
|
|
|
while (brace_flag ? (count > 0) : (c != ';')) |
|
|
{ |
|
|
switch (c) |
|
|
{ |
|
|
case '\n': |
|
|
obstack_1grow (&guard_obstack, c); |
|
|
lineno++; |
|
|
break; |
|
|
|
|
|
case '{': |
|
|
obstack_1grow (&guard_obstack, c); |
|
|
brace_flag = 1; |
|
|
count++; |
|
|
break; |
|
|
|
|
|
case '}': |
|
|
obstack_1grow (&guard_obstack, c); |
|
|
if (count > 0) |
|
|
count--; |
|
|
else |
|
|
{ |
|
|
complain (_("unmatched %s"), "`}'"); |
|
|
c = getc (finput); /* skip it */ |
|
|
} |
|
|
break; |
|
|
|
|
|
case '\'': |
|
|
case '"': |
|
|
copy_string (finput, &guard_obstack, c); |
|
|
break; |
|
|
|
|
|
case '/': |
|
|
copy_comment (finput, &guard_obstack); |
|
|
break; |
|
|
|
|
|
case '$': |
|
|
copy_dollar (finput, &guard_obstack, rule, stack_offset); |
|
|
break; |
|
|
|
|
|
case '@': |
|
|
copy_at (finput, &guard_obstack, stack_offset); |
|
|
break; |
|
|
|
|
|
case EOF: |
|
|
fatal ("%s", _("unterminated %guard clause")); |
|
|
|
|
|
default: |
|
|
obstack_1grow (&guard_obstack, c); |
|
|
} |
|
|
|
|
|
if (c != '}' || count != 0) |
|
|
c = getc (finput); |
|
|
} |
|
|
|
|
|
obstack_1grow (&guard_obstack, '\0'); |
|
|
rule->guard = obstack_finish (&guard_obstack); |
|
1171 |
} |
} |
1172 |
|
|
1173 |
|
|
1174 |
|
|
1175 |
/*-------------------------------------------------------------------. |
/*-------------------------------------------------------------------. |
1372 |
} |
} |
1373 |
else /* handle an action. */ |
else /* handle an action. */ |
1374 |
{ |
{ |
1375 |
copy_action (crule, rulelength); |
parse_action (crule, rulelength); |
1376 |
action_flag = 1; |
action_flag = 1; |
1377 |
xactions++; /* JF */ |
xactions++; /* JF */ |
1378 |
} |
} |
1397 |
if (!semantic_parser) |
if (!semantic_parser) |
1398 |
complain (_("%%guard present but %%semantic_parser not specified")); |
complain (_("%%guard present but %%semantic_parser not specified")); |
1399 |
|
|
1400 |
copy_guard (crule, rulelength); |
parse_guard (crule, rulelength); |
1401 |
t = lex (); |
t = lex (); |
1402 |
} |
} |
1403 |
|
|
1406 |
/* This case never occurs -wjh */ |
/* This case never occurs -wjh */ |
1407 |
if (action_flag) |
if (action_flag) |
1408 |
complain (_("two actions at end of one rule")); |
complain (_("two actions at end of one rule")); |
1409 |
copy_action (crule, rulelength); |
parse_action (crule, rulelength); |
1410 |
action_flag = 1; |
action_flag = 1; |
1411 |
xactions++; /* -wjh */ |
xactions++; /* -wjh */ |
1412 |
t = lex (); |
t = lex (); |
1798 |
/* Initialize the obstacks. */ |
/* Initialize the obstacks. */ |
1799 |
obstack_init (&action_obstack); |
obstack_init (&action_obstack); |
1800 |
obstack_init (&attrs_obstack); |
obstack_init (&attrs_obstack); |
|
obstack_init (&guard_obstack); |
|
1801 |
obstack_init (&output_obstack); |
obstack_init (&output_obstack); |
1802 |
|
|
1803 |
finput = xfopen (infile, "r"); |
finput = xfopen (infile, "r"); |