# 構文の形式的定義

ここに yash の文法の形式的定義を示します。Yash の文法は解析表現文法で定義されます。

Yash の文法における終端記号の集合は、yash を実行する環境が扱える任意の文字の集合 (実行文字集合) です (ただしナル文字 `'\0'` を除く)。

以下は、yash の文法を構成する非終端記号とそれに対応する終端記号の一覧です。ただしここに挙げる文法の定義にはヒアドキュメントの内容とその終わりを表す行の解析のための規則は含まれていません。また POSIX 準拠モードでは構文が若干変わりますが、ここには示しません。

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

  !.