help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Why yacc_EOF is used as a list_terminator for for_command?


From: Koichi Murase
Subject: Re: Why yacc_EOF is used as a list_terminator for for_command?
Date: Wed, 12 May 2021 12:16:54 +0900

2021年5月11日(火) 3:03 Peng Yu <pengyu.ut@gmail.com>:
> > Do you have a better idea? Where would you include it? Is it worth
> > changing the current implementation which works without problems
> > currently? It's useless to change the code that actually doesn't
> > change any behavior. It may just introduce a new bug.
>
> My goal is not to change the current implementation. I am asking the
> question from the perspective of how would one implement it from
> scratch.

Do you mean you are planning to develop your own new shell? Or, you
suggest replacing the parsing engine of Bash with a completely
different one developed from scratch? Anyway, if you want to develop
the parser from scratch, you don't have to much care about the
implementation details of existing engines because the structure would
be different so the knowledge on such details can't simply be applied
to the new implementation. As you might be afraid, there are no
reasons that `parse.y' should have been written in specifically the
current way. As far as the behavior is the same, you can write in any
style you like.

> "Correct" means if you were to start from scratch and whether it is
> the best of all the possible implementation choices. (Or maybe
> "necessary" is a better word in this case.)

How do you define "best"... It depends on the person. I can understand
what you want to say; indeed yacc_EOF is unneeded in `list_terminator`
when used in the definition of `for' statement, etc. So you may
distinguish two different types of line termination:

  list_terminator_middle: '\n' | ';'
  list_terminator_general: list_terminator_middle | yacc_EOF

and then use `list_terminator_middle' for `for' statement and other
compound commands, and `list_terminator_general' for the commands
after `time' and `!'. But there can be another way of thinking.
`list_terminator' encapsulates every possible case of list/pipeline
termination, then the syntax designer doesn't need to care about the
context-dependence of the concept `list_terminator'.

----

As a similar case, suppose you design a new language and want to add
an operator `plus'. Naively we can prepare `+' operator which can be
used for various types:

  int for1, for2;
  unsigned time1, time2;
  for1 + for2; // operator+(int, int)
  time1 + time2; // operator+(unsigned, unsigned)

In this example, the meaning of operator + is overloaded:
"operator+(int, int)" | "operator+(unsigned, unsigned)".  Here you may
argue that, when we write "for1 + for2", we know from the context that
the plus never means "operator+(unsigned, unsigned)", so the
overloaded plus would be "unnecessary" and "incorrect", but it would
be "correct" to give a distinct name for each operator and use these
specialized versions any time:

  +_signed: represents "operator+(int, int)"
  +_unsigned: represents "operator+(unsigned, unsigned)

Then, you can write unambiguously "for1 +_signed for2" or "time1
+_unsigned time2". Maybe sometimes this can be useful, but most of the
time we think the overloaded single operator `+' is more useful than
the specialized versions which are explicit and "correct" in your
term.

----

Anyway, these minor representation differences of the syntax should be
eliminated in the LALR table after the compilation of bison/yacc, so
it's useless to think about "necessary" / "redundant" at the EBNF
level. The important thing is readability, which depends on the person
to some extent. I feel it is such a detail where to put yacc_EOF.

> From your writing, it seems that yacc_EOF is unnecessary in the
> for-rule.

Yes.

> If so, although having yacc_EOF for the for-rule still
> works, it could be considered "incorrect" by the above definition.

I don't think it's "incorrect". It's just a matter of preference.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]