zsh-workers
 help / color / mirror / code / Atom feed
* zsh-3.1.4 bug, parsing case ... esac
@ 1998-09-03  0:53 SL Baur
  1998-09-03  3:52 ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: SL Baur @ 1998-09-03  0:53 UTC (permalink / raw)
  To: zsh-workers

The following code, when executed in zsh running as /bin/sh produces
the error messages:
zsh: parse error near `echo'
zsh: parse error in command substitution

"BISON=`if [ -f /usr/src/egcs-1.1a/gcc/../bison/bison ] ; then
		case . in
		/*) echo /usr/src/egcs-1.1a/gcc/../bison/bison -L ./../bison/ ;;
		*) echo /usr/src/egcs-1.1a/gcc/../bison/bison -L /usr/src/egcs-1.1a/gcc/./../bison/ ;;
		esac else echo bison ;
	fi`"

adding a semicolon after the esac makes the messages go away, but I
think this should work as is.

This test case came from egcs-1.1a and causes the build to break.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: zsh-3.1.4 bug, parsing case ... esac
  1998-09-03  0:53 zsh-3.1.4 bug, parsing case ... esac SL Baur
@ 1998-09-03  3:52 ` Bart Schaefer
  1998-09-03  5:43   ` Zoltan Hidvegi
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 1998-09-03  3:52 UTC (permalink / raw)
  To: SL Baur, zsh-workers

On Sep 2,  5:53pm, SL Baur wrote:
} Subject: zsh-3.1.4 bug, parsing case ... esac
}
} zsh: parse error near `echo'
} zsh: parse error in command substitution
} 
} 		esac else echo bison ;
} 
} adding a semicolon after the esac makes the messages go away, but I
} think this should work as is.

Blech.  That sure doesn't parse according to the bash manual.  The
stuff between "then" and "else" has to be a properly-terminated list,
which means it has to end with ; & or newline.

Anybody have access to a ksh manual?

It might be possible to special-case (ahem) this because esac is a
reserved word, but zsh's parser is doing exactly what it is documented
to do, so it can't be called a bug (except in egcs's makefile).

I'd report it to the egcs folks and see what they have to say.  My guess is
this wasn't intentional on their part.  It does appear that bash accepts
"esac", "done" or "fi" as termination of a "list", so it even accepts the
following gobbledygook:

if false; then if false; then if false; then; fi fi fi
if false; then case x in x);; esac else while true; do break; done fi
for y in y; do if true; then case x in x) break;; esac fi done

This only works in "list" context, e.g., if you run the above three lines
together it won't parse the "fi if".  I suspect all the above is terribly
unportable and should not be used in a reasonable shell script or makefile.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: zsh-3.1.4 bug, parsing case ... esac
  1998-09-03  3:52 ` Bart Schaefer
@ 1998-09-03  5:43   ` Zoltan Hidvegi
  1998-09-03 14:51     ` Bart Schaefer
  1998-09-03 15:04     ` PATCH: 3.0.5 - " Bart Schaefer
  0 siblings, 2 replies; 6+ messages in thread
From: Zoltan Hidvegi @ 1998-09-03  5:43 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: steve, zsh-workers

> On Sep 2,  5:53pm, SL Baur wrote:
> } Subject: zsh-3.1.4 bug, parsing case ... esac
> }
> } zsh: parse error near `echo'
> } zsh: parse error in command substitution
> } 
> } 		esac else echo bison ;
> } 
> } adding a semicolon after the esac makes the messages go away, but I
> } think this should work as is.
> 
> Blech.  That sure doesn't parse according to the bash manual.  The
> stuff between "then" and "else" has to be a properly-terminated list,
> which means it has to end with ; & or newline.

Actually, the shell grammar allows this, this is really a zsh bug.
For example,

if true; then if true; then echo foo; fi else echo bar; fi

is accepted by zsh although there is no semicolon between fi and else.
Similarily

if ((some math)) then ((some other math)) fi

works.  Same for [[ ... ]].

Zoli


*** Src/parse.c~	Sat May  2 03:45:37 1998
--- Src/parse.c	Thu Sep  3 00:36:33 1998
***************
*** 542,557 ****
  
  	while (tok == SEPER)
  	    yylex();
! 	if (tok == OUTBRACE) {
! 	    yylex();
  	    break;
- 	}
  	if (tok != STRING)
  	    YYERRORV;
! 	if (!strcmp(tokstr, "esac")) {
! 	    yylex();
  	    break;
- 	}
  	str = ncalloc(strlen(tokstr) + 2);
  	*str = ';';
  	strcpy(str + 1, tokstr);
--- 542,553 ----
  
  	while (tok == SEPER)
  	    yylex();
! 	if (tok == OUTBRACE)
  	    break;
  	if (tok != STRING)
  	    YYERRORV;
! 	if (!strcmp(tokstr, "esac"))
  	    break;
  	str = ncalloc(strlen(tokstr) + 2);
  	*str = ';';
  	strcpy(str + 1, tokstr);
***************
*** 618,627 ****
  	addlinknode(pats, str);
  	addlinknode(lists, par_list());
  	n++;
! 	if ((tok == ESAC && !brflag) || (tok == OUTBRACE && brflag)) {
! 	    yylex();
  	    break;
- 	}
  	if(tok == SEMIAMP)
  	    *str = '&';
  	else if (tok != DSEMI)
--- 614,621 ----
  	addlinknode(pats, str);
  	addlinknode(lists, par_list());
  	n++;
! 	if ((tok == ESAC && !brflag) || (tok == OUTBRACE && brflag))
  	    break;
  	if(tok == SEMIAMP)
  	    *str = '&';
  	else if (tok != DSEMI)
***************
*** 630,635 ****
--- 624,632 ----
  	incmdpos = 0;
  	yylex();
      }
+ 
+     incmdpos = 1;
+     yylex();
  
      cc->pats = (char **)alloc((n + 1) * sizeof(char *));
  


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: zsh-3.1.4 bug, parsing case ... esac
  1998-09-03  5:43   ` Zoltan Hidvegi
@ 1998-09-03 14:51     ` Bart Schaefer
  1998-09-03 19:00       ` Zoltan Hidvegi
  1998-09-03 15:04     ` PATCH: 3.0.5 - " Bart Schaefer
  1 sibling, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 1998-09-03 14:51 UTC (permalink / raw)
  To: zsh-workers

On Sep 3, 12:43am, Zoltan Hidvegi wrote:
} Subject: Re: zsh-3.1.4 bug, parsing case ... esac
}
} > } 		esac else echo bison ;
} > 
} > Blech.  That sure doesn't parse according to the bash manual.  The
} > stuff between "then" and "else" has to be a properly-terminated list,
} 
} Actually, the shell grammar allows this, this is really a zsh bug.

Obviously, this is a surprise to me.  Can you point me at "the shell
grammar" that specifies this?  The informal one in the man pages/info
sure doesn't.

} Similarily
} 
} if ((some math)) then ((some other math)) fi
} 
} works.  Same for [[ ... ]].

Yes, I knew about those, but I thought they were handled specially.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 6+ messages in thread

* PATCH: 3.0.5 - Re: zsh-3.1.4 bug, parsing case ... esac
  1998-09-03  5:43   ` Zoltan Hidvegi
  1998-09-03 14:51     ` Bart Schaefer
@ 1998-09-03 15:04     ` Bart Schaefer
  1 sibling, 0 replies; 6+ messages in thread
From: Bart Schaefer @ 1998-09-03 15:04 UTC (permalink / raw)
  To: zsh-workers

On Sep 3, 12:43am, Zoltan Hidvegi wrote:
} Subject: Re: zsh-3.1.4 bug, parsing case ... esac
} > }
} > } zsh: parse error near `echo'
} > } zsh: parse error in command substitution
} > } 
} > } 		esac else echo bison ;
} 
} Actually, the shell grammar allows this, this is really a zsh bug.

Here's Zoltan's patch tweaked for 3.0.5.

Index: Src/parse.c
===================================================================
--- parse.c	1998/07/02 15:56:02	1.6
+++ parse.c	1998/09/03 14:55:26
@@ -482,16 +482,12 @@
 
 	while (tok == SEPER)
 	    yylex();
-	if (tok == OUTBRACE) {
-	    yylex();
+	if (tok == OUTBRACE)
 	    break;
-	}
 	if (tok != STRING)
 	    YYERRORV;
-	if (!strcmp(tokstr, "esac")) {
-	    yylex();
+	if (!strcmp(tokstr, "esac"))
 	    break;
-	}
 	str = tokstr;
 	incasepat = 0;
 	incmdpos = 1;
@@ -556,16 +552,17 @@
 	addlinknode(pats, str);
 	addlinknode(lists, par_list());
 	n++;
-	if ((tok == ESAC && !brflag) || (tok == OUTBRACE && brflag)) {
-	    yylex();
+	if ((tok == ESAC && !brflag) || (tok == OUTBRACE && brflag))
 	    break;
-	}
 	if (tok != DSEMI)
 	    YYERRORV;
 	incasepat = 1;
 	incmdpos = 0;
 	yylex();
     }
+
+    incmdpos = 1;
+    yylex();
 
     cc->pats = (char **)alloc((n + 1) * sizeof(char *));
 


-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: zsh-3.1.4 bug, parsing case ... esac
  1998-09-03 14:51     ` Bart Schaefer
@ 1998-09-03 19:00       ` Zoltan Hidvegi
  0 siblings, 0 replies; 6+ messages in thread
From: Zoltan Hidvegi @ 1998-09-03 19:00 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

> } Actually, the shell grammar allows this, this is really a zsh bug.
> 
> Obviously, this is a surprise to me.  Can you point me at "the shell
> grammar" that specifies this?  The informal one in the man pages/info
> sure doesn't.

You can look at the Single Unix Specification -> Commands & Utilities
-> Shell Command Language -> Shell Grammar Rules:

if_clause        : If compound_list Then compound_list else_part Fi
                 | If compound_list Then compound_list           Fi
                 ;

compound_list    :              term
                 | newline_list term
                 |              term separator
                 | newline_list term separator
                 ;

term             : term separator and_or
                 |                and_or
                 ;

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline
                 ;


pipeline         :      pipe_sequence
                 | Bang pipe_sequence
                 ;

pipe_sequence    :                             command
                 | pipe_sequence '|' linebreak command
                 ;

command          : simple_command
                 | compound_command
                 | compound_command redirect_list
                 | function_definition
                 ;

compound_command : brace_group
                 | subshell
                 | for_clause
                 | case_clause
                 | if_clause
                 | while_clause
                 | until_clause
                 ;

case_clause      : Case WORD linebreak in linebreak case_list Esac
                 | Case WORD linebreak in linebreak           Esac
                 ;

There is more, but as you see, there is no required separator.
Obviously the manual and info pages are not that accurate.  People are
already complaining aboud the complicated and hard to understand
manual, a formal grammar description would be even more difficult to
read.

Zoli


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~1998-09-03 19:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-09-03  0:53 zsh-3.1.4 bug, parsing case ... esac SL Baur
1998-09-03  3:52 ` Bart Schaefer
1998-09-03  5:43   ` Zoltan Hidvegi
1998-09-03 14:51     ` Bart Schaefer
1998-09-03 19:00       ` Zoltan Hidvegi
1998-09-03 15:04     ` PATCH: 3.0.5 - " Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).