# Formal definition of command syntax

This chapter defines the syntax of shell commands as a parsing expression grammar.

The set of terminals of the grammar is the set of characters that can be handled on the environment in which the shell is run (a.k.a. execution character set), with the exception that the set does not contain the null character (`'\0'`).

Below is a list of nonterminals of the grammar with corresponding parsing expressions. The list does not include rules for parsing contents and ends of here documents. In the POSIXly-correct mode, the grammar varies from the list below to disable non-POSIX functionalities.

CompleteCommand

  Sequence EOF

Sequence

  N* List*

List

  Pipeline ((`&&` / `||`) N* Pipeline)* ListSeparator

Pipeline

  Bang? Command (`|` N* Command)*

Command

  CompoundCommand Redirection* /
  !R FunctionDefinition /
  !R SimpleCommand

CompoundCommand

  Subshell /
  Grouping /
  IfCommand /
  ForCommand /
  WhileCommand /
  CaseCommand /
  FunctionCommand

Subshell

  `(` Sequence `)` S*

Grouping

  LeftBrace Sequence RightBrace

IfCommand

  If Sequence Then Sequence (Elif Sequence Then Sequence)* (Else Sequence)? Fi

ForCommand

  For Name S* Separator? (In Word* Separator)? Do Sequence Done

WhileCommand

  (While / Until) Sequence Do Sequence Done

CaseCommand

  Case Word N* In N* CaseItem* Esac

CaseItem

  !Esac (`(` S*)? Word (`|` S* Word)* `)` Sequence (`;;` / &Esac)

FunctionCommand

  Function Word (`(` S* `)`)? N* CompoundCommand Redirection*

FunctionDefinition

  Name S* `(` S* `)` N* CompoundCommand Redirection*

SimpleCommand

  &(Word / Redirection) (Assignment / Redirection)* (Word / Redirection)*

Assignment

  Name `=` Word /
  Name `=(` N* (Word N*)* `)`

Name

  ![[:digit:]] [[:alnum:] `_`]+

PortableName

  ![`0`-`9`] [`0`-`9` `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_`]+

Word

  (WordElement / !SpecialChar .)+ S*

WordElement

  `\` . /
  `'` (!`'` .)* `'` /
  `"` QuoteElement* `"` /
  Parameter /
  Arithmetic /
  CommandSubstitution

QuoteElement

  `\` ([`$`"\`] / NL) /
  Parameter /
  Arithmetic /
  CommandSubstitution /
  ![``"\`] .

Parameter

  `$` [`@*#?-$!` [:digit:]] /
  `$` PortableName /
  `$` ParameterBody

ParameterBody

  `{` ParameterNumber? (ParameterName / ParameterBody / Parameter) ParameterIndex? ParameterMatch? `}`

ParameterNumber

  `#` ![`+=:/%`] !([`-?#`] `}`)

ParameterName

  [`@*#?-$!`] /
  [[:alnum:] `_`]+

ParameterIndex

  `[` ParameterIndexWord (`,` ParameterIndexWord)? `]`

ParameterIndexWord

  (WordElement / ![`"'],`] .)+

ParameterMatch

  `:`? [`-+=?`] ParameterMatchWord /
  (`#` / `##` / `%` / `%%`) ParameterMatchWord /
  (`:/` / `/` [`#%/`]?) ParameterMatchWordNoSlash (`/` ParameterMatchWord)?

ParameterMatchWord

  (WordElement / ![`"'}`] .)*

ParameterMatchWordNoSlash

  (WordElement / ![`"'/}`] .)*

Arithmetic

  `$((` ArithmeticBody* `))`

ArithmeticBody

  `\` . /
  Parameter /
  Arithmetic /
  CommandSubstitution /
  `(` ArithmeticBody `)` /
  ![``()`] .

CommandSubstitution

  `$(` Sequence `)` /
  ``` CommandSubstitutionBody* ```

CommandSubstitutionBody

  `\` [`$`\`] /
  !``` .

Redirection

  RedirectionFD RedirectionOperator S* Word /
  RedirectionFD `<(` Sequence `)` /
  RedirectionFD `>(` Sequence `)`

RedirectionFD

  [[:digit:]]*

RedirectionOperator

  `<` / `<>` / `>` / `>|` / `>>` / `>>|` / `<&` / `>&` / `<<` / `<<-` / `<<<`

ListSeparator

  Separator /
  `&` N* /
  &`)` /
  &`;;`

Separator

  `;` N* /
  N+ /
  EOF

N

  S* NL

S

  [[:blank:]] /
  Comment

Comment

  `#` (!NL .)*

R

  Bang / LeftBrace / RightBrace / Case / Do / Done / Elif / Else / Esac / Fi / For / If / In / Then / Until / While

Bang

  `!` D

LeftBrace

  `{` D

RightBrace

  `}` D

Case

  `case` D

Do

  `do` D

Done

  `done` D

Elif

  `elif` D

Else

  `else` D

Esac

  `esac` D

Fi

  `fi` D

For

  `for` D

Function

  `function` D

If

  `if` D

In

  `in` D

Then

  `then` D

Until

  `until` D

While

  `while` D

D

  !Word S*

SpecialChar

  [`|&;<>()`\"'` [:blank:]] / NL

NL

  <newline>

EOF

  !.