5
The "expect" directive indicates that this grammar has
6
a known ambiguity which is resolved by the default
9
The ambiguity is as follows: A single function call can
10
be confused with two expressions separated by a space.
11
This conflict does not apear in singleton expressions,
12
but only in space-separated lists, used by forany and forall.
13
For example, "foo ( baz )" could be interpreted as a
14
call to function foo, or the literal expression
17
I belive this is an acceptable ambiguity, because the
18
default is the common case and can be overridden when
19
necessary. For example,
25
...indicates that the function foo should be called and the
26
resulting list be used for the branches of the forany.
27
To force the expression-list interpretation, use this instead:
29
forany x in (foo) (baz)
34
%token TOKEN_DELIMITER
35
%token TOKEN_LEFT_ARROW
36
%token TOKEN_DOUBLE_LEFT_ARROW
37
%token TOKEN_LONG_LEFT_ARROW
38
%token TOKEN_LONG_DOUBLE_LEFT_ARROW
39
%token TOKEN_RIGHT_ARROW
40
%token TOKEN_DOUBLE_RIGHT_ARROW
41
%token TOKEN_SQUIGGLY_RIGHT_ARROW
42
%token TOKEN_NUMBERED_SQUIGGLY_RIGHT_ARROW
43
%token TOKEN_DOUBLE_SQUIGGLY_RIGHT_ARROW
44
%token TOKEN_NUMBERED_DOUBLE_SQUIGGLY_RIGHT_ARROW
45
%token TOKEN_LONG_RIGHT_ARROW
46
%token TOKEN_LONG_DOUBLE_RIGHT_ARROW
47
%token TOKEN_LONG_SQUIGGLY_RIGHT_ARROW
48
%token TOKEN_LONG_DOUBLE_SQUIGGLY_RIGHT_ARROW
110
%type <group> program group
111
%type <command> command
112
%type <function> function
113
%type <try> try try_limit
114
%type <try_limit> time_limit loop_limit opt_every_limit
115
%type <forloop> forloop
116
%type <whileloop> whileloop
117
%type <conditional> conditional
118
%type <shift> shift_line
119
%type <rtn> return_line
120
%type <assign> assign_line
121
%type <simple> simple_line simple
122
%type <redirect> redirect
123
%type <number> time_units fortype
124
%type <word> word wordequals
125
%type <expr> expr expr_list opt_expr_comma_list expr_comma_list
126
%type <token> TOKEN_FUNCTION TOKEN_END TOKEN_DELIMITER TOKEN_WHILE TOKEN_FOR TOKEN_IN TOKEN_IF TOKEN_ELSE TOKEN_TRY TOKEN_CATCH TOKEN_ASSIGN TOKEN_ATOM TOKEN_OR TOKEN_AND TOKEN_EQ TOKEN_NE TOKEN_EQL TOKEN_NEQL TOKEN_LT TOKEN_LE TOKEN_GT TOKEN_GE TOKEN_ADD TOKEN_SUB TOKEN_MUL TOKEN_DIV TOKEN_MOD TOKEN_NOT TOKEN_EXISTS TOKEN_ISR TOKEN_ISW TOKEN_ISX TOKEN_ISBLOCK TOKEN_ISCHAR TOKEN_ISDIR TOKEN_ISFILE TOKEN_ISLINK TOKEN_ISPIPE TOKEN_ISSOCK TOKEN_POW TOKEN_LPAREN TOKEN_RPAREN TOKEN_TO TOKEN_SHIFT TOKEN_LEFT_ARROW TOKEN_RIGHT_ARROW TOKEN_DOUBLE_RIGHT_ARROW TOKEN_NUMBERED_SQUIGGLY_RIGHT_ARROW TOKEN_NUMBERED_DOUBLE_SQUIGGLY_RIGHT_ARROW TOKEN_SQUIGGLY_RIGHT_ARROW TOKEN_LONG_LEFT_ARROW TOKEN_LONG_RIGHT_ARROW TOKEN_LONG_DOUBLE_RIGHT_ARROW TOKEN_LONG_SQUIGGLY_RIGHT_ARROW TOKEN_LONG_DOUBLE_SQUIGGLY_RIGHT_ARROW TOKEN_DOUBLE_SQUIGGLY_RIGHT_ARROW
132
%nonassoc TOKEN_EQ TOKEN_NE TOKEN_EQL TOKEN_NEQL TOKEN_LT TOKEN_LE TOKEN_GT TOKEN_GE
133
%left TOKEN_ADD TOKEN_SUB
134
%left TOKEN_MUL TOKEN_DIV TOKEN_MOD
135
%right TOKEN_NOT TOKEN_EXISTS TOKEN_ISR TOKEN_ISW TOKEN_ISX TOKEN_ISBLOCK TOKEN_ISCHAR TOKEN_ISDIR TOKEN_ISFILE TOKEN_ISLINK TOKEN_ISPIPE TOKEN_ISSOCK
138
%nonassoc PREC_LITERAL
145
#include "ftsh_error.h"
154
extern char * yytext;
157
extern int yyerror( char *str );
160
static struct ast_group * parser_result=0;
168
{ parser_result = $1; }
173
{ $$ = ast_group_create( $1, $2 ); }
175
{ $$ = ast_group_create( $1, 0 ); }
180
{ $$ = ast_command_create( AST_COMMAND_FUNCTION, $1 ); }
182
{ $$ = ast_command_create( AST_COMMAND_TRY, $1 ); }
184
{ $$ = ast_command_create( AST_COMMAND_FORLOOP, $1 ); }
186
{ $$ = ast_command_create( AST_COMMAND_WHILELOOP, $1 ); }
188
{ $$ = ast_command_create( AST_COMMAND_CONDITIONAL, $1 ); }
190
{ $$ = ast_command_create( AST_COMMAND_SHIFT, $1 ); }
192
{ $$ = ast_command_create( AST_COMMAND_ASSIGN, $1 ); }
194
{ $$ = ast_command_create( AST_COMMAND_RETURN, $1 ); }
196
{ $$ = ast_command_create( AST_COMMAND_SIMPLE, $1 ); }
198
{ $$ = ast_command_create( AST_COMMAND_EMPTY, 0 ); }
202
: TOKEN_FUNCTION word TOKEN_DELIMITER group TOKEN_END TOKEN_DELIMITER
203
{ $$ = ast_function_create( $1.line, $5.line, $2, $4 ); }
207
Ok, this is ugly, but the only way to get around the reality of LALR(1).
211
: TOKEN_TRY try_limit TOKEN_DELIMITER group TOKEN_END TOKEN_DELIMITER
214
$$->try_line=$1.line;
215
$$->catch_line=$5.line;
216
$$->end_line=$5.line;
219
| TOKEN_TRY try_limit TOKEN_DELIMITER group TOKEN_CATCH TOKEN_DELIMITER group TOKEN_END TOKEN_DELIMITER
222
$$->try_line=$1.line;
223
$$->catch_line=$5.line;
224
$$->end_line=$8.line;
232
{ $$ = ast_try_create(0,0,0,0,0,$1,0,0); }
233
| opt_conj time_limit opt_every_limit
234
{ $$ = ast_try_create(0,0,0,$2,0,$3,0,0); }
235
| opt_conj loop_limit opt_every_limit
236
{ $$ = ast_try_create(0,0,0,0,$2,$3,0,0); }
237
| opt_conj time_limit opt_conj loop_limit opt_every_limit
238
{ $$ = ast_try_create(0,0,0,$2,$4,$5,0,0); }
239
| opt_conj loop_limit opt_conj time_limit opt_every_limit
240
{ $$ = ast_try_create(0,0,0,$4,$2,$5,0,0); }
254
{ $$ = ast_try_limit_create( $1, $2 ); }
259
{ $$ = ast_try_limit_create( $1, 0 ); }
265
| TOKEN_EVERY expr time_units
266
{ $$ = ast_try_limit_create( $2, $3 ); }
281
: fortype word TOKEN_IN expr_list TOKEN_DELIMITER group TOKEN_END TOKEN_DELIMITER
282
{ $$ = ast_forloop_create( $1, $3.line, $7.line, $2, $4, $6 ); }
295
: TOKEN_WHILE expr TOKEN_DELIMITER group TOKEN_END TOKEN_DELIMITER
296
{ $$ = ast_whileloop_create( $1.line, $3.line, $5.line, $2, $4 ); }
300
: TOKEN_IF expr TOKEN_DELIMITER group TOKEN_END TOKEN_DELIMITER
301
{ $$ = ast_conditional_create( $1.line, $3.line, $5.line, $5.line, $2, $4, 0 ); }
302
| TOKEN_IF expr TOKEN_DELIMITER group TOKEN_ELSE TOKEN_DELIMITER group TOKEN_END TOKEN_DELIMITER
303
{ $$ = ast_conditional_create( $1.line, $3.line, $8.line, $8.line, $2, $4, $7 ); }
304
| TOKEN_IF expr TOKEN_DELIMITER group TOKEN_ELSE conditional
306
struct ast_group *g = ast_group_create( ast_command_create( AST_COMMAND_CONDITIONAL, $6 ), 0 );
307
$$ = ast_conditional_create( $1.line, $3.line, $5.line, $5.line, $2, $4, g );
312
: TOKEN_SHIFT expr TOKEN_DELIMITER
313
{ $$ = ast_shift_create($1.line,$2); }
314
| TOKEN_SHIFT TOKEN_DELIMITER
315
{ $$ = ast_shift_create($1.line,0); }
319
: wordequals expr TOKEN_DELIMITER
320
{ $$ = ast_assign_create( $3.line, $1, $2 ); }
321
| wordequals TOKEN_DELIMITER
322
{ $$ = ast_assign_create( $2.line, $1, 0 ); }
326
: TOKEN_RETURN expr TOKEN_DELIMITER
327
{ $$ = ast_return_create( $3.line, $2 ); }
331
: simple TOKEN_DELIMITER
332
{ $$ = $1; $1->line = $2.line; }
339
for( w=$1->words; w->next; w=w->next ) {}
345
struct ast_redirect *r;
346
if( $1->redirects ) {
347
for( r=$1->redirects; r->next; r=r->next ) {}
355
{ $$ = ast_simple_create( 0, $1, 0 ); }
359
: TOKEN_LEFT_ARROW word
360
{ $$ = ast_redirect_create( AST_REDIRECT_FILE, $1.firstint, $2, AST_REDIRECT_INPUT ); }
361
| TOKEN_RIGHT_ARROW word
362
{ $$ = ast_redirect_create( AST_REDIRECT_FILE, $1.firstint, $2, AST_REDIRECT_OUTPUT ); }
363
| TOKEN_DOUBLE_RIGHT_ARROW word
364
{ $$ = ast_redirect_create( AST_REDIRECT_FILE, $1.firstint, $2, AST_REDIRECT_APPEND ); }
365
| TOKEN_NUMBERED_SQUIGGLY_RIGHT_ARROW word
366
{ $$ = ast_redirect_create( AST_REDIRECT_FD, $1.firstint, $2, AST_REDIRECT_OUTPUT ); }
367
| TOKEN_NUMBERED_DOUBLE_SQUIGGLY_RIGHT_ARROW word
368
{ $$ = ast_redirect_create( AST_REDIRECT_FD, $1.firstint, $2, AST_REDIRECT_APPEND ); }
369
| TOKEN_SQUIGGLY_RIGHT_ARROW word
371
$$ = ast_redirect_create( AST_REDIRECT_FILE, 1, $2, AST_REDIRECT_OUTPUT );
372
$$->next = ast_redirect_create( AST_REDIRECT_FD, 2, ast_word_create($1.line,"1"), AST_REDIRECT_APPEND );
374
| TOKEN_DOUBLE_SQUIGGLY_RIGHT_ARROW word
376
$$ = ast_redirect_create( AST_REDIRECT_FILE, 1, $2, AST_REDIRECT_APPEND );
377
$$->next = ast_redirect_create( AST_REDIRECT_FD, 2, ast_word_create($1.line,"1"), AST_REDIRECT_APPEND );
379
| TOKEN_LONG_LEFT_ARROW word
380
{ $$ = ast_redirect_create( AST_REDIRECT_BUFFER, $1.firstint, $2, AST_REDIRECT_INPUT ); }
381
| TOKEN_LONG_RIGHT_ARROW word
382
{ $$ = ast_redirect_create( AST_REDIRECT_BUFFER, $1.firstint, $2, AST_REDIRECT_OUTPUT ); }
383
| TOKEN_LONG_DOUBLE_RIGHT_ARROW word
384
{ $$ = ast_redirect_create( AST_REDIRECT_BUFFER, $1.firstint, $2, AST_REDIRECT_APPEND ); }
385
| TOKEN_LONG_SQUIGGLY_RIGHT_ARROW word
387
$$ = ast_redirect_create( AST_REDIRECT_BUFFER, 1, $2, AST_REDIRECT_OUTPUT );
388
$$->next = ast_redirect_create( AST_REDIRECT_FD, 2, ast_word_create($1.line,"1"), AST_REDIRECT_APPEND );
390
| TOKEN_LONG_DOUBLE_SQUIGGLY_RIGHT_ARROW word
392
$$ = ast_redirect_create( AST_REDIRECT_BUFFER, 1, $2, AST_REDIRECT_APPEND );
393
$$->next = ast_redirect_create( AST_REDIRECT_FD, 2, ast_word_create($1.line,"1"), AST_REDIRECT_APPEND );
407
| expr TOKEN_COMMA expr_comma_list
408
{ $$ = $1; $1->next=$3; }
415
{ $$ = $1; $1->next=$2; }
419
: expr TOKEN_TO expr %prec TOKEN_TO
420
{ $$ = expr_create($2.line,EXPR_TO,0,$1,$3,0); }
421
| expr TOKEN_TO expr TOKEN_STEP expr %prec TOKEN_STEP
422
{ $$ = expr_create($2.line,EXPR_TO,0,$1,$3,$5); }
424
{ $$ = expr_create($2.line,EXPR_OR,0,$1,$3,0); }
425
| expr TOKEN_AND expr
426
{ $$ = expr_create($2.line,EXPR_AND,0,$1,$3,0); }
428
{ $$ = expr_create($2.line,EXPR_EQ,0,$1,$3,0); }
430
{ $$ = expr_create($2.line,EXPR_NE,0,$1,$3,0); }
431
| expr TOKEN_EQL expr
432
{ $$ = expr_create($2.line,EXPR_EQL,0,$1,$3,0); }
433
| expr TOKEN_NEQL expr
434
{ $$ = expr_create($2.line,EXPR_NEQL,0,$1,$3,0); }
436
{ $$ = expr_create($2.line,EXPR_LT,0,$1,$3,0); }
438
{ $$ = expr_create($2.line,EXPR_LE,0,$1,$3,0); }
440
{ $$ = expr_create($2.line,EXPR_GT,0,$1,$3,0); }
442
{ $$ = expr_create($2.line,EXPR_GE,0,$1,$3,0); }
443
| expr TOKEN_ADD expr
444
{ $$ = expr_create($2.line,EXPR_ADD,0,$1,$3,0); }
445
| expr TOKEN_SUB expr
446
{ $$ = expr_create($2.line,EXPR_SUB,0,$1,$3,0); }
447
| expr TOKEN_MUL expr
448
{ $$ = expr_create($2.line,EXPR_MUL,0,$1,$3,0); }
449
| expr TOKEN_DIV expr
450
{ $$ = expr_create($2.line,EXPR_DIV,0,$1,$3,0); }
451
| expr TOKEN_MOD expr
452
{ $$ = expr_create($2.line,EXPR_MOD,0,$1,$3,0); }
454
{ $$ = expr_create( $1.line, EXPR_NOT, 0, $2, 0, 0); }
456
{ $$ = expr_create( $1.line, EXPR_EXISTS, 0, $2, 0, 0); }
458
{ $$ = expr_create( $1.line, EXPR_ISR, 0, $2, 0, 0); }
460
{ $$ = expr_create( $1.line, EXPR_ISW, 0, $2, 0, 0); }
462
{ $$ = expr_create( $1.line, EXPR_ISX, 0, $2, 0, 0); }
464
{ $$ = expr_create( $1.line, EXPR_ISBLOCK, 0, $2, 0, 0); }
466
{ $$ = expr_create( $1.line, EXPR_ISCHAR, 0, $2, 0, 0); }
468
{ $$ = expr_create( $1.line, EXPR_ISDIR, 0, $2, 0, 0); }
470
{ $$ = expr_create( $1.line, EXPR_ISFILE, 0, $2, 0, 0); }
472
{ $$ = expr_create( $1.line, EXPR_ISLINK, 0, $2, 0, 0); }
474
{ $$ = expr_create( $1.line, EXPR_ISPIPE, 0, $2, 0, 0); }
476
{ $$ = expr_create( $1.line, EXPR_ISSOCK, 0, $2, 0, 0); }
477
| expr TOKEN_POW expr
478
{ $$ = expr_create( $2.line, EXPR_POW, 0, $1, $3, 0 ); }
479
| TOKEN_LPAREN expr TOKEN_RPAREN %prec PREC_EXPR
480
{ $$ = expr_create($1.line,EXPR_EXPR,0,$2,0,0); }
481
| word %prec PREC_LITERAL
482
{ $$ = expr_create($1->line,EXPR_LITERAL,$1,0,0,0); }
483
| word TOKEN_LPAREN opt_expr_comma_list TOKEN_RPAREN %prec PREC_FCALL
484
{ $$ = expr_create($2.line,EXPR_FCALL,$1,$3,0,0); }
489
{ $$ = ast_word_create( $1.line, yytext ); }
494
{ $$ = ast_word_create( $1.line, yytext ); }
500
struct ast_group * parse_file( FILE *f, int do_debug )
506
return parser_result;
509
extern int current_line;
511
int yyerror( char *string )
513
ftsh_fatal(current_line,"parse error near here",current_line);