public function __construct()
 {
     $this('Script')->is('ScriptHeader', 'Block+')->call(function ($header, $blockList) {
         return new TES4Script($header, null, $blockList);
     })->is('ScriptHeader', 'VariableDeclaration+')->call(function ($header, $variableList) {
         return new TES4Script($header, $variableList, null);
     })->is('ScriptHeader', 'VariableDeclaration+', 'Block+')->call(function ($header, $variableList, $blockList) {
         return new TES4Script($header, $variableList, $blockList);
     });
     $this('ScriptHeader')->is('ScriptHeaderToken', 'ScriptName')->call(function ($headerToken, CommonToken $scriptName) {
         return new TES4ScriptHeader($scriptName->getValue());
     });
     $this('VariableDeclaration+')->is('VariableDeclaration+', 'VariableDeclaration')->call(function (TES4VariableDeclarationList $list, TES4VariableDeclaration $variableDeclaration) {
         $list->add($variableDeclaration);
         return $list;
     })->is('VariableDeclaration')->call(function (TES4VariableDeclaration $variableDeclaration) {
         $list = new TES4VariableDeclarationList();
         $list->add($variableDeclaration);
         return $list;
     });
     $this('VariableDeclaration')->is('VariableDeclarationType', 'VariableName')->call(function (CommonToken $variableDeclarationType, CommonToken $variableName) {
         return new TES4VariableDeclaration($variableName->getValue(), TES4Type::memberByValue(strtolower($variableDeclarationType->getValue())));
     });
     $this('Block+')->is('Block+', 'Block')->call(function (TES4BlockList $list, TES4CodeBlock $blockDeclaration) {
         $list->add($blockDeclaration);
         return $list;
     })->is('Block')->call(function (TES4CodeBlock $blockDeclaration) {
         $list = new TES4BlockList();
         $list->add($blockDeclaration);
         return $list;
     });
     $this('Block')->is('BlockStart', 'BlockType', 'BlockParameter+', 'Code+', 'BlockEnd')->call(function ($blockStart, CommonToken $blockType, TES4BlockParameterList $blockParameters, TES4CodeChunks $codeChunks, $blockEnd) {
         return new TES4CodeBlock($blockType->getValue(), $blockParameters, $codeChunks);
     })->is('BlockStart', 'BlockType', 'BlockParameter+', 'BlockEnd')->call(function ($blockStart, CommonToken $blockType, TES4BlockParameterList $blockParameters, $blockEnd) {
         return new TES4CodeBlock($blockType->getValue(), $blockParameters, null);
     })->is('BlockStart', 'BlockType', 'Code+', 'BlockEnd')->call(function ($blockStart, CommonToken $blockType, TES4CodeChunks $codeChunks, $blockEnd) {
         return new TES4CodeBlock($blockType->getValue(), null, $codeChunks);
     })->is('BlockStart', 'BlockType', 'BlockEnd')->call(function ($blockStart, CommonToken $blockType, $blockEnd) {
         return new TES4CodeBlock($blockType->getValue(), null, null);
     });
     //rare empty block
     $this('BlockParameter+')->is('BlockParameter+', 'BlockParameter')->call(function (TES4BlockParameterList $list, TES4BlockParameter $blockParameter) {
         $list->add($blockParameter);
         return $list;
     })->is('BlockParameter')->call(function (TES4BlockParameter $blockParameter) {
         $block = new TES4BlockParameterList();
         $block->add($blockParameter);
         return $block;
     });
     $this('BlockParameter')->is('BlockParameterToken')->call(function (CommonToken $token) {
         return new TES4BlockParameter($token->getValue());
     });
     $this->createObscriptCodeParsingTree();
     $this->start('Script');
 }
 public function filter(\Closure $c)
 {
     $variableDeclarationList = [];
     $blockList = [];
     if ($this->variableDeclarationList !== null) {
         $variableDeclarationList = $this->variableDeclarationList->filter($c);
     }
     if ($this->blockList !== null) {
         $blockList = $this->blockList->filter($c);
     }
     return array_merge($variableDeclarationList, $blockList);
 }