syntax(sh): Improve the recognition of bracket expressions

Commit: 
https://github.com/vim/vim/commit/48fa3198b7118023fea4b15015a97c920887eb07
Author: Aliaksei Budavei <0x000...@gmail.com>
Date:   Mon Dec 30 10:23:50 2024 +0100

    syntax(sh): Improve the recognition of bracket expressions
    
    - Define a general non-"contained" "shBracketExpr" group,
      and replace with it the "contained" bracket variant of
      "shOperator", adjusting the patterns for the competing
      conditional commands "[" and "[[".
    - Accommodate some unbalanced brackets (e.g. "[!][!]").
    - Make the leading "!" (or "^") stand out in NON-matching
      bracket expressions.
    - Support literal newlines in parametric patterns (along
      with pathname globbings and "case" patterns).
    - Also match bracket expressions in:
      * parametric patterns (e.g. "${1#[ab]_}");
      * pathname globbings (e.g. "[ab]*.txt");
      * arguments for the "[[", "echo", and "print" commands.
    - Recognise collating symbols (e.g. "[.a.]") and equivalence
      classes (e.g. "[=a=]").
    - Recognise end patterns for a pattern substitution form of
      parameter expansion and match bracket expressions in such
      patterns (e.g. "${1/%[.!]/;}").
    
    fixes #15799
    closes: #15941
    
    References:
    
https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap09.html#tag_09_03_05
    
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_14
    
https://git.savannah.gnu.org/gitweb/?p=bash.git;a=blob_plain;f=doc/bash.html;hb=37b7e91d64ad10b1a1815d12128c9475636df670
    http://www.mirbsd.org/htman/i386/man1/mksh.htm
    
    Signed-off-by: Aliaksei Budavei <0x000...@gmail.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/syntax/sh.vim b/runtime/syntax/sh.vim
index 97e74d205..0a8fb47b7 100644
--- a/runtime/syntax/sh.vim
+++ b/runtime/syntax/sh.vim
@@ -4,6 +4,7 @@
 " Previous Maintainers:        Charles E. Campbell
 "              Lennart Schultz <lennart.schu...@ecmwf.int>
 " Last Change:         2024 Mar 04 by Vim Project
+"              2024 Nov 03 by Aliaksei Budavei <0x000c70 AT gmail DOT com> 
(improved bracket expressions, #15941)
 " Version:             208
 " Former URL:          http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
 " For options and settings, please use:      :help ft-sh-syntax
@@ -127,6 +128,50 @@ else
  com! -nargs=* ShFoldIfDoFor <args>
 endif
 
+" Generate bracket expression items {{{1
+" =================================
+" Note that the following function can be invoked as many times as necessary
+" provided that these constraints hold for the passed dictionary argument:
+" - every time a unique group-name value is assigned to the "itemGroup" key;
+" - only ONCE either the "extraArgs" key is not entered or it is entered and
+"   its value does not have "contained" among other optional arguments (":help
+"   :syn-arguments").
+fun! s:GenerateBracketExpressionItems(dict) abort
+ let itemGroup = a:dict.itemGroup
+ let bracketGroup = a:dict.bracketGroup
+ let invGroup = itemGroup . 'Inv'
+ let skipLeftBracketGroup = itemGroup . 'SkipLeftBracket'
+ let skipRightBracketGroup = itemGroup . 'SkipRightBracket'
+ let extraArgs = has_key(a:dict, 'extraArgs') ? a:dict.extraArgs : ''
+
+ " Make the leading "[!^]" stand out in a NON-matching expression.
+ exec 'syn match ' . invGroup . ' contained "\[\@<=[!^]"'
+
+ " Set up indirections for unbalanced-bracket highlighting.
+ exec 'syn region ' . skipRightBracketGroup . ' contained matchgroup=' . 
bracketGroup . ' start="\[\%([!^]\=\\=\]\)\@=" matchgroup=shCollSymb 
end="\[\.[^]]\{-}\][^]]\{-}\.\]" matchgroup=' . itemGroup . ' end="\]" 
contains=@shBracketExprList,shDoubleQuote,' . invGroup
+ exec 'syn region ' . skipLeftBracketGroup . ' contained matchgroup=' . 
bracketGroup . ' start="\[\%([!^]\=\\=\]\)\@=" 
skip="[!^]\=\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\%(\[[:.=]\@!\)\@=" matchgroup=' . 
itemGroup . ' end="\[[:.=]\@!" contains=@shBracketExprList,shDoubleQuote,' . 
invGroup
+
+ " Look for a general matching expression.
+ exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' 
start="\[\S\@=" end="\]" contains=@shBracketExprList,shDoubleQuote ' . extraArgs
+ " Look for a general NON-matching expression.
+ exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' 
start="\[[!^]\@=" end="\]" contains=@shBracketExprList,shDoubleQuote,' . 
invGroup . ' ' . extraArgs
+
+ " Accommodate unbalanced brackets in bracket expressions.  The supported
+ " syntax for a plain "]" can be: "[]ws]" and "[^]ws]"; or, "[ws[.xs]ys.]zs]"
+ " and "[^ws[.xs]ys.]zs]"; see ยง9.3.5 RE Bracket Expression (in XBD).
+ exec 'syn region ' . itemGroup . ' matchgroup=NONE start="\[[!^]\=\\=\]" 
matchgroup=' . bracketGroup . ' end="\]" 
contains=@shBracketExprList,shDoubleQuote,' . skipRightBracketGroup . ' ' . 
extraArgs
+ " Strive to handle "[]...[]" etc.
+ exec 'syn region ' . itemGroup . ' matchgroup=NONE 
start="\[[!^]\=\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\[[:.=]\@!" matchgroup=' . 
bracketGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . 
skipLeftBracketGroup . ' ' . extraArgs
+
+ if !exists("g:skip_sh_syntax_inits")
+  exec 'hi def link ' . skipLeftBracketGroup . ' ' . itemGroup
+  exec 'hi def link ' . skipRightBracketGroup . ' ' . itemGroup
+  exec 'hi def link ' . invGroup . ' Underlined'
+ endif
+endfun
+
+call s:GenerateBracketExpressionItems({'itemGroup': 'shBracketExpr', 
'bracketGroup': 'shBracketExprDelim'})
+
 " sh syntax is case sensitive {{{1
 syn case match
 
@@ -136,23 +181,24 @@ syn cluster shErrorList   
contains=shDoError,shIfError,shInError,shCaseError,shEsa
 if exists("b:is_kornshell") || exists("b:is_bash")
  syn cluster ErrorList add=shDTestError
 endif
-syn cluster shArithParenList   
contains=shArithmetic,shArithParen,shCaseEsac,shComment,shDeref,shDo,shDerefSimple,shEcho,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shExDoubleQuote,shHereString,shRedir,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen,bashSpecialVariables,bashStatement,shIf,shFor,shFunctionKey,shFunctionOne,shFunctionTwo
+syn cluster shArithParenList   
contains=shArithmetic,shArithParen,shCaseEsac,shComment,shDeref,shDerefVarArray,shDo,shDerefSimple,shEcho,shEscape,shExpr,shNumber,shOperator,shPosnParm,shExSingleQuote,shExDoubleQuote,shHereString,shRedir,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen,bashSpecialVariables,bashStatement,shIf,shFor,shFunctionKey,shFunctionOne,shFunctionTwo
 syn cluster shArithList        contains=@shArithParenList,shParenError
+syn cluster shBracketExprList  
contains=shCharClassOther,shCharClass,shCollSymb,shEqClass
 syn cluster shCaseEsacList     
contains=shCaseStart,shCaseLabel,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq,@shErrorList,shStringSpecial,shCaseRange
 syn cluster shCaseList 
contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shComment,shDblBrace,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
 if exists("b:is_kornshell") || exists("b:is_bash")
  syn cluster shCaseList        add=shForPP,shDblParen
 endif
-syn cluster shCommandSubList   
contains=shAlias,shArithmetic,shCmdParenRegion,shCommandSub,shComment,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
+syn cluster shCommandSubList   
contains=shAlias,shArithmetic,shBracketExpr,shCmdParenRegion,shCommandSub,shComment,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
 syn cluster shCurlyList        
contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
 " COMBAK: removing shEscape from shDblQuoteList fails ksh04:43 -- Jun 09, 
2022: I don't see the problem with ksh04, so am reinstating shEscape
 syn cluster shDblQuoteList     
contains=shArithmetic,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shDeref,shDerefSimple,shEscape,shPosnParm,shCtrlSeq,shSpecial,shSpecialDQ
 syn cluster shDerefList        
contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPSR,shDerefPPS
 syn cluster shDerefVarList     
contains=shDerefOffset,shDerefOp,shDerefVarArray,shDerefOpError
-syn cluster shEchoList 
contains=shArithmetic,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shDeref,shDerefSimple,shEscape,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
-syn cluster shExprList1        
contains=shCharClass,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
+syn cluster shEchoList 
contains=shArithmetic,shBracketExpr,shCommandSub,shCommandSubBQ,shDerefVarArray,shSubshare,shValsub,shDeref,shDerefSimple,shEscape,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
+syn cluster shExprList1        
contains=shBracketExpr,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
 syn cluster shExprList2        contains=@shExprList1,@shCaseList,shTest
-syn cluster shFunctionList     
contains=@shCommandSubList,shCaseEsac,shColon,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
+syn cluster shFunctionList     
contains=shBracketExpr,@shCommandSubList,shCaseEsac,shColon,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
 if exists("b:is_kornshell") || exists("b:is_bash")
  syn cluster shFunctionList    add=shRepeat,shDblBrace,shDblParen,shForPP
  syn cluster shDerefList       add=shCommandSubList,shEchoDeref
@@ -160,16 +206,16 @@ endif
 syn cluster shHereBeginList    contains=@shCommandSubList
 syn cluster shHereList contains=shBeginHere,shHerePayload
 syn cluster shHereListDQ       
contains=shBeginHere,@shDblQuoteList,shHerePayload
-syn cluster shIdList   
contains=shArithmetic,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shWrapLineOperator,shSetOption,shComment,shDeref,shDerefSimple,shHereString,shNumber,shOperator,shRedir,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial,shAtExpr
+syn cluster shIdList   
contains=shArithmetic,shCommandSub,shCommandSubBQ,shDerefVarArray,shSubshare,shValsub,shWrapLineOperator,shSetOption,shComment,shDeref,shDerefSimple,shHereString,shNumber,shOperator,shRedir,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial,shAtExpr
 syn cluster shIfList   
contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey,shFunctionOne,shFunctionTwo
 syn cluster shLoopList 
contains=@shCaseList,@shErrorList,shCaseEsac,shConditional,shDblBrace,shExpr,shFor,shIf,shOption,shSet,shTest,shTestOpr,shTouch
 if exists("b:is_kornshell") || exists("b:is_bash")
  syn cluster shLoopList        add=shForPP,shDblParen
 endif
-syn cluster shPPSLeftList      
contains=shAlias,shArithmetic,shCmdParenRegion,shCommandSub,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
+syn cluster shPPSLeftList      
contains=shAlias,shArithmetic,shBracketExpr,shCmdParenRegion,shCommandSub,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
 syn cluster shPPSRightList     
contains=shDeref,shDerefSimple,shEscape,shPosnParm
-syn cluster shSubShList        
contains=@shCommandSubList,shCommandSubBQ,shSubshare,shValsub,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator
-syn cluster shTestList 
contains=shArithmetic,shCharClass,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shSpecialDQ,shExDoubleQuote,shExpr,shExSingleQuote,shNumber,shOperator,shSingleQuote,shTest,shTestOpr
+syn cluster shSubShList        
contains=shBracketExpr,@shCommandSubList,shCommandSubBQ,shSubshare,shValsub,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator
+syn cluster shTestList 
contains=shArithmetic,shBracketExpr,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shSpecialDQ,shExDoubleQuote,shExpr,shExSingleQuote,shNumber,shOperator,shSingleQuote,shTest,shTestOpr
 syn cluster shNoZSList contains=shSpecialNoZS
 syn cluster shForList  
contains=shTestOpr,shNumber,shDerefSimple,shDeref,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shArithmetic
 
@@ -190,7 +236,7 @@ endif
 syn match  shEchoQuote contained       '\%(\\\)*\["`'()]'
 
 " This must be after the strings, so that ... \" will be correct
-syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" 
skip="\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 
end="\d[<>]"me=e-2 end="\s#"me=e-2 
contains=shNumber,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shOperator,shExDoubleQuote,shDoubleQuote,shCharClass,shCtrlSeq
+syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" 
skip="\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 
end="\d[<>]"me=e-2 end="\s#"me=e-2 
contains=shBracketExpr,shNumber,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shOperator,shExDoubleQuote,shDoubleQuote,shCtrlSeq
 
 " Alias: {{{1
 " =====
@@ -240,7 +286,6 @@ syn match      shRedir      "\d<<-\="
 " ==========
 syn match   shOperator "<<\|>>"                contained
 syn match   shOperator "[!&;|]"                contained
-syn match   shOperator "\[[[^:]\|\]]"          contained
 syn match   shOperator "[-=/*+%]\=="           skipwhite nextgroup=shPattern
 syn match   shPattern  "\<\S\+\())\)\@="       contained 
contains=shExSingleQuote,shSingleQuote,shExDoubleQuote,shDoubleQuote,shDeref
 
@@ -251,9 +296,9 @@ syn region shSubSh transparent matchgroup=shSubShRegion 
start="[^(]\zs(" end=")"
 
 " Tests: {{{1
 "=======
-syn region shExpr      matchgroup=shRange start="\[" skip=+\\\|\$\|\[+ 
end="\]" contains=@shTestList,shSpecial
+syn region shExpr      matchgroup=shRange start="\[\s\@=" skip=+\\\|\$\|\[+ 
end="\]" contains=@shTestList,shSpecial
 syn region shTest      transparent matchgroup=shStatement start="\<test\s" 
skip=+\\\|\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
-syn region shNoQuote   start='\S'      skip='\%(\\\)*\.'       end='\ze\s' 
end="\ze['"]"       contained contains=shDerefSimple,shDeref
+syn region shNoQuote   start='\S'      skip='\%(\\\)*\.'       end='\ze\s' 
end="\ze['"]"       contained contains=shBracketExpr,shDerefSimple,shDeref
 syn match  shAstQuote  contained       '\*\ze"'        nextgroup=shString
 syn match  shTestOpr   contained       '[^-+/%]\zs=' skipwhite 
nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
 syn match  shTestOpr   contained       
"<=\|>=\|!=\|==\|=\~\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
@@ -262,13 +307,16 @@ syn region shTestDoubleQuote      contained       
start='\%(\%(\\\)*\\)\@<!"' skip=+\\
 syn match  shTestSingleQuote   contained       '\.'    
nextgroup=shTestSingleQuote
 syn match  shTestSingleQuote   contained       "'[^']*'"
 if exists("b:is_kornshell") || exists("b:is_bash")
- syn region  shDblBrace matchgroup=Delimiter start="\[\["      
skip=+\%(\\\)*\$+ end="\]\]"    
contains=@shTestList,shAstQuote,shNoQuote,shComment
+ syn region  shDblBrace matchgroup=Delimiter start="\[\[\s\@=" 
skip=+\%(\\\)*\$+ end="\]\]"    
contains=@shTestList,shAstQuote,shNoQuote,shComment
  syn region  shDblParen matchgroup=Delimiter start="(("        
skip=+\%(\\\)*\$+ end="))"      contains=@shTestList,shComment
 endif
 
 " Character Class In Range: {{{1
 " =========================
+syn match   shCharClassOther   contained       "\[:\w\{-}:\]"
 syn match   shCharClass        contained       
"\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
+syn match   shCollSymb contained       "\[\..\{-}\.\]"
+syn match   shEqClass  contained       "\[=.\{-}=\]"
 
 " Loops: do, if, while, until {{{1
 " ======
@@ -298,7 +346,7 @@ syn match  shComma     contained    ","
 " ====
 syn match shCaseBar    contained skipwhite "\(^\|[^\]\)\(\\\)*\zs|"            
nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
 syn match shCaseStart  contained skipwhite skipnl "("                  
nextgroup=shCase,shCaseBar
-syn match shCaseLabel  contained skipwhite     "\%(\.\|[-a-zA-Z0-9_*.]\)\+"    
contains=shCharClass
+syn match shCaseLabel  contained skipwhite     "\%(\.\|[-a-zA-Z0-9_*.]\)\+"    
contains=shBracketExpr
 if exists("b:is_bash")
  ShFoldIfDoFor syn region      shCase  contained skipwhite skipnl 
matchgroup=shSnglCase start="\%(\.\|[^#$()'"         ]\)\{-}\zs)"  end=";;" 
end=";&" end=";;&" end="esac"me=s-1      contains=@shCaseList    
nextgroup=shCaseStart,shCase,shComment
 elseif exists("b:is_kornshell")
@@ -317,11 +365,9 @@ endif
 syn region  shCaseSingleQuote  matchgroup=shQuote start=+'+ end=+'+            
contains=shStringSpecial                skipwhite skipnl nextgroup=shCaseBar    
contained
 syn region  shCaseDoubleQuote  matchgroup=shQuote start=+"+ skip=+\\\|\.+ 
end=+"+      contains=@shDblQuoteList,shStringSpecial        skipwhite skipnl 
nextgroup=shCaseBar    contained
 syn region  shCaseCommandSub   start=+`+ skip=+\\\|\.+ end=+`+         
contains=@shCommandSubList              skipwhite skipnl nextgroup=shCaseBar    
contained
+call s:GenerateBracketExpressionItems({'itemGroup': 'shCaseRange', 
'bracketGroup': 'shBracketExprDelim', 'extraArgs': 'skip=+\\+ contained'})
 if exists("b:is_bash")
- syn region  shCaseRange       matchgroup=Delimiter start=+\[+ skip=+\\+ 
end=+\]+      contained       contains=shCharClass
  syn match   shCharClass       
'\[:\%(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|or\|xdigit\):\]'
                       contained
-else
- syn region  shCaseRange       matchgroup=Delimiter start=+\[+ skip=+\\+ 
end=+\]+      contained
 endif
 " Misc: {{{1
 "======
@@ -453,7 +499,18 @@ endif
 "=============
 syn match  shSetOption "\s\zs[-+][a-zA-Z0-9]\+\>"      contained
 syn match  shVariable  "\<\h\w*\ze="                   nextgroup=shVarAssign
-syn match  shVarAssign "="             contained       
nextgroup=shCmdParenRegion,shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
+if exists("b:is_bash")
+ " The subscript form for array values, e.g. "foo=([2]=10 [4]=100)".
+ syn region shArrayValue       contained       start="\[\%(..\{-}\]=\)\@=" 
end="\]=\@="        contains=@shArrayValueList nextgroup=shVarAssign
+ syn cluster shArrayValueList  
contains=shArithmetic,shArithParen,shCommandSub,shDeref,shDerefSimple,shExpr,shNumber,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shSpecial,shParen,bashSpecialVariables,shParenError
+endif
+if exists("b:is_bash") || exists("b:is_kornshell")
+ syn match shVariable  
"\<\h\w*\%(\[..\{-}\]\)\=\ze\%([|^&*/%+-]\|[<^]<\|[>^]>\)\=="   
contains=shDerefVarArray nextgroup=shVarAssign
+ syn match shVarAssign contained       "\%([|^&*/%+-]\|[<^]<\|[>^]>\)\=="      
nextgroup=shArrayRegion,shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
+ syn region shArrayRegion      contained matchgroup=shShellVariables start="(" 
skip='\\\|\.' end=")" contains=@shArrayValueList,shArrayValue,shComment
+else
+ syn match  shVarAssign        contained       "="     
nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
+endif
 syn match  shVar       contained       "\h\w*"
 syn region shAtExpr    contained       start="@(" end=")" contains=@shIdList
 if exists("b:is_bash")
@@ -571,8 +628,11 @@ syn match  shDerefOp       contained       ":\=+"  
nextgroup=@shDerefPatternList
 if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
  syn match  shDerefOp  contained       "#\{1,2}"               
nextgroup=@shDerefPatternList
  syn match  shDerefOp  contained       "%\{1,2}"               
nextgroup=@shDerefPatternList
- syn match  shDerefPattern     contained       "[^{}]\+"               
contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape
 nextgroup=shDerefPattern
+ syn match  shDerefPattern     contained       "[^{}]\+"               
contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape
 nextgroup=shDerefPattern skipnl
  syn region shDerefPattern     contained       start="{" end="}"       
contains=shDeref,shDerefSimple,shDerefString,shCommandSub 
nextgroup=shDerefPattern
+ " Match parametric bracket expressions with a leading whitespace character.
+ syn region shDerefPattern     contained       matchgroup=shBracketExprDelim 
start="\[" end="\]"       contains=@shBracketExprList,shDoubleQuote 
nextgroup=shDerefPattern
+ call s:GenerateBracketExpressionItems({'itemGroup': 'shDerefPattern', 
'bracketGroup': 'shBracketExprDelim', 'extraArgs': 'contained 
nextgroup=shDerefPattern'})
  syn match  shDerefEscape      contained       '\%(\\\)*\.'
 endif
 if exists("b:is_bash")
@@ -592,15 +652,16 @@ if exists("b:is_bash") || exists("b:is_kornshell") || 
exists("b:is_posix")
 endif
 
 if exists("b:is_bash")
+ " bash : ${parameter/pattern/string}
  " bash : ${parameter//pattern/string}
- " bash : ${parameter//pattern}
  syn match  shDerefPPS contained       '/\{1,2}'       nextgroup=shDerefPPSleft
  syn region shDerefPPSleft     contained       start='.'       
skip=@\%(\\\)*\/@ matchgroup=shDerefOp  end='/' end='\ze}' end='"'      
nextgroup=shDerefPPSright       contains=@shPPSLeftList
  syn region shDerefPPSright    contained       start='.'       
skip=@\%(\\\)\+@                end='\ze}'                              
contains=@shPPSRightList
 
- " bash : ${parameter/#substring/replacement}
- syn match  shDerefPSR contained       '/#'    
nextgroup=shDerefPSRleft,shDoubleQuote,shSingleQuote
- syn region shDerefPSRleft     contained       start='[^"']'   
skip=@\%(\\\)*\/@ matchgroup=shDerefOp  end='/' end='\ze}'      
nextgroup=shDerefPSRright
+ " bash : ${parameter/#pattern/string}
+ " bash : ${parameter/%pattern/string}
+ syn match  shDerefPSR contained       '/[#%]' 
nextgroup=shDerefPSRleft,shDoubleQuote,shSingleQuote
+ syn region shDerefPSRleft     contained       start='[^"']'   
skip=@\%(\\\)*\/@ matchgroup=shDerefOp  end='/' end='\ze}'      
nextgroup=shDerefPSRright       contains=shBracketExpr
  syn region shDerefPSRright    contained       start='.'       
skip=@\%(\\\)\+@                end='\ze}'
 endif
 
@@ -670,6 +731,7 @@ syn sync match shWhileSync  grouphere       shRepeat        
"\<while\>"
 " =====================
 if !exists("skip_sh_syntax_inits")
  hi def link shArithRegion     shShellVariables
+ hi def link shArrayValue      shDeref
  hi def link shAstQuote        shDoubleQuote
  hi def link shAtExpr  shSetList
  hi def link shBkslshSnglQuote shSingleQuote
@@ -764,7 +826,10 @@ if !exists("skip_sh_syntax_inits")
  endif
 
  hi def link shArithmetic              Special
+ hi def link shBracketExprDelim                Delimiter
  hi def link shCharClass               Identifier
+ hi def link shCollSymb                shCharClass
+ hi def link shEqClass         shCharClass
  hi def link shSnglCase                Statement
  hi def link shCommandSub              Special
  hi def link shCommandSubBQ            shCommandSub
@@ -814,6 +879,10 @@ delc ShFoldFunctions
 delc ShFoldHereDoc
 delc ShFoldIfDoFor
 
+" Delete the bracket expression function {{{1
+" ======================================
+delfun s:GenerateBracketExpressionItems
+
 " Set Current Syntax: {{{1
 " ===================
 if exists("b:is_bash")
diff --git a/runtime/syntax/testdir/dumps/sh_04_01.dump 
b/runtime/syntax/testdir/dumps/sh_04_01.dump
index 5a0ebe8f8..c536106c3 100644
--- a/runtime/syntax/testdir/dumps/sh_04_01.dump
+++ b/runtime/syntax/testdir/dumps/sh_04_01.dump
@@ -7,14 +7,14 @@
 |#+0#0000e05&| |T|h|i|s| |i|s| |O|K| +0#0000000&@62
 |:+0#0000e05&| 
+0#0000000&|$+0#e000e06&|{|V|a|r|i|a|b|l|e|B|:+0#af5f00255&|-|$+0#e000e06&|{|V|a|r|i|a|b|l|e|C|:+0#af5f00255&|-|e+0#0000000&|n|g|}+0#e000e06&@1|
 +0#0000000&@41
 |:+0#0000e05&| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|{|V|a|r|i|a|b|l|e|B|:+0#af5f00255&|-|$+0#e000e06&|{|V|a|r|i|a|b|l|e|C|:+0#af5f00255&|-|e+0#0000000&|n|g|}+0#e000e06&@1|"+0#af5f00255&|
 +0#0000000&@39
-@75
-|#+0#0000e05&| |F|i|r|s|t| |l|i|n|e| |i|s| |O|K| |e|x|c|e|p|t| |i|t|s| 
|m|i|s@1|i|n|g| |a| |c|l|o|s|i|n|g| |"|}|"|,| +0#0000000&@22
-|#+0#0000e05&| |s|o| |s|e|c|o|n|d| |l|i|n|e| |s|h|o|u|l|d| |h|a|v|e| |s|o|m|e| 
|e|r@1|o|r| |h|i|g|h|l|i|g|h|t|i|n|g| +0#0000000&@22
-|V+0#00e0e07&|a|r|i|a|b|l|e|=+0#0000000&|$+0#e000e06&|{|V|a|r|i|a|b|l|e|B|:+0#af5f00255&|=|$+0#e000e06&|{|V|a|r|i|a|b|l|e|C|:+0#af5f00255&|=|{+0#0000000&|V|a|r|3|:|=|$+0#e000e06&|{|V|a|r|4|:+0#af5f00255&|-|e+0#0000000&|n|g|}+0#e000e06&|}+0#0000000&|}+0#e000e06&|
 +0#0000000&@18
-|V+0#ffffff16#ff404010|a|r|i|a|b|l|e|=|$+0#e000e06#ffffff0|{|V|a|r|i|a|b|l|e|B|:+0#af5f00255&|-|$+0#e000e06&|{|V|a|r|i|a|b|l|e|C|:+0#af5f00255&|-|{+0#0000000&|V|a|r|3|:|=|e|n|g|}|}+0#e000e06&|
 +0#0000000&@27
 |~+0#4040ff13&| @73
 |~| @73
 |~| @73
 |~| @73
 |~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
 | +0#0000000&@56|1|9|,|0|-|1| @7|B|o|t| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_00.dump 
b/runtime/syntax/testdir/dumps/sh_12_00.dump
new file mode 100644
index 000000000..d2d99280e
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_00.dump
@@ -0,0 +1,20 @@
+>#+0#0000e05#ffffff0|!|/|b|i|n|/|b|a|s|h| +0#0000000&@63
+|#+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |h|i|g|h|l|i|g|h|t| |l|i|n|k| 
|s|h|A|r@1|a|y|V|a|l|u|e| |I|d|e|n|t|i|f|i|e|r| +0#0000000&@19
+|#+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |h|i|g|h|l|i|g|h|t| |l|i|n|k| 
|s|h|B|r|a|c|k|e|t|E|x|p|r|D|e|l|i|m| |S|t|r|u|c|t|u|r|e| +0#0000000&@14
+|#+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |h|i|g|h|l|i|g|h|t| |l|i|n|k| 
|s|h|C|h|a|r|C|l|a|s@1| |T|o|d|o| +0#0000000&@26
+|#+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |h|i|g|h|l|i|g|h|t| |l|i|n|k| 
|s|h|R|a|n|g|e| |C|u|r|s|o|r|L|i|n|e| +0#0000000&@24
+@75
+@75
+@75
+@75
+|[+0#e000e06&@1| +0#0000000&|(+0#e000002&| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| 
+0#0000000&|=+0#af5f00255&@1| 
+0#0000000&|?+0#e000002&|(|-|)|+|(|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|)+0#e000002&|
 +0#0000000&|&+0#e000002&@1| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| 
+0#0000000&|=+0#af5f00255&|~| 
+0#0000000&|^+0#e000002&|-|?|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|++0#e000002&|$|
 +0#0000000&|&+0#e000002&@1| +0#0000000&@18
+|'+0#af5f00255&|^+0#e000002&|?|(|-|)|+|(|[@1|:|d|i|g|i|t|:|]@1|)|$|'+0#af5f00255&|
 +0#0000000&|=+0#af5f00255&@1| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| 
+0#0000000&|&+0#e000002&@1| +0#0000000&|!+0#af5f00255&| 
+0#0000000&|"+0#af5f00255&|^+0#e000002&|-|?|[|0|-|9|]|+|$|"+0#af5f00255&| 
+0#0000000&|=+0#af5f00255&|~| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| 
+0#0000000&|)+0#e000002&| +0#0000000&|]+0#e000e06&@1| +0#0000000&||@1| |:| @8
+@75
+|[+8&&| +0&&|\+0#e000e06&|(| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| 
+0#0000000&|!+0#af5f00255&|=| 
+0#0000000&|"+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[|0|-|9|]|)|"+0#af5f00255&| 
+0#0000000&|-+0#af5f00255&|a| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| 
+0#0000000&|!+0#af5f00255&|=| 
+0#0000000&|'+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[@1|:|d|i|g|i|t|:|]@1|)|'+0#af5f00255&|
 +0#0000000&|\+0#e000e06&|)| +0#0000000&|]+8&&| +0&&|&@1| @7
+|[+8&&| +0&&|\+0#e000e06&|(| 
+0#0000000&|"+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[@1|:|d|i|g|i|t|:|]@1|)|"+0#af5f00255&|
 +0#0000000&|!+0#af5f00255&|=| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| 
+0#0000000&|-+0#af5f00255&|a| 
+0#0000000&|'+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[|0|-|9|]|)|'+0#af5f00255&| 
+0#0000000&|!+0#af5f00255&|=| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| 
+0#0000000&|\+0#e000e06&|)| +0#0000000&|]+8&&| +0&&||@1| |:| @5
+@75
+|#+0#0000e05&| |M|a|t|c|h| |"|\|[|0|\|]|\|[|0|\|]|"|,| |"|{|0|}|{|0|}|"|,| 
|e|t|c|.| +0#0000000&@38
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@38
+|:| |[+0#00e0003&|\+0#0000000&| @70
+|[|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@41
+|i|s|_|b|a|s|h|:| |1|,| @45|1|,|1| @10|T|o|p| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_01.dump 
b/runtime/syntax/testdir/dumps/sh_12_01.dump
new file mode 100644
index 000000000..fbc00826d
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_01.dump
@@ -0,0 +1,20 @@
+|[+8&#ffffff0| +0&&|\+0#e000e06&|(| 
+0#0000000&|"+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[@1|:|d|i|g|i|t|:|]@1|)|"+0#af5f00255&|
 +0#0000000&|!+0#af5f00255&|=| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| 
+0#0000000&|-+0#af5f00255&|a| 
+0#0000000&|'+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[|0|-|9|]|)|'+0#af5f00255&| 
+0#0000000&|!+0#af5f00255&|=| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| 
+0#0000000&|\+0#e000e06&|)| +0#0000000&|]+8&&| +0&&||@1| |:| @5
+@75
+|#+0#0000e05&| |M|a|t|c|h| |"|\|[|0|\|]|\|[|0|\|]|"|,| |"|{|0|}|{|0|}|"|,| 
|e|t|c|.| +0#0000000&@38
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@38
+|:| |[+0#00e0003&|\+0#0000000&| @70
+>[|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@41
+|:| |[+0#00e0003&|[+0#0000000&|\| @69
+|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@42
+|:| |[+0#00e0003&|[+0#0000000&|{|\| @68
+|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@43
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|\+0#af5f00255&| +0#0000000&@67
+|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@44
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&| @66
+|0|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@45
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|\| @63
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@48
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|\+0#af5f00255&|
 +0#0000000&@62
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@49
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|\+0#af5f00255&|
 +0#0000000&@61
+@57|1|9|,|1| @10|6|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_02.dump 
b/runtime/syntax/testdir/dumps/sh_12_02.dump
new file mode 100644
index 000000000..a2cfb6cb7
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_02.dump
@@ -0,0 +1,20 @@
+|:+0&#ffffff0| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|\+0#af5f00255&|
 +0#0000000&@61
+|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@50
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\|
 @59
+|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@52
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\|
 @58
+>]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@53
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|\+0#af5f00255&|
 +0#0000000&@57
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@54
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|\+0#0000000&|
 @56
+|[|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@55
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|\|
 @55
+|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@56
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|\|
 @54
+|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@57
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|\+0#af5f00255&|
 +0#0000000&@53
+|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@58
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&|
 @52
+|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|
 +0#0000000&@59
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|\+0#0000000#ffffff0|
 @43
+@57|3|7|,|1| @9|1|6|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_03.dump 
b/runtime/syntax/testdir/dumps/sh_12_03.dump
new file mode 100644
index 000000000..e1e9af709
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_03.dump
@@ -0,0 +1,20 @@
+|:+0&#ffffff0| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|\+0#0000000#ffffff0|
 @43
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| 
+0#0000000&@68
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|\+0#af5f00255&|
 +0#0000000&@42
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@69
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|\+0#af5f00255&|
 +0#0000000&@41
+>[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@70
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\|
 @39
+|}|]+0#00e0003&| +0#0000000&@72
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\|
 @38
+|]+0#00e0003&| +0#0000000&@73
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&|
 +0#0000000&@34
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|\+0#0000000&|
 @40
+|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&| +0#0000000&@67
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|\+0#0000000#ffffff0|
 @35
+|}|]+0#00e0003&| +0#0000000&@72
+|:| 
|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|\|
 @34
+|]+0#00e0003&| +0#0000000&@73
+@75
+|#+0#0000e05&| |M|a|t|c|h| |"|\|[|0|\|]|\|[|0|\|]|"|,| |"|{|0|}|{|0|}|"|,| 
|e|t|c|.| +0#0000000&@38
+@57|5@1|,|1| @9|2|6|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_04.dump 
b/runtime/syntax/testdir/dumps/sh_12_04.dump
new file mode 100644
index 000000000..535ca23d2
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_04.dump
@@ -0,0 +1,20 @@
+|#+0#0000e05#ffffff0| |M|a|t|c|h| |"|\|[|0|\|]|\|[|0|\|]|"|,| 
|"|{|0|}|{|0|}|"|,| |e|t|c|.| +0#0000000&@38
+|c+0#af5f00255&|a|s|e| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| 
+0#0000000&|i+0#af5f00255&|n| +0#0000000&@62
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| |[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|;+0#af5f00255&| 
+0#0000000&|:| 
|[+0#00e0003&|!+8#e000e06&|0+0#0000000&|-|9|]+0#00e0003&|;+0#af5f00255&| 
+0#0000000&|:| 
|[+0#00e0003&|^+8#e000e06&|0+0#0000000&|-|9|]+0#00e0003&|;+0#af5f00255&@1| 
+0#0000000&@8
+|[+0#00e0003&|\+0#0000000&| @72
+|[|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| |[+0#00e0003&|0+0#0000000&|1|2|3|]+0#00e0003&|;+0#af5f00255&| 
+0#0000000&|:| 
|[+0#00e0003&|!+8#e000e06&|0+0#0000000&|1|2|3|]+0#00e0003&|;+0#af5f00255&| 
+0#0000000&|:| 
|[+0#00e0003&|^+8#e000e06&|0+0#0000000&|1|2|3|]+0#00e0003&|;+0#af5f00255&@1| 
+0#0000000&@6
+>[+0#00e0003&|[+0#0000000&|\| @71
+|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| 
|[+0#00e0003&|1+0#0000000&|[+0#0000001#ffff4012|.|0|.|]|]+0#00e0003#ffffff0|;+0#af5f00255&|
 +0#0000000&|:| 
|[+0#00e0003&|!+8#e000e06&|[+0#0000001#ffff4012|.|0|.|]|]+0#00e0003#ffffff0|;+0#af5f00255&|
 +0#0000000&|:| 
|[+0#00e0003&|^+8#e000e06&|[+0#0000001#ffff4012|.|0|.|]|^+0#0000000#ffffff0|]+0#00e0003&|;+0#af5f00255&@1|
 +0#0000000&@2
+|[+0#00e0003&|[+0#0000000&|{|\| @70
+|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| 
|[+0#00e0003&|1+0#0000000&|[+0#0000001#ffff4012|=|0|=|]|]+0#00e0003#ffffff0|;+0#af5f00255&|
 +0#0000000&|:| 
|[+0#00e0003&|!+8#e000e06&|[+0#0000001#ffff4012|=|0|=|]|!+0#0000000#ffffff0|]+0#00e0003&|;+0#af5f00255&|
 +0#0000000&|:| 
|[+0#00e0003&|^+8#e000e06&|[+0#0000001#ffff4012|=|0|=|]|]+0#00e0003#ffffff0|;+0#af5f00255&@1|
 +0#0000000&@3
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|\+0#0000000&| @69
+|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@39
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&| @68
+|0|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@40
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|\| @65
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| 
|?|[+0#00e0003&|[+0#0000000&|:|f|o@1|:|]|]+0#00e0003&|?+0#0000000&|;+0#af5f00255&|
 +0#0000000&|:| 
|[+0#00e0003&|!+8#e000e06&|[+0#0000000&|:|f|o@1|:|]|]+0#00e0003&|?+0#0000000&|;+0#af5f00255&|
 +0#0000000&|:| 
|?|[+0#00e0003&|^+8#e000e06&|[+0#0000000&|:|f|o@1|:|]|]+0#00e0003&|;+0#af5f00255&@1|
 +0#0000000&
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|\+0#0000000&|
 @64
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| 
|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|;+0#af5f00255&|
 +0#0000000&|:| 
|[+0#00e0003&|!+8#e000e06&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|;+0#af5f00255&|
 +0#0000000&|:| 
|[+0#00e0003&|^+8#e000e06&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|;+0#af5f00255&@1
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|\|
 @63
+|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|^+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|:|l|o|w|e|r|:|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|^+0#af5f00255&@1|[+0#00e0003&|a+0#0000000&|-|z|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1|
 +0#0000000&@8
+@57|7|3|,|1| @9|3|5|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_05.dump 
b/runtime/syntax/testdir/dumps/sh_12_05.dump
new file mode 100644
index 000000000..9df4ef7b5
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_05.dump
@@ -0,0 +1,20 @@
+|[+0#00e0003#ffffff0|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|^+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|:|l|o|w|e|r|:|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|^+0#af5f00255&@1|[+0#00e0003&|a+0#0000000&|-|z|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1|
 +0#0000000&@8
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\|
 @61
+|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|,+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|:|u|p@1|e|r|:|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|,+0#af5f00255&@1|[+0#00e0003&|A+0#0000000&|-|Z|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1|
 +0#0000000&@10
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\|
 @60
+|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@48
+>[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|\+0#0000000&|
 @59
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@49
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|\+0#0000000&|
 @58
+|[|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&@1|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1|
 +0#0000000&@13
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|\|
 @57
+|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1|
 +0#0000000&@14
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|\|
 @56
+|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|/+0#af5f00255&|[+0#00e0003&|]+0#0000000&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|[+0#0000000#ffffff0|]+0#00e0003&|/+0#af5f00255&|[+0#0000000&|0|-|9|]|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|/+0#af5f00255&@1|[+0#00e0003&|]+0#0000000&|0|-|9|[|]+0#00e0003&|/+0#af5f00255&|[+0#0000000&|0|-|9|]|}+0#e000e06&|"+0#af5f00255&|;@1
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|\+0#0000000&|
 @55
+|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|/+0#af5f00255&|#|[+0#00e0003&|]+0#0000000&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|[+0#0000000#ffffff0|]+0#00e0003&|/+0#af5f00255&|[+0#0000000&|0|-|9|]|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|/+0#af5f00255&|%|[+0#00e0003&|]+0#0000000&|0|-|9|[|]+0#00e0003&|/+0#af5f00255&|[+0#0000000&|0|-|9|]|}+0#e000e06&|"+0#af5f00255&|;@1
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&|
 @54
+|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@54
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|\+0#0000000#ffffff0|
 @45
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@63
+@57|9|1|,|1| @9|4|5|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_06.dump 
b/runtime/syntax/testdir/dumps/sh_12_06.dump
new file mode 100644
index 000000000..ab66951a9
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_06.dump
@@ -0,0 +1,20 @@
+|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@63
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|\+0#0000000&|
 @44
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| 
+0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|[|.|]|[|.|]|.|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|[|.|[|.|]|]+0#00e0003#ffffff0|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|"+0#af5f00255&| 
+0#e000002&|"+0#af5f00255&|[+0#00e0003&|]+0#0000000&|[|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|\|
 @43
+|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| 
+0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|=|[|=|]|[|=|]|=|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|=|]|=|]|[|=|[|=|]|]+0#00e0003#ffffff0|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|\| 
|[+0#00e0003&|!+8#e000e06&|]+0#0000000&|[|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1|
 +0#0000000&
+>[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\|
 @41
+|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|!+8#e000e06&|]+0#0000000&|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|^+8#e000e06&|]+0#0000000&|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|!+8#e000e06&|[+0#0000000&|]+0#00e0003&|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|^+8#e000e06&|[+0#0000000&|]+0#00e0003&|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;@1|
 +0#0000000&@5
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\|
 @40
+|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|!+8#e000e06&|\+0#0000000&|]|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|^+8#e000e06&|\+0#0000000&|]|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|!+8#e000e06&|\+0#0000000&|[|]+0#00e0003&|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;|
 +0#0000000&|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|^+8#e000e06&|\+0#0000000&|[|]+0#00e0003&|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;@1|
 +0#0000000&@2
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|\+0#0000000&|
 @39
+|*|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@69
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&|\+0#0000000&|
 @35
+|*|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@69
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|\+0#0000000&|
 @42
+|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@62
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|\+0#0000000#ffffff0|
 @37
+|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| 
+0#0000000&@67
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|\|
 @36
+|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| 
+0#0000000&@68
+@57|1|0|9|,|1| @8|5@1|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_07.dump 
b/runtime/syntax/testdir/dumps/sh_12_07.dump
new file mode 100644
index 000000000..d265221e8
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_07.dump
@@ -0,0 +1,20 @@
+|]+0#00e0003#ffffff0|*+0#0000000&|)+0#af5f00255&| 
+0#0000000&|;+0#af5f00255&@1| +0#0000000&@68
+|[+0#00e0003&|!+8#e000e06&|]+0#0000000&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|[|:|x|d|i|g|i|t|:|]|\+0#0000000#ffffff0|
 
|[|^|[+0#0000001#ffff4012|:|l|o|w|e|r|:|]|!+0#0000000#ffffff0|[+0#0000001#ffff4012|:|u|p@1|e|r|:|]|]+0#00e0003#ffffff0|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@23
+|[+0#00e0003&|^+8#e000e06&|]+0#0000000&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|0+0#0000000#ffffff0|-|9|a|-|f|A|-|F|\|
 
|[|!|[+0#0000001#ffff4012|:|l|o|w|e|r|:|]|^+0#0000000#ffffff0|[+0#0000001#ffff4012|:|u|p@1|e|r|:|]|]+0#00e0003#ffffff0|*+0#0000000&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@24
+|[+0#00e0003&|!+8#e000e06&|!+0#0000000&|]+0#00e0003&| 
+0#0000000&||+0#af5f00255&| 
+0#0000000&|[+0#00e0003&|!+8#e000e06&|!+0#0000000&|[|]+0#00e0003&| 
+0#0000000&||+0#af5f00255&| 
+0#0000000&|[+0#00e0003&|!+8#e000e06&|]+0#0000000&|!|]+0#00e0003&| 
+0#0000000&||+0#af5f00255&| 
+0#0000000&|[+0#00e0003&|!+8#e000e06&|^+0#0000000&|]+0#00e0003&| 
+0#0000000&||+0#af5f00255&| 
+0#0000000&|[+0#00e0003&|!+8#e000e06&|^+0#0000000&|[|]+0#00e0003&| 
+0#0000000&||+0#af5f00255&| 
+0#0000000&|[+0#00e0003&|!+8#e000e06&|]+0#0000000&|^|]+0#00e0003&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@27
+|[+0#00e0003&|^+8#e000e06&|!+0#0000000&|]+0#00e0003&| 
+0#0000000&||+0#af5f00255&| 
+0#0000000&|[+0#00e0003&|^+8#e000e06&|!+0#0000000&|[|]+0#00e0003&| 
+0#0000000&||+0#af5f00255&| 
+0#0000000&|[+0#00e0003&|^+8#e000e06&|]+0#0000000&|!|]+0#00e0003&| 
+0#0000000&||+0#af5f00255&| 
+0#0000000&|[+0#00e0003&|^+8#e000e06&|^+0#0000000&|]+0#00e0003&| 
+0#0000000&||+0#af5f00255&| 
+0#0000000&|[+0#00e0003&|^+8#e000e06&|^+0#0000000&|[|]+0#00e0003&| 
+0#0000000&||+0#af5f00255&| 
+0#0000000&|[+0#00e0003&|^+8#e000e06&|]+0#0000000&|^|]+0#00e0003&|)+0#af5f00255&|
 +0#0000000&|;+0#af5f00255&@1| +0#0000000&@27
+>e+0#af5f00255&|s|a|c| +0#0000000&@70
+@75
+|#+0#0000e05&| |M|a|t|c|h| |"|\|[|0|\|]|\|[|0|\|]|"|,| |"|{|0|}|{|0|}|"|,| 
|e|t|c|.| +0#0000000&@38
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@30
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|\| @65
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@38
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|\+0#0000000&|
 @64
+|[|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@39
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|\|
 @63
+|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@40
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|\|
 @62
+|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@41
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|\+0#0000000&|
 @61
+|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@42
+@57|1|2|7|,|1| @8|6|4|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_08.dump 
b/runtime/syntax/testdir/dumps/sh_12_08.dump
new file mode 100644
index 000000000..ddbabda70
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_08.dump
@@ -0,0 +1,20 @@
+|[+0#00e0003#ffffff0|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@42
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&|
 @60
+|0|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@43
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|\|
 @57
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@46
+>:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|\+0#0000000&|
 @56
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@47
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|\|
 @55
+|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@48
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\|
 @53
+|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@50
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\|
 @52
+|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@51
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|\+0#0000000&|
 @51
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@52
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|\+0#0000000&|
 @50
+|[|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@53
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|\|
 @49
+|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@54
+@57|1|4|5|,|1| @8|7|4|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_09.dump 
b/runtime/syntax/testdir/dumps/sh_12_09.dump
new file mode 100644
index 000000000..35ba1f8e1
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_09.dump
@@ -0,0 +1,20 @@
+|{+0&#ffffff0|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@54
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|\|
 @48
+|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@55
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|\+0#0000000&|
 @47
+|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@56
+>:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&|
 @46
+|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@57
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|\+0#0000000#ffffff0|
 @37
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@66
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|\+0#0000000&|
 @36
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| 
+0#0000000&@67
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|\|
 @35
+|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| 
+0#0000000&@68
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\|
 @33
+|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@70
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\|
 @32
+|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@71
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|\+0#0000000&|
 @31
+|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@72
+@57|1|6|3|,|1| @8|8|3|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_10.dump 
b/runtime/syntax/testdir/dumps/sh_12_10.dump
new file mode 100644
index 000000000..f6d8ca0a3
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_10.dump
@@ -0,0 +1,20 @@
+|}+0#e000e06#ffffff0|"+0#af5f00255&| +0#0000000&@72
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@26
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|\+0#0000000&|
 @34
+|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|
 +0#0000000&@65
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|\+0#0000000#ffffff0|
 @29
+>}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@70
+|:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&|\+0#0000000&|
 @27
+|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@72
+@75
+|:| 
|*|[+0#00e0003&|x+0#0000000&|[+0#0000001#ffff4012|=|[|=|]|[|=|]|=|]|]+0#00e0003#ffffff0|;+0#0000000&|
 |:| 
|[+0#00e0003&|x+0#0000000&|[+0#0000001#ffff4012|=|]|=|]|[|=|[|=|]|]+0#00e0003#ffffff0|*+0#0000000&|;|
 |:| 
|*|[+0#00e0003&|x+0#0000000&|[+0#0000001#ffff4012|.|[|.|]|[|.|]|.|]|]+0#00e0003#ffffff0|;+0#0000000&|
 |:| 
|[+0#00e0003&|x+0#0000000&|[+0#0000001#ffff4012|.|]|.|]|[|.|[|.|]|]+0#00e0003#ffffff0|*+0#0000000&|
 @4
+|:| 
|*|[+0#00e0003&|[+0#0000001#ffff4012|=|[|=|]|x+0#0000000#ffffff0|[+0#0000001#ffff4012|=|]|=|]|]+0#00e0003#ffffff0|;+0#0000000&|
 |:| 
|[+0#00e0003&|[+0#0000001#ffff4012|=|]|=|]|x+0#0000000#ffffff0|[+0#0000001#ffff4012|=|[|=|]|]+0#00e0003#ffffff0|*+0#0000000&|;|
 |:| 
|*|[+0#00e0003&|[+0#0000001#ffff4012|.|[|.|]|x+0#0000000#ffffff0|[+0#0000001#ffff4012|.|]|.|]|]+0#00e0003#ffffff0|;+0#0000000&|
 |:| 
|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|x+0#0000000#ffffff0|[+0#0000001#ffff4012|.|[|.|]|]+0#00e0003#ffffff0|*+0#0000000&|
 @4
+|:| 
|*|[+0#00e0003&|[+0#0000001#ffff4012|=|[|=|]|[|=|]|=|]|x+0#0000000#ffffff0|]+0#00e0003&|;+0#0000000&|
 |:| 
|[+0#00e0003&|[+0#0000001#ffff4012|=|]|=|]|[|=|[|=|]|x+0#0000000#ffffff0|]+0#00e0003&|*+0#0000000&|;|
 |:| 
|*|[+0#00e0003&|[+0#0000001#ffff4012|.|[|.|]|[|.|]|.|]|x+0#0000000#ffffff0|]+0#00e0003&|;+0#0000000&|
 |:| 
|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|[|.|[|.|]|x+0#0000000#ffffff0|]+0#00e0003&|*+0#0000000&|
 @4
+|:| |[+0#00e0003&|!+8#e000e06&|]+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|^+8#e000e06&|]+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|!+8#e000e06&|[+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|^+8#e000e06&|[+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|!+8#e000e06&|\+0#0000000&|]|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|^+8#e000e06&|\+0#0000000&|]|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|!+8#e000e06&|\+0#0000000&|[|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|^+8#e000e06&|\+0#0000000&|[|]+0#00e0003&| +0#0000000&@8
+|:| |[+0#00e0003&|$+0#0000000&|'|\|x|5|b|'|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|$+0#0000000&|'|\|x|5|d|'|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|]+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|[+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|\+0#0000000&|]|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|\+0#0000000&|[|]+0#00e0003&| +0#0000000&@20
+|:| |[+0#00e0003&|$+0#0000000&|'|\|x|2|0|'|[|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|"+0#af5f00255&| 
+0#e000002&|"+0#af5f00255&|[+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|'+0#0000000&| |'|[|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|\+0#0000000&| |[|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|\+0#0000000&| |\|[|]+0#00e0003&|;+0#0000000&| |:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|[+0#00e0003&| 
+0#0000000&@2|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@7
+|:| |[+0#00e0003&|[+0#0000000&|$|'|\|x|2|0|'|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|[+0#0000000&|"+0#af5f00255&| 
+0#e000002&|"+0#af5f00255&|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|[+0#0000000&|'| |'|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|[+0#0000000&|\| |]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|\+0#0000000&|[|\| |]+0#00e0003&|;+0#0000000&| |:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|[+0#00e0003&| 
+0#0000000&@3|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@6
+|:| 
|[+0#00e0003&|^+8#e000e06&|$+0#0000000&|'|\|x|2|0|'|[|]+0#00e0003&|;+0#0000000&|
 |:| |[+0#00e0003&|!+8#e000e06&|"+0#af5f00255&| 
+0#e000002&|"+0#af5f00255&|[+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|^+8#e000e06&|'+0#0000000&| |'|[|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|!+8#e000e06&|\+0#0000000&| |[|]+0#00e0003&|;+0#0000000&| |:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|[+0#00e0003&|^+8#e000e06&| 
+0#0000000&@7|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@7
+|:| 
|[+0#00e0003&|!+8#e000e06&|[+0#0000000&|$|'|\|x|2|0|'|]+0#00e0003&|;+0#0000000&|
 |:| |[+0#00e0003&|^+8#e000e06&|[+0#0000000&|"+0#af5f00255&| 
+0#e000002&|"+0#af5f00255&|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|!+8#e000e06&|[+0#0000000&|'| |'|]+0#00e0003&|;+0#0000000&| |:| 
|[+0#00e0003&|^+8#e000e06&|[+0#0000000&|\| |]+0#00e0003&|;+0#0000000&| |:| 
|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|[+0#00e0003&|!+8#e000e06&| 
+0#0000000&@8|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@6
+@75
+@57|1|8|1|,|1| @8|9|3|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_11.dump 
b/runtime/syntax/testdir/dumps/sh_12_11.dump
new file mode 100644
index 000000000..21edbc825
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_11.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@74
+|n+0#00e0e07&|l|=+0#0000000&|'+0#af5f00255&| +0#0000000&@70
+|'+0#af5f00255&| +0#0000000&@73
+|e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|"+0#af5f00255&|$+0#e000e06&|{|n|l|}|"+0#af5f00255&|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&|;+0#0000000&|
 |e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|'+0#0000000&|$|{|n|l|}|'|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&|
 +0#0000000&@14
+|e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|\+0#0000000&|"|$|{|n|l|}|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&|;+0#0000000&|
 |e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|\+0#0000000&|'|$|{|n|l|}|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&|
 +0#0000000&@14
+>e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|$+0#0000000&|{|n|l|}|\|"|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&|;+0#0000000&|
 |e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|$+0#0000000&|{|n|l|}|\|'|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&|
 +0#0000000&@14
+@75
+|b+0#00e0e07&|i|n|s|=+0#0000000&|(+0#e000e06&|)|;+0#0000000&| 
|b+0#00e0e07&|i|n|s|=+0#0000000&|(+0#e000e06&|0+0#e000002&| 
+0#0000000&|1+0#e000002&|)+0#e000e06&|;+0#0000000&| |e+0#af5f00255&|v|a|l| 
+0#0000000&|b+0#00e0e07&|i|n|s|++0#0000000&|=|(+0#e000e06&|{|0+0#e000002&|.+0#0000000&@1|1+0#e000002&|}+0#e000e06&|)|
 +0#0000000&@34
+|b+0#00e0e07&|i|n|s|[+0#e000e06&|0+0#e000002&|]+0#e000e06&|=+0#0000000&|0+0#e000002&|;+0#0000000&|
 
|b+0#00e0e07&|i|n|s|[+0#e000e06&|1+0#e000002&|]+0#e000e06&|=+0#0000000&|1+0#e000002&|;+0#0000000&|
 |e+0#af5f00255&|v|a|l| 
+0#0000000&|b+0#00e0e07&|i|n|s|++0#0000000&|=|(+0#e000e06&|\+0#0000000&|$+0#e000e06&|{|b|i|n|s|[|{|1+0#e000002&|.+0#0000000&@1|0+0#e000002&|}+0#e000e06&|]|}|)|;+0#0000000&|
 |u+0#af5f00255&|n|s|e|t| 
+0#00e0e07&|b|i|n|s|[+0#e000e06&|3+0#e000002&|]+0#e000e06&| 
+0#00e0e07&|b|i|n|s|[+0#e000e06&|2+0#e000002&|]+0#e000e06&| +0#0000000&
+|b+0#00e0e07&|i|n|s|=+0#0000000&|(+0#e000e06&|[+0#00e0e07&|8+0#e000002&|#|0|]+0#00e0e07&|=+0#0000000&|$+0#e000e06&|(@1|2+0#e000002&|#|1|0@1|)+0#e000e06&@1|
 
+0#0000000&|[+0#00e0e07&|$+0#e000e06&|(@1|8+0#e000002&|#|1|)+0#e000e06&@1|]+0#00e0e07&|=+0#0000000&|$+0#e000e06&|(@1|2+0#e000002&|#|1|0|)+0#e000e06&@1|
 
+0#0000000&|[+0#00e0e07&|3+0#e000002&|]+0#00e0e07&|=+0#0000000&|$+0#e000e06&|{|b|i|n|s|[|2+0#e000002&|#|1|]+0#e000e06&|}|
 +0#0000000&|$+0#e000e06&|{|b|i|n|s|[|0+0#e000002&|]+0#e000e06&|}|)| 
+0#0000000&@2
+|(+0#e000e06&|e+0#af5f00255&|c|h|o| 
+0#e000002&|s|u|m|[+0#e000e06&|$|(@1|b|i|n|s|[|1+0#e000002&|6|#|3|]+0#e000e06&| 
|+| |b|i|n|s|[|8+0#e000002&|#|2|]+0#e000e06&| |+| 
|b|i|n|s|[|2+0#e000002&|#|1|]+0#e000e06&| |+| 
|b|i|n|s|[|0+0#e000002&|]+0#e000e06&|)@1|]|)| +0#0000000&@13
+|e+0#af5f00255&|v|a|l| +0#0000000&|u+0#af5f00255&|n|s|e|t| 
+0#00e0e07&|b|i|n|s|[+0#e000e06&|{|0+0#e000002&|.+0#0000000&@1|$+0#e000e06&|(@1|$|{|#|b|i|n|s|[|*+0#0000000&|]+0#e000e06&|}|
 |-| |1+0#e000002&|)+0#e000e06&@1|}|]| +0#0000000&@32
+|:| @73
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|9@1|,|1| @8|B|o|t| 
diff --git a/runtime/syntax/testdir/input/sh_04.sh 
b/runtime/syntax/testdir/input/sh_04.sh
index e9ec5fedb..150379060 100644
--- a/runtime/syntax/testdir/input/sh_04.sh
+++ b/runtime/syntax/testdir/input/sh_04.sh
@@ -20,8 +20,3 @@ Variable="${VariableB:=${VariableC:={Var3:=${Var4:-eng}}}}"
 # This is OK
 : ${VariableB:-${VariableC:-eng}}
 : "${VariableB:-${VariableC:-eng}}"
-
-# First line is OK except its missing a closing "}",
-# so second line should have some error highlighting
-Variable=${VariableB:=${VariableC:={Var3:=${Var4:-eng}}}
-Variable=${VariableB:-${VariableC:-{Var3:=eng}}
diff --git a/runtime/syntax/testdir/input/sh_12.sh 
b/runtime/syntax/testdir/input/sh_12.sh
new file mode 100644
index 000000000..dcfa55354
--- /dev/null
+++ b/runtime/syntax/testdir/input/sh_12.sh
@@ -0,0 +1,206 @@
+#!/bin/bash
+# VIM_TEST_SETUP highlight link shArrayValue Identifier
+# VIM_TEST_SETUP highlight link shBracketExprDelim Structure
+# VIM_TEST_SETUP highlight link shCharClass Todo
+# VIM_TEST_SETUP highlight link shRange CursorLine
+
+
+
+
+[[ ( "$1" == ?(-)+([0-9]) && "$1" =~ ^-?[[:digit:]]+$ &&
+'^?(-)+([[:digit:]])$' == "$2" && ! "^-?[0-9]+$" =~ "$2" ) ]] || :
+
+[ \( "$1" != "?(-)+([0-9])" -a "$1" != '?(-)+([[:digit:]])' \) ] &&
+[ \( "?(-)+([[:digit:]])" != "$2" -a '?(-)+([0-9])' != "$2" \) ] || :
+
+# Match "\[0\]\[0\]", "{0}{0}", etc.
+: [[{][0-9]*[]}][[{][[:digit:]]*[]}]
+: [\
+[{][0-9]*[]}][[{][[:digit:]]*[]}]
+: [[\
+{][0-9]*[]}][[{][[:digit:]]*[]}]
+: [[{\
+][0-9]*[]}][[{][[:digit:]]*[]}]
+: [[{]\
+[0-9]*[]}][[{][[:digit:]]*[]}]
+: [[{][\
+0-9]*[]}][[{][[:digit:]]*[]}]
+: [[{][0-9\
+]*[]}][[{][[:digit:]]*[]}]
+: [[{][0-9]\
+*[]}][[{][[:digit:]]*[]}]
+: [[{][0-9]*\
+[]}][[{][[:digit:]]*[]}]
+: [[{][0-9]*[]\
+}][[{][[:digit:]]*[]}]
+: [[{][0-9]*[]}\
+][[{][[:digit:]]*[]}]
+: [[{][0-9]*[]}]\
+[[{][[:digit:]]*[]}]
+: [[{][0-9]*[]}][\
+[{][[:digit:]]*[]}]
+: [[{][0-9]*[]}][[\
+{][[:digit:]]*[]}]
+: [[{][0-9]*[]}][[{\
+][[:digit:]]*[]}]
+: [[{][0-9]*[]}][[{]\
+[[:digit:]]*[]}]
+: [[{][0-9]*[]}][[{][\
+[:digit:]]*[]}]
+: [[{][0-9]*[]}][[{][[:digit:]\
+]*[]}]
+: [[{][0-9]*[]}][[{][[:digit:]]\
+*[]}]
+: [[{][0-9]*[]}][[{][[:digit:]]*\
+[]}]
+: [[{][0-9]*[]}][[{][[:digit:]]*[]\
+}]
+: [[{][0-9]*[]}][[{][[:digit:]]*[]}\
+]
+: [[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]
+: [[{][0-9]*[]}][[{][[:digit:]]*[\
+[.].]}]
+: [[{][0-9]*[]}][[{][[:digit:]]*[[.].]\
+}]
+: [[{][0-9]*[]}][[{][[:digit:]]*[[.].]}\
+]
+
+# Match "\[0\]\[0\]", "{0}{0}", etc.
+case "$1" in
+[[{][0-9]*[]}][[{][[:digit:]]*[]}]*) : [0-9]; : [!0-9]; : [^0-9];;
+[\
+[{][0-9]*[]}][[{][[:digit:]]*[]}]*) : [0123]; : [!0123]; : [^0123];;
+[[\
+{][0-9]*[]}][[{][[:digit:]]*[]}]*) : [1[.0.]]; : [![.0.]]; : [^[.0.]^];;
+[[{\
+][0-9]*[]}][[{][[:digit:]]*[]}]*) : [1[=0=]]; : [![=0=]!]; : [^[=0=]];;
+[[{]\
+[0-9]*[]}][[{][[:digit:]]*[]}]*) ;;
+[[{][\
+0-9]*[]}][[{][[:digit:]]*[]}]*) ;;
+[[{][0-9\
+]*[]}][[{][[:digit:]]*[]}]*) : ?[[:foo:]]?; : [![:foo:]]?; : ?[^[:foo:]];;
+[[{][0-9]\
+*[]}][[{][[:digit:]]*[]}]*) : [[:digit:]]; : [![:digit:]]; : [^[:digit:]];;
+[[{][0-9]*\
+[]}][[{][[:digit:]]*[]}]*) : "${1^[[:lower:]]}"; : "${1^^[a-z]}";;
+[[{][0-9]*[]\
+}][[{][[:digit:]]*[]}]*) : "${1,[[:upper:]]}"; : "${1,,[A-Z]}";;
+[[{][0-9]*[]}\
+][[{][[:digit:]]*[]}]*) ;;
+[[{][0-9]*[]}]\
+[[{][[:digit:]]*[]}]*) ;;
+[[{][0-9]*[]}][\
+[{][[:digit:]]*[]}]*) : "${1#[[:digit:]]}"; : "${1##[0-9]}";;
+[[{][0-9]*[]}][[\
+{][[:digit:]]*[]}]*) : "${1%[[:digit:]]}"; : "${1%%[0-9]}";;
+[[{][0-9]*[]}][[{\
+][[:digit:]]*[]}]*) : "${1/[][:digit:][]/[0-9]}"; : "${1//[]0-9[]/[0-9]}";;
+[[{][0-9]*[]}][[{]\
+[[:digit:]]*[]}]*) : "${1/#[][:digit:][]/[0-9]}"; : "${1/%[]0-9[]/[0-9]}";;
+[[{][0-9]*[]}][[{][\
+[:digit:]]*[]}]*) ;;
+[[{][0-9]*[]}][[{][[:digit:]\
+]*[]}]*) ;;
+[[{][0-9]*[]}][[{][[:digit:]]\
+*[]}]*) : "${1#*[[.[.][.].]]}"; : "${1%[[.].][.[.]]*}"; : "${1#*" "[][]}";;
+[[{][0-9]*[]}][[{][[:digit:]]*\
+[]}]*) : "${1#*[[=[=][=]=]]}"; : "${1%[[=]=][=[=]]*}"; : "${1#*\ [!][]}";;
+[[{][0-9]*[]}][[{][[:digit:]]*[]\
+}]*) : "${1#*[!]]}"; : "${1#*[^]]}"; : "${1%[![]*}"; : "${1%[^[]*}";;
+[[{][0-9]*[]}][[{][[:digit:]]*[]}\
+]*) : "${1#*[!\]]}"; : "${1#*[^\]]}"; : "${1%[!\[]*}"; : "${1%[^\[]*}";;
+[[{][0-9]*[]}][[{][[:digit:]]*[]}]\
+*) ;;
+[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]\
+*) ;;
+[[{][0-9]*[]}][[{][[:digit:]]*[\
+[.].]}]*) ;;
+[[{][0-9]*[]}][[{][[:digit:]]*[[.].]\
+}]*) ;;
+[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}\
+]*) ;;
+[!][:digit:][:xdigit:]\ [^[:lower:]![:upper:]]*) ;;
+[^][:digit:]0-9a-fA-F\ [![:lower:]^[:upper:]]*) ;;
+[!!] | [!![] | [!]!] | [!^] | [!^[] | [!]^]) ;;
+[^!] | [^![] | [^]!] | [^^] | [^^[] | [^]^]) ;;
+esac
+
+# Match "\[0\]\[0\]", "{0}{0}", etc.
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*\
+[[{][0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[\
+[{][0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[\
+{][0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{\
+][0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{]\
+[0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][\
+0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9\
+]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]\
+*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*\
+[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]\
+}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}\
+][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}]\
+[[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][\
+[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[\
+{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{\
+][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{]\
+[[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{][\
+[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]\
+]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]\
+*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*\
+[]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]\
+}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]}\
+]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]}]\
+}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[\
+[.].]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[[.].]\
+}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]\
+}"
+
+: *[x[=[=][=]=]]; : [x[=]=][=[=]]*; : *[x[.[.][.].]]; : [x[.].][.[.]]*
+: *[[=[=]x[=]=]]; : [[=]=]x[=[=]]*; : *[[.[.]x[.].]]; : [[.].]x[.[.]]*
+: *[[=[=][=]=]x]; : [[=]=][=[=]x]*; : *[[.[.][.].]x]; : [[.].][.[.]x]*
+: [!]]; : [^]]; : [![]; : [^[]; : [!\]]; : [^\]]; : [!\[]; : [^\[]
+: [$'\x5b']; : [$'\x5d']; : []]; : [[]; : [\]]; : [\[]
+: [$'\x20'[]; : [" "[]; : [' '[]; : [\ []; : [\ \[]; : "${1#[  ]}"
+: [[$'\x20']; : [[" "]; : [[' ']; : [[\ ]; : [\[\ ]; : "${1#[   ]}"
+: [^$'\x20'[]; : [!" "[]; : [^' '[]; : [!\ []; : "${1#[^       ]}"
+: [![$'\x20']; : [^[" "]; : [![' ']; : [^[\ ]; : "${1#[!        ]}"
+
+nl='
+'
+echo "${1#${1%%[!"${nl}"]*}}"; echo "${1#${1%%[!'${nl}']*}}"
+echo "${1#${1%%[!\"${nl}]*}}"; echo "${1#${1%%[!\'${nl}]*}}"
+echo "${1#${1%%[!${nl}\"]*}}"; echo "${1#${1%%[!${nl}\']*}}"
+
+bins=(); bins=(0 1); eval bins+=({0..1})
+bins[0]=0; bins[1]=1; eval bins+=(\${bins[{1..0}]}); unset bins[3] bins[2]
+bins=([8#0]=$((2#100)) [$((8#1))]=$((2#10)) [3]=${bins[2#1]} ${bins[0]})
+(echo sum[$((bins[16#3] + bins[8#2] + bins[2#1] + bins[0]))])
+eval unset bins[{0..$((${#bins[*]} - 1))}]
+:

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1tSC69-00DSUy-0Z%40256bit.org.

Raspunde prin e-mail lui