ここにプログラミング言語としてのシェルの構文定義を示します。
注
|
以下に示す構文の一部は POSIX 準拠モードでは使用できません。 |
トークン分割
入力ソースコードの文字列はまずトークンに分割されます。トークンはソースコード内のより先に現れるトークンができるだけ長くなるように分割します。一つ以上の空白 (blank) 文字の連なりはトークンを分割します。
Yash に存在する演算子トークンは以下の通りです:
&
&&
(
)
;
;;
|
||
<
<<
<&
<(
<<-
<<<
<>
>
>>
>&
>(
>>|
>|
(改行)
注
|
他の一般的なプログラミング言語とは異なり、改行演算子は空白ではなくトークンとして扱われます。 |
空白ではなく演算子トークンの一部でもない文字は単語 (word) トークンとなります。単語は以下の解析表現文法によって解析されます。
- Word
-
(WordElement / !SpecialChar .)+
- WordElement
-
\
. /
'
(!'
.)*'
/
"
QuoteElement*"
/
Parameter /
Arithmetic /
CommandSubstitution - QuoteElement
-
\
([$`"\
] / <改行>) /
Parameter /
Arithmetic /
CommandSubstitutionQuoted /
![`"\
] . - Parameter
-
$
[@*#?-$!
[:digit:]] /
$
PortableName /
$
ParameterBody - PortableName
-
![
0
-9
] [0
-9
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_
]+ - ParameterBody
-
{
ParameterNumber? (ParameterName / ParameterBody /$
ParameterBody / Arithmetic / CommandSubstitution) 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
-
$(
CompleteProgram)
/
`
CommandSubstitutionBody*`
- CommandSubstitutionQuoted
-
$(
CompleteProgram)
/
`
CommandSubstitutionBodyQuoted*`
- CommandSubstitutionBody
-
\
[$`\
] /
!`
. - CommandSubstitutionBodyQuoted
-
\
[$`\`
] /
!`
. - SpecialChar
-
[
|&;<>()`\"'
[:blank:]] / <改行>
この文法における終端記号の集合は、yash を実行する環境が扱える任意の文字の集合 (実行文字集合) です (ただしナル文字 '\0'
を除く)。
厳密には、上記の文法定義は完全な解析表現文法ではありません。CommandSubstitution (Quoted) のルールが構文定義の非終端記号である CompleteProgram に依存しているためです。
トークン分類
単語トークンが生成された後、単語はさらに IO_NUMBER トークン・予約語・名前・代入・通常の単語のどれかに分類されます。通常の単語以外の分類は、その単語が現れる文脈においてその分類のトークンが現れ得る場合のみ採用されます。予約語の一覧と予約語が認識される文脈の要件は、トークンの解析と予約語を参照してください。
トークンが数字のみから構成されていて直後に <
または >
が続くとき、それは IO_NUMBER トークンとなります。
代入 (assignment) トークンは名前 (name) とそれに続く =
で始まるトークンです:
- AssignmentWord
- AssignmentPrefix
-
Name
=
- Name
-
![[:digit:]] \[[:alnum:]
_
]+
構文
トークンが分割された後、その結果であるトークンの並びは以下に示す文脈自由文法によって解析されます。(以下、*
と +
と ?
は正規表現と同様の意味を持ちます)
- CompleteProgram
-
NL* | CompoundList
- CompoundList
-
NL* AndOrList ((
;
|&
| NL) CompleteProgram)? - AndOrList
- Pipeline
- Command
-
CompoundCommand Redirection* |
FunctionDefinition |
SimpleCommand - CompoundCommand
-
Subshell |
Grouping |
IfCommand |
ForCommand |
WhileCommand |
CaseCommand |
DoubleBracketCommand |
FunctionCommand - Subshell
-
(
CompoundList)
- Grouping
-
{
CompoundList}
- IfCommand
-
if
CompoundListthen
CompoundList (elif
CompoundListthen
CompoundList)* (else
CompoundList)?fi
- ForCommand
-
for
Name ((NL*in
Word*)? (;
| NL) NL*)?do
CompoundListdone
- WhileCommand
-
(
while
|until
) CompoundListdo
CompoundListdone
- CaseCommand
- CaseList
- CaseItem
-
(
? Word (|
Word)*)
CompleteProgram - DoubleBracketCommand
-
[[
Ors]]
- Ors
-
Ands (
||
Ands)* - Ands
-
Nots (
&&
Nots)* - Nots
-
!
* Primary - Primary
-
(
-b
|-c
|-d
|-e
|-f
|-G
|-g
|-h
|-k
|-L
|-N
|-n
|-O
|-o
|-p
|-r
|-S
|-s
|-t
|-u
|-w
|-x
|-z
) Word |
Word (-ef
|-eq
|-ge
|-gt
|-le
|-lt
|-ne
|-nt
|-ot
|-veq
|-vge
|-vgt
|-vle
|-vlt
|-vne
|=
|==
|===
|=~
|!=
|!==
|<
|>
) Word |
(
Ors)
|
Word - FunctionCommand
-
function
Word ((
)
)? NL* CompoundCommand Redirection* - FunctionDefinition
-
Name
(
)
NL* CompoundCommand Redirection* - SimpleCommand
-
(Assignment | Redirection) SimpleCommand? |
Word (Word | Redirection)* - Assignment
-
AssignmentWord |
AssignmentPrefix(
NL* (Word NL*)*)
- Redirection
-
IO_NUMBER? RedirectionOperator Word |
IO_NUMBER?<(
CompleteProgram)
|
IO_NUMBER?>(
CompleteProgram)
- RedirectionOperator
-
<
|<>
|>
|>|
|>>
|>>|
|<&
|>&
|<<
|<<-
|<<<
- NL
-
<改行>
ルール Primary では、Word トークンは ]]
に一致してはなりません。また、Primary が Word トークンで始まる場合にはその Word は同ルールで認められている単項演算子に一致してはなりません。
ルール SimpleCommand では、Word トークンはそれが Assignment の始まりとは解釈できない場合にのみ採用されます。
ルール Assignment では、AssignmentPrefix と (
の間に空白を置くことはできません。
上記の文法定義にはヒアドキュメントの内容とその終わりを表す行の解析のための規則は含まれていません。それらは対応するリダイレクト演算子の後にある最初の改行 (NL) トークンが解析された直後に解析されます。
エイリアス置換
単語はエイリアス置換の対象となります。
-
単語が SimpleCommand の Word として解析されようとした時に、通常のエイリアス及びグローバルエイリアスを対象として置換が試みられます。
-
置換結果が空白文字 (blank) で終わるエイリアス置換の次に単語トークンがある場合、その単語も通常のエイリアス及びグローバルエイリアスを対象として置換が試みられます。
-
その他の単語は、グローバルエイリアスのみを対象として置換が試みられます。(POSIX 準拠モードを除く)
予約語に分類されたトークンはエイリアス置換の対象からは除外されます。