Dlaczego grupa poleceń nawias klamrowy potrzebuje spacji po nawiasie otwierającym w gramatyce powłoki POSIX?


10

TL; DR : Dlaczego grupa nawiasów POSIX potrzebuje spacji po {zarezerwowanym słowie, a podpowłoka nie po zarezerwowanym słowie (?

Gramatyka powłoki POSIX definiuje grupę nawiasów i podpowłokę w następujący sposób

brace_group      : Lbrace compound_list Rbrace

subshell         : '(' compound_list ')'

Teraz, jeśli czytamy to dosłownie, spacje są znaczące. Oznaczałoby to, że musi istnieć przestrzeń otwierająca i zamykająca nawias klamrowy i nawias jak w

{ echo hello world; }

( echo hello world )

Spowodowałoby to również dostosowanie do definicji poleceń złożonych :

Każde z tych poleceń złożonych ma na początku zarezerwowane słowo lub operator sterujący, a na końcu odpowiednie zarezerwowane słowo lub operator terminatora.

Jednak to, co nie ma sensu, to dlaczego (list)i ( list )działa dobrze (ta przestrzeń po (nie jest wymagana), jednak rozwijanie nawiasów musi mieć wiodącą przestrzeń, tzn. {echo hello;}Nie działa.

Oczywiście słowo zastrzeżone traktowane jako słowo powłoki miałoby sens później potrzebując spacji, aby dostosować się do koncepcji podziału pola , jednak sama definicja nie wspomina o spacjach. Ponadto, jeśli {i (oba są uważane za słowa zastrzeżone według definicji POSIX polecenia złożonego, dlaczego są traktowane inaczej w odniesieniu do znaku spacji po tych zastrzeżonych słowach? Teraz instrukcja ksh (1) zawiera:

Słowa, które są sekwencjami znaków, są rozdzielane niecytowanymi białymi znakami (spacja, tabulator i nowa linia) lub metaznakami (<,>, |,;, &, (i))

Innymi słowy, sensowne jest, aby ksh rozpoznał (jako separator słów, gdzie pierwsze słowo byłoby poleceniem lub przypisaniem zmiennej. POSIX jednak nie pojawia się (jako meta-znak. Jedynym możliwym wyjaśnieniem, które znalazłem, jeśli chodzi o gramatykę POSIX, jest to, że {jest uważane za „token”, gdzie (nie ma go jako jednego.

/* These are reserved words, not operator tokens, and are
   recognized when reserved words are recognized. */


%token  Lbrace    Rbrace    Bang
/*      '{'       '}'       '!'   */

Jakie byłoby dokładne uzasadnienie tej rozbieżności?

Zaakceptowane uwagi do odpowiedzi:

  • Przeniesiono zaakceptowany znacznik na odpowiedź Izaaka, ponieważ zawiera on sam formularz , który bezpośrednio odpowiada na moje pytanie:

    Na przykład „(” i „)” są operatorami sterującymi, więc nie <space>są potrzebne w (liście). Jednak „{” i „}” są słowami zastrzeżonymi w {list;}, więc w tym przypadku wiodące <space>i <semicolon>są wymagane.

  • Akceptacja odpowiedzi Kusalanandy . Odpowiedź Kusalanandy dotyczy tego, czego potrzebowałem, choć głównie z nieformalnego i intuicyjnego punktu widzenia; wskazuje, że {to słowo zastrzeżone i (jest operatorem. Michael Homer zauważył również to samo w komentarzach - że definicja Compound Command stwierdza (wyróżnienie dodane):

    Każda z tych złożonych poleceń ma słowa zastrzeżonego lub operatora kontroli na początku

  • {są zdefiniowane jako słowo zastrzeżone, podobne do forlub while, wymienione w gramatyce powłoki (patrz ostatni blok kodu w pytaniu)

  • Sekcja 2.9 stanowi (wyróżnienie dodane):

    W szczególności reprezentacje obejmują odstępy między tokenami w niektórych miejscach, w których <blank>s nie byłoby konieczne (gdy jeden z tokenów jest operatorem).

  • Chociaż standard nie definiuje wyraźnie (jako operatora, (jest nazywany operatorem; konkretnie, sekcja 2.9.2 mówi

    Jeśli potok zaczyna się od słowa zarezerwowanego! a polecenie1 jest poleceniem podpowłoki, aplikacja powinna dopilnować, aby (operator na początku polecenia 1 był oddzielony od! jednym lub kilkoma znakami. Zachowanie słowa zarezerwowanego! bezpośrednio po nim (operator nie jest określony.

  • Pytanie o przepełnienie stosu przez Digital Trauma wskazuje na sekcję 2.4 dotyczącą słów zastrzeżonych:

    Rozpoznanie to nastąpi tylko wtedy, gdy żaden z tych znaków nie jest cytowany i gdy słowo jest użyte jako:

    - Pierwsze słowo polecenia

  • Jak wspomniano w odpowiedzi Kusalanandy: „Spacje pokazane w gramatyce POSIX nie są spacjami, które muszą znajdować się w danych wejściowych powłoki, ale jedynie sposobem wyświetlania samej gramatyki. Fakt, że nawiasy klamrowe są zastrzeżonymi słowami, sugeruje, że muszą być otoczone białymi spacjami ”. Jak wspomniał Michael Homer w komentarzach:„ Gdyby przestrzenie były znaczące same w sobie, musiałyby zostać wymienione w produkcji

Sprawa zamknięta.


3
Jeśli miejsca same w sobie były znaczące, musiałyby zostać wymienione w produkcji.
Michael Homer

2
„Ponadto, jeśli {i (oba są uważane za słowa zastrzeżone według definicji POSIX polecenia złożonego”, por. „Każde z tych poleceń złożonych ma na początku zarezerwowane słowo lub operator sterujący ”.
Michael Homer

2
@SergiyKolodyazhnyy Uważam, że ma na myśli, że gdyby przestrzeń była znacząca, gramatyka musiałaby zawierać wyraźny znak spacji ( ' '). Zamiast tego, spacje są implikowane przez to, jakie tokeny są słowami.
Kusalananda

2
Definicja specyfikacji klasy tokena jest ... co najmniej niezręczna. Cała gramatyka jest dość okropna, a specyfikacja miesza definiowanie rzeczy w prozie w tekście (czasem pośrednio!), W regułach prozy poprzedzających gramatykę i w samej gramatyce. Jest to niezrozumiałe, jeśli nie znasz odpowiedzi i pracujesz wstecz. Reguły leksykalne są zdefiniowane wstecz, według tego, co zaczyna nowy token, zamiast opisywania, co zawiera token. Wokoło jest tylko bałagan.
Michael Homer

1
@Sergiy w gramatyce formalnej produkcja (lub reguła produkcyjna) opisuje, w jaki sposób można wygenerować coś z czegoś innego. Zobacz en.wikipedia.org/wiki/Production_%28computer_science%29 Więc command : simple_command | compound_command | compound_command redirect_list | function_definition ;jest to produkcja, która mówi, gdzie możesz mieć komendę, może to być jedna z prostych komend, komenda złożona lub komenda złożona z przekierowaniem lub definicja funkcji.
muru

Odpowiedzi:


6

Jest to ograniczenie sposobu, w jaki powłoka dzieli linie na tokeny.

Powłoka odczytuje wiersze z pliku wejściowego i zgodnie z sekcją 2 „Wprowadzenie do powłoki” konwertuje je na słowo lub operator :

  1. Powłoka dzieli dane wejściowe na tokeny: słowa i operatory

{to słowo zastrzeżone

Niektóre słowa są słowami zastrzeżonymi

Słowa zastrzeżone to słowa, które mają specjalne znaczenie dla powłoki. Następujące słowa zostaną uznane za słowa zastrzeżone:

! { } case do done elif else esac fi for if in then until while

Słowa, które należy rozpoznać jako słowa, muszą być rozdzielane .

Zastrzeżone słowa są rozpoznawane tylko wtedy, gdy są rozdzielane ...

Głównie według pustych miejsc (punkt 7) i operatorów.

  1. Jeśli bieżącym znakiem jest <nieużywany>, każdy token zawierający poprzedni znak jest rozdzielany, a obecny znak należy odrzucić.

(jest operatorem

Operatorzy stoją sami :

podczas gdy operatorzy sami są ogranicznikami.

Gdzie „operatorzy” to :

3.260 Operator

W języku poleceń powłoki operator sterujący lub operator przekierowania .

Operatory przekierowania to :

Operator przekierowania

W języku poleceń powłoki: token pełniący funkcję przekierowania. Jest to jeden z następujących symboli:

<     >     >|     <<     >>     <&     >&     <<-     <>

Operatorzy sterujący to :

3.113 Operator sterowania

W języku poleceń powłoki: token pełniący funkcję kontrolną. Jest to jeden z następujących symboli:

&   &&   (   )   ;   ;;   newline   |   ||

Wniosek

Zatem „(” i „)” są operatorami sterującymi, a „{” „}” to słowa zastrzeżone.

Dokładny opis twojego pytania znajduje się w specyfikacji :

Na przykład „(” i „)” są operatorami sterującymi, więc w <list> nie jest wymagane użycie <spacji>. Jednak „{” i „}” są słowami zastrzeżonymi w {list;}, więc w tym przypadku wymagane są początkowe <space> i <semicolon>.

Co dokładnie wyjaśnia, dlaczego spacja (lub inny separator) jest wymagana po {.

Jest to ważne:

{ echo yes;}

Jak to jest:

{(echo yes);}

To:

{(echo yes)}

Lub nawet to:

{>/dev/tty echo yes;}

Cóż, ostatni cytat jest dokładnie na miejscu! + 1'ed. Muszę teraz przejrzeć pytanie i odpowiedzi
Sergiy Kolodyazhnyy

13

Różnica między klamrami oraz nawiasach podano, że szelki (i !) są zarezerwowane słowa, podobnie jak for, if, thenitd., Podczas gdy nawiasy są operatorzy kontroli. Słowa muszą być oddzielone spacjami.

Oznacza to, że tak jak ty nie możesz mieć

foriin*; do

nie możesz mieć

{somecommand;} >file

lub

if !somecommand; then

Spacje pokazane w gramatyce POSIX nie są spacjami, które muszą znajdować się w danych wejściowych powłoki, ale po prostu sposobem wyświetlania samej gramatyki. Fakt, że nawiasy klamrowe są zastrzeżonymi słowami , oznacza, że ​​muszą być otoczone białymi spacjami, podczas gdy nawiasy podpowłoki nie.


1
Cóż, wydaje się, że prawie na to odpowiada i widzę, że mówi: „W szczególności reprezentacje obejmują odstępy między tokenami w niektórych miejscach, w których <puste pola nie byłyby konieczne (gdy jeden z tokenów jest operatorem)”. Tylko jedno pytanie: gdzie standard definiuje się (jako operator? Nie ma go przynajmniej w dziale gramatyki
Sergiy Kolodyazhnyy

@MichaelHomer Ah, „operator sterowania”, tak jak ;. Dziękuję za to.
Kusalananda

Operatory sterujące są wymienione na górze strony podręcznika w obszarze DEFINICJE. Możemy patrzeć na to, ()że operatory kontrolne, jak |w tym przypadku, obejmują podpowłoki. I { }pracuje w bieżącej powłoki i nie może obejmować podpowłoce.
glenn jackman

@Kusalananda znalazł to, sekcja 2.9.2: „Jeśli potok zaczyna się od słowa zarezerwowanego! A polecenie1 jest poleceniem podpowłoki, aplikacja zapewnia, aby (operator na początku polecenia1 był oddzielony od! Jednym lub więcej < puste> znaki. Zachowanie słowa zarezerwowanego! bezpośrednio po nim (operator nie jest określony. "Nie jest to jednoznaczna definicja, ale standard nazywa go (operatorem
Sergiy Kolodyazhnyy

@glennjackman Chociaż prawdą jest, że potoki zawierają podpowłoki, nie jest to typ definicji, która wydaje się odpowiednia. Standard wspomina również, że w niektórych implementacjach potok może działać w bieżącym środowisku wykonywania powłoki (i wiem, że jest w standardzie, ponieważ widziałem tekst wczoraj i szukam go teraz). Jednak twoja sugestia skłoniła mnie do znalezienia cytatu, który skomentowałem powyżej, w którym przynajmniej standard nazywa go operatorem, chociaż nie definiuje go jednoznacznie
Sergiy Kolodyazhnyy
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.