
# This file was generated by Hermes Parser Generator on Tue Nov 24 09:55:36 2015
# 
# Hermes command: hermes generate grammar.hgr --name=wdl --directory=wdl --header
# Run from: .. (relative to this file)
# Hermes version: hermes-parser 2.0rc4
# 
# !!! DO NOT CHANGE THIS FILE DIRECTLY !!!
# 
# If you wish to change something in this file, either change the grammar and
# re-generate this file, or change the templates in Hermes and regenerate.
# See the Hermes repository: http://github.com/scottfrazer/hermes
import sys
import os
import re
import base64
import argparse
from collections import OrderedDict
# Common Code #
def parse_tree_string(parsetree, indent=None, b64_source=True, indent_level=0, debug=False):
    indent_str = (' ' * indent * indent_level) if indent else ''
    if isinstance(parsetree, ParseTree):
        children = [parse_tree_string(child, indent, b64_source, indent_level+1, debug) for child in parsetree.children]
        debug_str = parsetree.debug_str() if debug else ''
        if indent is None or len(children) == 0:
            return '{0}({1}: {2}{3})'.format(indent_str, parsetree.nonterminal, debug_str, ', '.join(children))
        else:
            return '{0}({1}:{2}\n{3}\n{4})'.format(
                indent_str,
                parsetree.nonterminal,
                debug_str,
                ',\n'.join(children),
                indent_str
            )
    elif isinstance(parsetree, Terminal):
        return indent_str + parsetree.dumps(b64_source=b64_source)
def ast_string(ast, indent=None, b64_source=True, indent_level=0):
    indent_str = (' ' * indent * indent_level) if indent else ''
    next_indent_str = (' ' * indent * (indent_level+1)) if indent else ''
    if isinstance(ast, Ast):
        children = OrderedDict([(k, ast_string(v, indent, b64_source, indent_level+1)) for k, v in ast.attributes.items()])
        if indent is None:
            return '({0}: {1})'.format(
                ast.name,
                ', '.join('{0}={1}'.format(k, v) for k, v in children.items())
            )
        else:
            return '({0}:\n{1}\n{2})'.format(
                ast.name,
                ',\n'.join(['{0}{1}={2}'.format(next_indent_str, k, v) for k, v in children.items()]),
                indent_str
            )
    elif isinstance(ast, list):
        children = [ast_string(element, indent, b64_source, indent_level+1) for element in ast]
        if indent is None or len(children) == 0:
            return '[{0}]'.format(', '.join(children))
        else:
            return '[\n{1}\n{0}]'.format(
                indent_str,
                ',\n'.join(['{0}{1}'.format(next_indent_str, child) for child in children]),
            )
    elif isinstance(ast, Terminal):
        return ast.dumps(b64_source=b64_source)
class Terminal:
  def __init__(self, id, str, source_string, resource, line, col):
      self.__dict__.update(locals())
  def getId(self):
      return self.id
  def ast(self):
      return self
  def dumps(self, b64_source=True, **kwargs):
      source_string = base64.b64encode(self.source_string.encode('utf-8')).decode('utf-8') if b64_source else self.source_string
      return '<{resource}:{line}:{col} {terminal} "{source}">'.format(
          resource=self.resource,
          line=self.line,
          col=self.col,
          terminal=self.str,
          source=source_string
      )
  def __str__(self):
      return self.dumps()
class NonTerminal():
  def __init__(self, id, str):
    self.__dict__.update(locals())
    self.list = False
  def __str__(self):
    return self.str
class AstTransform:
  pass
class AstTransformSubstitution(AstTransform):
  def __init__(self, idx):
    self.__dict__.update(locals())
  def __repr__(self):
    return '$' + str(self.idx)
  def __str__(self):
    return self.__repr__()
class AstTransformNodeCreator(AstTransform):
  def __init__( self, name, parameters ):
    self.__dict__.update(locals())
  def __repr__( self ):
    return self.name + '( ' + ', '.join(['%s=$%s' % (k,str(v)) for k,v in self.parameters.items()]) + ' )'
  def __str__(self):
    return self.__repr__()
class AstList(list):
  def ast(self):
      retval = []
      for ast in self:
          retval.append(ast.ast())
      return retval
  def dumps(self, indent=None, b64_source=True):
      args = locals()
      del args['self']
      return ast_string(self, **args)
class ParseTree():
  def __init__(self, nonterminal):
      self.__dict__.update(locals())
      self.children = []
      self.astTransform = None
      self.isExpr = False
      self.isNud = False
      self.isPrefix = False
      self.isInfix = False
      self.nudMorphemeCount = 0
      self.isExprNud = False # true for rules like _expr := {_expr} + {...}
      self.listSeparator = None
      self.list = False
  def debug_str(self):
      from copy import deepcopy
      def h(v):
          if v == False or v is None:
              return str(v)
          from xtermcolor import colorize
          return colorize(str(v), ansi=190)
      d = deepcopy(self.__dict__)
      for key in ['self', 'nonterminal', 'children']:
          del d[key]
      f = {k: v for k, v in d.items() if v != False and v is not None}
      return '[{}]'.format(', '.join(['{}={}'.format(k,h(v)) for k,v in f.items()]))
  def add(self, tree):
      self.children.append( tree )
  def ast(self):
      if self.list == True:
          r = AstList()
          if len(self.children) == 0:
              return r
          end = max(0, len(self.children) - 1)
          for child in self.children[:end]:
              if isinstance(child, Terminal) and self.listSeparator is not None and child.id == self.listSeparator.id:
                  continue
              r.append(child.ast())
          r.extend(self.children[end].ast())
          return r
      elif self.isExpr:
          if isinstance(self.astTransform, AstTransformSubstitution):
              return self.children[self.astTransform.idx].ast()
          elif isinstance(self.astTransform, AstTransformNodeCreator):
              parameters = OrderedDict()
              for name, idx in self.astTransform.parameters.items():
                  if idx == '$':
                      child = self.children[0]
                  elif isinstance(self.children[0], ParseTree) and \
                       self.children[0].isNud and \
                       not self.children[0].isPrefix and \
                       not self.isExprNud and \
                       not self.isInfix:
                      if idx < self.children[0].nudMorphemeCount:
                          child = self.children[0].children[idx]
                      else:
                          index = idx - self.children[0].nudMorphemeCount + 1
                          child = self.children[index]
                  elif len(self.children) == 1 and not isinstance(self.children[0], ParseTree) and not isinstance(self.children[0], list):
                      return self.children[0]
                  else:
                      child = self.children[idx]
                  parameters[name] = child.ast()
              return Ast(self.astTransform.name, parameters)
      else:
          if isinstance(self.astTransform, AstTransformSubstitution):
              return self.children[self.astTransform.idx].ast()
          elif isinstance(self.astTransform, AstTransformNodeCreator):
              parameters = OrderedDict()
              for name, idx in self.astTransform.parameters.items():
                  parameters[name] = self.children[idx].ast()
              return Ast(self.astTransform.name, parameters)
          elif len(self.children):
              return self.children[0].ast()
          else:
              return None
  def dumps(self, indent=None, b64_source=True, debug=False):
      args = locals()
      del args['self']
      return parse_tree_string(self, **args)
class Ast():
    def __init__(self, name, attributes):
        self.__dict__.update(locals())
    def attr(self, attr):
        return self.attributes[attr]
    def dumps(self, indent=None, b64_source=True):
        args = locals()
        del args['self']
        return ast_string(self, **args)
class SyntaxError(Exception):
    def __init__(self, message):
        self.__dict__.update(locals())
    def __str__(self):
        return self.message
class TokenStream(list):
    def __init__(self, arg=[]):
        super(TokenStream, self).__init__(arg)
        self.index = 0
    def advance(self):
        self.index += 1
        return self.current()
    def last(self):
        return self[-1]
    def current(self):
        try:
            return self[self.index]
        except IndexError:
            return None
class DefaultSyntaxErrorHandler:
    def __init__(self):
        self.errors = []
    def _error(self, string):
        error = SyntaxError(string)
        self.errors.append(error)
        return error
    def unexpected_eof(self):
        return self._error("Error: unexpected end of file")
    def excess_tokens(self):
        return self._error("Finished parsing without consuming all tokens.")
    def unexpected_symbol(self, nonterminal, actual_terminal, expected_terminals, rule):
        return self._error("Unexpected symbol (line {line}, col {col}) when parsing parse_{nt}.  Expected {expected}, got {actual}.".format(
            line=actual_terminal.line,
            col=actual_terminal.col,
            nt=nonterminal,
            expected=', '.join(expected_terminals),
            actual=actual_terminal
        ))
    def no_more_tokens(self, nonterminal, expected_terminal, last_terminal):
        return self._error("No more tokens.  Expecting " + expected_terminal)
    def invalid_terminal(self, nonterminal, invalid_terminal):
        return self._error("Invalid symbol ID: {} ({})".format(invalid_terminal.id, invalid_terminal.string))
    def unrecognized_token(self, string, line, col):
        lines = string.split('\n')
        bad_line = lines[line-1]
        return self._error('Unrecognized token on line {}, column {}:\n\n{}\n{}'.format(
            line, col, bad_line, ''.join([' ' for x in range(col-1)]) + '^'
        ))
class ParserContext:
  def __init__(self, tokens, errors):
    self.__dict__.update(locals())
    self.nonterminal_string = None
    self.rule_string = None
# Parser Code #
terminals = {
    0: 'runtime',
    1: 'type',
    2: 'double_ampersand',
    3: 'type_e',
    4: 'lsquare',
    5: 'float',
    6: 'cmd_part',
    7: 'import',
    8: 'parameter_meta',
    9: 'lparen',
    10: 'rsquare',
    11: 'plus',
    12: 'colon',
    13: 'scatter',
    14: 'dash',
    15: 'lbrace',
    16: 'cmd_param_end',
    17: 'qmark',
    18: 'lteq',
    19: 'raw_command',
    20: 'asterisk',
    21: 'if',
    22: 'not',
    23: 'output',
    24: 'cmd_param_start',
    25: 'integer',
    26: 'object',
    27: 'double_pipe',
    28: 'in',
    29: 'cmd_attr_hint',
    30: 'raw_cmd_start',
    31: 'meta',
    32: 'gt',
    33: 'identifier',
    34: 'gteq',
    35: 'raw_cmd_end',
    36: 'call',
    37: 'comma',
    38: 'rparen',
    39: 'boolean',
    40: 'as',
    41: 'fqn',
    42: 'percent',
    43: 'double_equal',
    44: 'string',
    45: 'while',
    46: 'dot',
    47: 'rbrace',
    48: 'input',
    49: 'slash',
    50: 'lt',
    51: 'not_equal',
    52: 'equal',
    53: 'workflow',
    54: 'task',
    55: 'e',
    'runtime': 0,
    'type': 1,
    'double_ampersand': 2,
    'type_e': 3,
    'lsquare': 4,
    'float': 5,
    'cmd_part': 6,
    'import': 7,
    'parameter_meta': 8,
    'lparen': 9,
    'rsquare': 10,
    'plus': 11,
    'colon': 12,
    'scatter': 13,
    'dash': 14,
    'lbrace': 15,
    'cmd_param_end': 16,
    'qmark': 17,
    'lteq': 18,
    'raw_command': 19,
    'asterisk': 20,
    'if': 21,
    'not': 22,
    'output': 23,
    'cmd_param_start': 24,
    'integer': 25,
    'object': 26,
    'double_pipe': 27,
    'in': 28,
    'cmd_attr_hint': 29,
    'raw_cmd_start': 30,
    'meta': 31,
    'gt': 32,
    'identifier': 33,
    'gteq': 34,
    'raw_cmd_end': 35,
    'call': 36,
    'comma': 37,
    'rparen': 38,
    'boolean': 39,
    'as': 40,
    'fqn': 41,
    'percent': 42,
    'double_equal': 43,
    'string': 44,
    'while': 45,
    'dot': 46,
    'rbrace': 47,
    'input': 48,
    'slash': 49,
    'lt': 50,
    'not_equal': 51,
    'equal': 52,
    'workflow': 53,
    'task': 54,
    'e': 55,
}
# table[nonterminal][terminal] = rule
table = [
    [-1, -1, -1, -1, -1, -1, -1, -1, 49, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [26, -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24, -1, -1, -1, 25, -1, -1, -1, -1, -1, -1, -1, 28, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 98, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, 43, -1, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 85, 82, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, 39, 39, -1, -1, -1, 39, -1, 39, -1, -1, 39, 39, -1, -1, -1, -1, -1, -1, 39, -1, -1, 39, 39, -1, -1, 36, -1, -1, -1, 39, -1, -1, -1, -1, -1, 39, -1, -1, -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39],
    [-1, 67, -1, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67, -1, -1, -1, -1, -1, -1, -1, 67, -1, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67, -1, -1, -1, -1, -1, -1, -1, -1, 67, -1, 68, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, 129, 129, -1, -1, -1, 129, 132, 129, -1, -1, 129, 129, -1, -1, -1, -1, -1, -1, 129, -1, -1, 129, 129, -1, -1, -1, -1, -1, -1, 129, -1, -1, -1, -1, 132, 129, -1, -1, -1, -1, 129, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 129],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 105, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, -1, -1, -1, -1, -1, -1, 89, 89, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, 47, -1, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, 83, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 101, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 10, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 81, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1, -1, -1, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 103, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 64, -1, -1, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [60, 60, -1, 60, -1, -1, -1, -1, 60, -1, -1, -1, -1, 60, -1, -1, -1, -1, -1, 60, -1, 60, -1, 60, -1, -1, -1, -1, -1, -1, -1, 60, -1, -1, -1, -1, 60, -1, -1, -1, -1, -1, -1, -1, -1, 60, -1, 60, 60, -1, -1, -1, 59, -1, -1, -1],
    [-1, 72, -1, 72, -1, -1, -1, -1, -1, -1, -1, -1, -1, 75, -1, -1, -1, -1, -1, -1, -1, 74, -1, 76, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 71, -1, -1, -1, -1, -1, -1, -1, -1, 73, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, -1, -1, -1, -1, -1, -1, 99, 100, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, 107, -1, 107, -1, -1, -1, -1, -1, -1, 110, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, 42, -1, 42, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 45, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, -1],
    [-1, 80, -1, 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 80, -1, 79, -1, -1, -1, -1, -1, 80, -1, 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 80, -1, -1, -1, -1, -1, -1, -1, -1, 80, -1, 80, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, 34, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, 38, 38, -1, -1, -1, 38, -1, 38, -1, -1, 38, 38, -1, -1, -1, -1, -1, -1, 38, -1, -1, 38, 38, -1, -1, 37, -1, -1, -1, 38, -1, -1, -1, -1, -1, 38, -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 91, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 109, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 108, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, 65, 65, -1, -1, -1, 65, -1, 65, -1, -1, 65, 65, -1, -1, -1, -1, -1, -1, 65, -1, -1, 65, 65, -1, -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 106, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1],
    [20, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 12, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 4, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, 78, -1, 78, -1, -1, -1, -1, -1, -1, -1, -1, -1, 78, -1, 78, -1, -1, -1, -1, -1, 78, -1, 78, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 78, -1, -1, -1, 77, -1, -1, -1, -1, 78, -1, 78, -1, -1, -1, -1, -1, -1, -1, -1],
    [18, 15, -1, 15, -1, -1, -1, -1, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, -1, -1, -1, 18, -1, -1, -1, -1, -1, -1, -1, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 130, 131, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 87, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 90, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, 142, 142, -1, -1, -1, 142, -1, 142, -1, -1, 142, 142, -1, -1, -1, -1, -1, -1, 142, -1, -1, 142, 142, -1, -1, -1, -1, -1, -1, 142, -1, -1, -1, -1, -1, 142, -1, -1, -1, -1, 142, -1, -1, 145, -1, -1, -1, -1, -1, -1, -1, 142],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 94, -1, -1, -1, -1, -1, 97, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 136, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 139, -1, -1, -1, -1, -1, -1, -1, -1],
    [48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, 61, -1, 61, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 137, -1, -1, -1, -1, -1, -1, -1, -1, -1, 138, -1, -1, -1, -1, -1, -1, -1, -1],
    [17, 16, -1, 16, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 2, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, 144, -1, -1, -1, -1, -1, -1, -1, -1],
    [19, -1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, 19, -1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66, -1, -1, -1, -1, -1, -1, -1, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, 66, -1, 69, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 5, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 70, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, 8, -1],
]
nonterminal_first = {
    56: [8],
    57: [8, 0, 23, 31, 19],
    58: [23],
    59: [3, 1, -1],
    60: [40],
    61: [40],
    62: [48, -1],
    63: [29, -1],
    64: [1, -1, 45, 3, 13, 21, 36, 23],
    65: [33],
    66: [25, 26, -1, 4, 5, 33, 14, 9, 11, 15, 39, 44, 22, 55],
    67: [13],
    68: [37, -1],
    69: [46],
    70: [3, 1],
    71: [23],
    72: [48, -1],
    73: [41],
    74: [53, 54],
    75: [37, -1],
    76: [36],
    77: [17, 11, -1],
    78: [45],
    79: [17, 11],
    80: [52, -1],
    81: [36, 21, 1, 45, 13, 23, 3],
    82: [46, -1],
    83: [3, 1, -1],
    84: [33, -1],
    85: [3, 1],
    86: [15],
    87: [3, 1, -1],
    88: [33],
    89: [24, 6, -1],
    90: [7, -1],
    91: [15, -1],
    92: [24, 6],
    93: [29, -1],
    94: [48],
    95: [37, -1],
    96: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    97: [15],
    98: [24],
    99: [33],
    100: [54],
    101: [8, 0, -1, 31, 23, 19],
    102: [40, -1],
    103: [53, 54, -1],
    104: [33, -1],
    105: [7],
    106: [40, -1],
    107: [3, 1, -1],
    108: [37, -1],
    109: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    110: [33, -1],
    111: [19],
    112: [24, 6, -1],
    113: [29],
    114: [25, 26, 39, -1, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    115: [41, -1],
    116: [31],
    117: [33, -1],
    118: [0],
    119: [3, 1],
    120: [37, -1],
    121: [3, 1, -1],
    122: [52],
    123: [7, -1],
    124: [37, -1],
    125: [8, 0, -1, 31, 23, 19],
    126: [1, -1, 45, 3, 13, 21, 36, 23],
    127: [53, 54, -1],
    128: [53],
    129: [21],
    130: [7, 54, 53, -1],
}
nonterminal_follow = {
    56: [0, 31, 47, 19, 8, 23],
    57: [8, 0, 31, 23, 47, 19],
    58: [1, 45, 3, 47, 13, 21, 36, 23],
    59: [47],
    60: [7, 54, -1, 53],
    61: [1, 45, 3, 47, 13, 21, 36, 23, 15],
    62: [47],
    63: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    64: [47],
    65: [33, 47],
    66: [38, 10],
    67: [1, 45, 3, 47, 13, 21, 36, 23],
    68: [47, 48],
    69: [47, 37],
    70: [47, 3, 1],
    71: [0, 31, 47, 19, 8, 23],
    72: [47],
    73: [47, 37],
    74: [53, 54, -1],
    75: [47],
    76: [1, 45, 3, 47, 13, 21, 36, 23],
    77: [33],
    78: [1, 45, 3, 47, 13, 21, 36, 23],
    79: [33],
    80: [0, 1, 31, 3, 8, 13, 36, 45, 47, 48, 19, 21, 23],
    81: [21, 1, 13, 36, 45, 23, 3, 47],
    82: [47, 37],
    83: [10],
    84: [47],
    85: [33, 37, 10, 17, 11],
    86: [0, 31, 47, 19, 8, 23],
    87: [47],
    88: [47, 48, 37],
    89: [35],
    90: [53, 54, -1],
    91: [1, 45, 3, 47, 13, 21, 36, 23],
    92: [24, 6, 35],
    93: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    94: [47, 48],
    95: [10],
    96: [47, 37],
    97: [1, 45, 3, 47, 13, 21, 36, 23],
    98: [24, 6, 35],
    99: [47, 37],
    100: [53, 54, -1],
    101: [47],
    102: [7, 54, -1, 53],
    103: [-1],
    104: [47],
    105: [7, 54, -1, 53],
    106: [1, 45, 3, 47, 13, 21, 36, 23, 15],
    107: [8, 0, 31, 23, 48, 19],
    108: [38, 10],
    109: [0, 1, 2, 3, 4, 5, 10, 14, 9, 8, 11, 12, 13, 15, 16, 18, 19, 20, 21, 22, 23, 25, 26, 27, 29, 31, 32, 33, 34, 36, 37, 38, 39, 42, 43, 44, 45, 49, 47, 48, 50, 51, 55],
    110: [47, 48],
    111: [0, 31, 47, 19, 8, 23],
    112: [35],
    113: [25, 26, 39, 29, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    114: [47],
    115: [47],
    116: [0, 31, 47, 19, 8, 23],
    117: [47],
    118: [0, 31, 47, 19, 8, 23],
    119: [0, 1, 45, 31, 3, 48, 47, 19, 8, 13, 21, 36, 23],
    120: [47],
    121: [8, 0, 31, 23, 48, 19],
    122: [0, 1, 31, 3, 8, 13, 36, 45, 47, 48, 19, 21, 23],
    123: [53, 54, -1],
    124: [47],
    125: [47],
    126: [47],
    127: [-1],
    128: [53, 54, -1],
    129: [1, 45, 3, 47, 13, 21, 36, 23],
    130: [-1],
}
rule_first = {
    0: [7],
    1: [7],
    2: [-1],
    3: [-1],
    4: [53, 54],
    5: [53, 54],
    6: [-1],
    7: [-1],
    8: [7, 54, 53, -1],
    9: [53],
    10: [54],
    11: [40],
    12: [-1],
    13: [7],
    14: [40],
    15: [3, 1],
    16: [3, 1],
    17: [-1],
    18: [-1],
    19: [8, 0, 23, 31, 19],
    20: [8, 0, 23, 31, 19],
    21: [-1],
    22: [-1],
    23: [54],
    24: [19],
    25: [23],
    26: [0],
    27: [8],
    28: [31],
    29: [24, 6],
    30: [24, 6],
    31: [-1],
    32: [-1],
    33: [19],
    34: [6],
    35: [24],
    36: [29],
    37: [29],
    38: [-1],
    39: [-1],
    40: [24],
    41: [29],
    42: [3, 1],
    43: [3, 1],
    44: [-1],
    45: [-1],
    46: [23],
    47: [3, 1],
    48: [0],
    49: [8],
    50: [31],
    51: [33],
    52: [33],
    53: [-1],
    54: [-1],
    55: [15],
    56: [33],
    57: [17, 11],
    58: [-1],
    59: [52],
    60: [-1],
    61: [3, 1],
    62: [52],
    63: [17],
    64: [11],
    65: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    66: [1, 21, 13, 45, 36, 23, 3],
    67: [1, 21, 13, 45, 36, 23, 3],
    68: [-1],
    69: [-1],
    70: [53],
    71: [36],
    72: [3, 1],
    73: [45],
    74: [21],
    75: [13],
    76: [23],
    77: [40],
    78: [-1],
    79: [15],
    80: [-1],
    81: [36],
    82: [48],
    83: [48],
    84: [-1],
    85: [-1],
    86: [15],
    87: [33],
    88: [37],
    89: [-1],
    90: [-1],
    91: [48],
    92: [33],
    93: [40],
    94: [41],
    95: [37],
    96: [-1],
    97: [-1],
    98: [23],
    99: [46],
    100: [-1],
    101: [41],
    102: [46],
    103: [45],
    104: [21],
    105: [13],
    106: [33],
    107: [3, 1],
    108: [37],
    109: [-1],
    110: [-1],
    111: [1],
    112: [1],
    113: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    114: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    115: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    116: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    117: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    118: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    119: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    120: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    121: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    122: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    123: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    124: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    125: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    126: [22],
    127: [11],
    128: [14],
    129: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    130: [37],
    131: [-1],
    132: [-1],
    133: [33],
    134: [33],
    135: [33],
    136: [33],
    137: [37],
    138: [-1],
    139: [-1],
    140: [26],
    141: [4],
    142: [25, 26, 39, 44, 4, 5, 33, 14, 9, 11, 22, 15, 55],
    143: [37],
    144: [-1],
    145: [-1],
    146: [15],
    147: [9],
    148: [44],
    149: [33],
    150: [39],
    151: [25],
    152: [5],
}
nonterminal_rules = {
    56: [
        "$parameter_meta = :parameter_meta $map -> ParameterMeta( map=$1 )",
    ],
    57: [
        "$sections = $command",
        "$sections = $outputs",
        "$sections = $runtime",
        "$sections = $parameter_meta",
        "$sections = $meta",
    ],
    58: [
        "$wf_outputs = :output :lbrace $_gen27 :rbrace -> WorkflowOutputs( outputs=$2 )",
    ],
    59: [
        "$_gen14 = $output_kv $_gen14",
        "$_gen14 = :_empty",
    ],
    60: [
        "$import_namespace = :as :identifier -> $1",
    ],
    61: [
        "$alias = :as :identifier -> $1",
    ],
    62: [
        "$_gen23 = $call_input $_gen24",
        "$_gen23 = :_empty",
    ],
    63: [
        "$_gen11 = $cmd_param_kv $_gen12",
        "$_gen11 = :_empty",
    ],
    64: [
        "$_gen20 = $wf_body_element $_gen20",
        "$_gen20 = :_empty",
    ],
    65: [
        "$kv = :identifier :colon $e -> RuntimeAttribute( key=$0, value=$2 )",
    ],
    66: [
        "$_gen32 = $e $_gen33",
        "$_gen32 = :_empty",
    ],
    67: [
        "$scatter = :scatter :lparen :identifier :in $e :rparen :lbrace $_gen19 :rbrace -> Scatter( item=$2, collection=$4, body=$7 )",
    ],
    68: [
        "$_gen26 = :comma $mapping $_gen26",
        "$_gen26 = :_empty",
    ],
    69: [
        "$wf_output_wildcard = :dot :asterisk -> $1",
    ],
    70: [
        "$output_kv = $type_e :identifier :equal $e -> Output( type=$0, var=$1, expression=$3 )",
    ],
    71: [
        "$outputs = :output :lbrace $_gen13 :rbrace -> Outputs( attributes=$2 )",
    ],
    72: [
        "$_gen24 = $call_input $_gen24",
        "$_gen24 = :_empty",
    ],
    73: [
        "$wf_output = :fqn $_gen29 -> WorkflowOutput( fqn=$0, wildcard=$1 )",
    ],
    74: [
        "$workflow_or_task = $workflow",
        "$workflow_or_task = $task",
    ],
    75: [
        "$_gen28 = :comma $wf_output $_gen28",
        "$_gen28 = :_empty",
    ],
    76: [
        "$call = :call :fqn $_gen21 $_gen22 -> Call( task=$1, alias=$2, body=$3 )",
    ],
    77: [
        "$_gen17 = $postfix_quantifier",
        "$_gen17 = :_empty",
    ],
    78: [
        "$while_loop = :while :lparen $e :rparen :lbrace $_gen19 :rbrace -> WhileLoop( expression=$2, body=$5 )",
    ],
    79: [
        "$postfix_quantifier = :qmark",
        "$postfix_quantifier = :plus",
    ],
    80: [
        "$_gen18 = $setter",
        "$_gen18 = :_empty",
    ],
    81: [
        "$wf_body_element = $call",
        "$wf_body_element = $declaration",
        "$wf_body_element = $while_loop",
        "$wf_body_element = $if_stmt",
        "$wf_body_element = $scatter",
        "$wf_body_element = $wf_outputs",
    ],
    82: [
        "$_gen29 = $wf_output_wildcard",
        "$_gen29 = :_empty",
    ],
    83: [
        "$_gen30 = $type_e $_gen31",
        "$_gen30 = :_empty",
    ],
    84: [
        "$_gen16 = $kv $_gen16",
        "$_gen16 = :_empty",
    ],
    85: [
        "$type_e = :type <=> :lsquare $_gen30 :rsquare -> Type( name=$0, subtype=$2 )",
        "$type_e = :type",
    ],
    86: [
        "$map = :lbrace $_gen15 :rbrace -> $1",
    ],
    87: [
        "$_gen13 = $output_kv $_gen14",
        "$_gen13 = :_empty",
    ],
    88: [
        "$mapping = :identifier :equal $e -> IOMapping( key=$0, value=$2 )",
    ],
    89: [
        "$_gen9 = $command_part $_gen10",
        "$_gen9 = :_empty",
    ],
    90: [
        "$_gen0 = $import $_gen1",
        "$_gen0 = :_empty",
    ],
    91: [
        "$_gen22 = $call_body",
        "$_gen22 = :_empty",
    ],
    92: [
        "$command_part = :cmd_part",
        "$command_part = $cmd_param",
    ],
    93: [
        "$_gen12 = $cmd_param_kv $_gen12",
        "$_gen12 = :_empty",
    ],
    94: [
        "$call_input = :input :colon $_gen25 -> Inputs( map=$2 )",
    ],
    95: [
        "$_gen31 = :comma $type_e $_gen31",
        "$_gen31 = :_empty",
    ],
    96: [
        "$map_kv = $e :colon $e -> MapLiteralKv( key=$0, value=$2 )",
    ],
    97: [
        "$call_body = :lbrace $_gen5 $_gen23 :rbrace -> CallBody( declarations=$1, io=$2 )",
    ],
    98: [
        "$cmd_param = :cmd_param_start $_gen11 $e :cmd_param_end -> CommandParameter( attributes=$1, expr=$2 )",
    ],
    99: [
        "$object_kv = :identifier :colon $e -> ObjectKV( key=$0, value=$2 )",
    ],
    100: [
        "$task = :task :identifier :lbrace $_gen5 $_gen7 :rbrace -> Task( name=$1, declarations=$3, sections=$4 )",
    ],
    101: [
        "$_gen8 = $sections $_gen8",
        "$_gen8 = :_empty",
    ],
    102: [
        "$_gen4 = $import_namespace",
        "$_gen4 = :_empty",
    ],
    103: [
        "$_gen2 = $workflow_or_task $_gen3",
        "$_gen2 = :_empty",
    ],
    104: [
        "$_gen15 = $kv $_gen16",
        "$_gen15 = :_empty",
    ],
    105: [
        "$import = :import :string $_gen4 -> Import( uri=$1, namespace=$2 )",
    ],
    106: [
        "$_gen21 = $alias",
        "$_gen21 = :_empty",
    ],
    107: [
        "$_gen5 = $declaration $_gen6",
        "$_gen5 = :_empty",
    ],
    108: [
        "$_gen33 = :comma $e $_gen33",
        "$_gen33 = :_empty",
    ],
    109: [
        "$e = $e :double_pipe $e -> LogicalOr( lhs=$0, rhs=$2 )",
        "$e = $e :double_ampersand $e -> LogicalAnd( lhs=$0, rhs=$2 )",
        "$e = $e :double_equal $e -> Equals( lhs=$0, rhs=$2 )",
        "$e = $e :not_equal $e -> NotEquals( lhs=$0, rhs=$2 )",
        "$e = $e :lt $e -> LessThan( lhs=$0, rhs=$2 )",
        "$e = $e :lteq $e -> LessThanOrEqual( lhs=$0, rhs=$2 )",
        "$e = $e :gt $e -> GreaterThan( lhs=$0, rhs=$2 )",
        "$e = $e :gteq $e -> GreaterThanOrEqual( lhs=$0, rhs=$2 )",
        "$e = $e :plus $e -> Add( lhs=$0, rhs=$2 )",
        "$e = $e :dash $e -> Subtract( lhs=$0, rhs=$2 )",
        "$e = $e :asterisk $e -> Multiply( lhs=$0, rhs=$2 )",
        "$e = $e :slash $e -> Divide( lhs=$0, rhs=$2 )",
        "$e = $e :percent $e -> Remainder( lhs=$0, rhs=$2 )",
        "$e = :not $e -> LogicalNot( expression=$1 )",
        "$e = :plus $e -> UnaryPlus( expression=$1 )",
        "$e = :dash $e -> UnaryNegation( expression=$1 )",
        "$e = :identifier <=> :lparen $_gen32 :rparen -> FunctionCall( name=$0, params=$2 )",
        "$e = :identifier <=> :lsquare $e :rsquare -> ArrayOrMapLookup( lhs=$0, rhs=$2 )",
        "$e = :identifier <=> :dot :identifier -> MemberAccess( lhs=$0, rhs=$2 )",
        "$e = :object :lbrace $_gen34 :rbrace -> ObjectLiteral( map=$2 )",
        "$e = :lsquare $_gen32 :rsquare -> ArrayLiteral( values=$1 )",
        "$e = :lbrace $_gen36 :rbrace -> MapLiteral( map=$1 )",
        "$e = :lparen $e :rparen -> $1",
        "$e = :string",
        "$e = :identifier",
        "$e = :boolean",
        "$e = :integer",
        "$e = :float",
    ],
    110: [
        "$_gen25 = $mapping $_gen26",
        "$_gen25 = :_empty",
    ],
    111: [
        "$command = :raw_command :raw_cmd_start $_gen9 :raw_cmd_end -> RawCommand( parts=$2 )",
    ],
    112: [
        "$_gen10 = $command_part $_gen10",
        "$_gen10 = :_empty",
    ],
    113: [
        "$cmd_param_kv = :cmd_attr_hint :identifier :equal $e -> CommandParameterAttr( key=$1, value=$3 )",
    ],
    114: [
        "$_gen36 = $map_kv $_gen37",
        "$_gen36 = :_empty",
    ],
    115: [
        "$_gen27 = $wf_output $_gen28",
        "$_gen27 = :_empty",
    ],
    116: [
        "$meta = :meta $map -> Meta( map=$1 )",
    ],
    117: [
        "$_gen34 = $object_kv $_gen35",
        "$_gen34 = :_empty",
    ],
    118: [
        "$runtime = :runtime $map -> Runtime( map=$1 )",
    ],
    119: [
        "$declaration = $type_e $_gen17 :identifier $_gen18 -> Declaration( type=$0, postfix=$1, name=$2, expression=$3 )",
    ],
    120: [
        "$_gen35 = :comma $object_kv $_gen35",
        "$_gen35 = :_empty",
    ],
    121: [
        "$_gen6 = $declaration $_gen6",
        "$_gen6 = :_empty",
    ],
    122: [
        "$setter = :equal $e -> $1",
    ],
    123: [
        "$_gen1 = $import $_gen1",
        "$_gen1 = :_empty",
    ],
    124: [
        "$_gen37 = :comma $map_kv $_gen37",
        "$_gen37 = :_empty",
    ],
    125: [
        "$_gen7 = $sections $_gen8",
        "$_gen7 = :_empty",
    ],
    126: [
        "$_gen19 = $wf_body_element $_gen20",
        "$_gen19 = :_empty",
    ],
    127: [
        "$_gen3 = $workflow_or_task $_gen3",
        "$_gen3 = :_empty",
    ],
    128: [
        "$workflow = :workflow :identifier :lbrace $_gen19 :rbrace -> Workflow( name=$1, body=$3 )",
    ],
    129: [
        "$if_stmt = :if :lparen $e :rparen :lbrace $_gen19 :rbrace -> If( expression=$2, body=$5 )",
    ],
    130: [
        "$document = $_gen0 $_gen2 -> Document( imports=$0, definitions=$1 )",
    ],
}
rules = {
    0: "$_gen0 = $import $_gen1",
    1: "$_gen1 = $import $_gen1",
    2: "$_gen1 = :_empty",
    3: "$_gen0 = :_empty",
    4: "$_gen2 = $workflow_or_task $_gen3",
    5: "$_gen3 = $workflow_or_task $_gen3",
    6: "$_gen3 = :_empty",
    7: "$_gen2 = :_empty",
    8: "$document = $_gen0 $_gen2 -> Document( imports=$0, definitions=$1 )",
    9: "$workflow_or_task = $workflow",
    10: "$workflow_or_task = $task",
    11: "$_gen4 = $import_namespace",
    12: "$_gen4 = :_empty",
    13: "$import = :import :string $_gen4 -> Import( uri=$1, namespace=$2 )",
    14: "$import_namespace = :as :identifier -> $1",
    15: "$_gen5 = $declaration $_gen6",
    16: "$_gen6 = $declaration $_gen6",
    17: "$_gen6 = :_empty",
    18: "$_gen5 = :_empty",
    19: "$_gen7 = $sections $_gen8",
    20: "$_gen8 = $sections $_gen8",
    21: "$_gen8 = :_empty",
    22: "$_gen7 = :_empty",
    23: "$task = :task :identifier :lbrace $_gen5 $_gen7 :rbrace -> Task( name=$1, declarations=$3, sections=$4 )",
    24: "$sections = $command",
    25: "$sections = $outputs",
    26: "$sections = $runtime",
    27: "$sections = $parameter_meta",
    28: "$sections = $meta",
    29: "$_gen9 = $command_part $_gen10",
    30: "$_gen10 = $command_part $_gen10",
    31: "$_gen10 = :_empty",
    32: "$_gen9 = :_empty",
    33: "$command = :raw_command :raw_cmd_start $_gen9 :raw_cmd_end -> RawCommand( parts=$2 )",
    34: "$command_part = :cmd_part",
    35: "$command_part = $cmd_param",
    36: "$_gen11 = $cmd_param_kv $_gen12",
    37: "$_gen12 = $cmd_param_kv $_gen12",
    38: "$_gen12 = :_empty",
    39: "$_gen11 = :_empty",
    40: "$cmd_param = :cmd_param_start $_gen11 $e :cmd_param_end -> CommandParameter( attributes=$1, expr=$2 )",
    41: "$cmd_param_kv = :cmd_attr_hint :identifier :equal $e -> CommandParameterAttr( key=$1, value=$3 )",
    42: "$_gen13 = $output_kv $_gen14",
    43: "$_gen14 = $output_kv $_gen14",
    44: "$_gen14 = :_empty",
    45: "$_gen13 = :_empty",
    46: "$outputs = :output :lbrace $_gen13 :rbrace -> Outputs( attributes=$2 )",
    47: "$output_kv = $type_e :identifier :equal $e -> Output( type=$0, var=$1, expression=$3 )",
    48: "$runtime = :runtime $map -> Runtime( map=$1 )",
    49: "$parameter_meta = :parameter_meta $map -> ParameterMeta( map=$1 )",
    50: "$meta = :meta $map -> Meta( map=$1 )",
    51: "$_gen15 = $kv $_gen16",
    52: "$_gen16 = $kv $_gen16",
    53: "$_gen16 = :_empty",
    54: "$_gen15 = :_empty",
    55: "$map = :lbrace $_gen15 :rbrace -> $1",
    56: "$kv = :identifier :colon $e -> RuntimeAttribute( key=$0, value=$2 )",
    57: "$_gen17 = $postfix_quantifier",
    58: "$_gen17 = :_empty",
    59: "$_gen18 = $setter",
    60: "$_gen18 = :_empty",
    61: "$declaration = $type_e $_gen17 :identifier $_gen18 -> Declaration( type=$0, postfix=$1, name=$2, expression=$3 )",
    62: "$setter = :equal $e -> $1",
    63: "$postfix_quantifier = :qmark",
    64: "$postfix_quantifier = :plus",
    65: "$map_kv = $e :colon $e -> MapLiteralKv( key=$0, value=$2 )",
    66: "$_gen19 = $wf_body_element $_gen20",
    67: "$_gen20 = $wf_body_element $_gen20",
    68: "$_gen20 = :_empty",
    69: "$_gen19 = :_empty",
    70: "$workflow = :workflow :identifier :lbrace $_gen19 :rbrace -> Workflow( name=$1, body=$3 )",
    71: "$wf_body_element = $call",
    72: "$wf_body_element = $declaration",
    73: "$wf_body_element = $while_loop",
    74: "$wf_body_element = $if_stmt",
    75: "$wf_body_element = $scatter",
    76: "$wf_body_element = $wf_outputs",
    77: "$_gen21 = $alias",
    78: "$_gen21 = :_empty",
    79: "$_gen22 = $call_body",
    80: "$_gen22 = :_empty",
    81: "$call = :call :fqn $_gen21 $_gen22 -> Call( task=$1, alias=$2, body=$3 )",
    82: "$_gen23 = $call_input $_gen24",
    83: "$_gen24 = $call_input $_gen24",
    84: "$_gen24 = :_empty",
    85: "$_gen23 = :_empty",
    86: "$call_body = :lbrace $_gen5 $_gen23 :rbrace -> CallBody( declarations=$1, io=$2 )",
    87: "$_gen25 = $mapping $_gen26",
    88: "$_gen26 = :comma $mapping $_gen26",
    89: "$_gen26 = :_empty",
    90: "$_gen25 = :_empty",
    91: "$call_input = :input :colon $_gen25 -> Inputs( map=$2 )",
    92: "$mapping = :identifier :equal $e -> IOMapping( key=$0, value=$2 )",
    93: "$alias = :as :identifier -> $1",
    94: "$_gen27 = $wf_output $_gen28",
    95: "$_gen28 = :comma $wf_output $_gen28",
    96: "$_gen28 = :_empty",
    97: "$_gen27 = :_empty",
    98: "$wf_outputs = :output :lbrace $_gen27 :rbrace -> WorkflowOutputs( outputs=$2 )",
    99: "$_gen29 = $wf_output_wildcard",
    100: "$_gen29 = :_empty",
    101: "$wf_output = :fqn $_gen29 -> WorkflowOutput( fqn=$0, wildcard=$1 )",
    102: "$wf_output_wildcard = :dot :asterisk -> $1",
    103: "$while_loop = :while :lparen $e :rparen :lbrace $_gen19 :rbrace -> WhileLoop( expression=$2, body=$5 )",
    104: "$if_stmt = :if :lparen $e :rparen :lbrace $_gen19 :rbrace -> If( expression=$2, body=$5 )",
    105: "$scatter = :scatter :lparen :identifier :in $e :rparen :lbrace $_gen19 :rbrace -> Scatter( item=$2, collection=$4, body=$7 )",
    106: "$object_kv = :identifier :colon $e -> ObjectKV( key=$0, value=$2 )",
    107: "$_gen30 = $type_e $_gen31",
    108: "$_gen31 = :comma $type_e $_gen31",
    109: "$_gen31 = :_empty",
    110: "$_gen30 = :_empty",
    111: "$type_e = :type <=> :lsquare $_gen30 :rsquare -> Type( name=$0, subtype=$2 )",
    112: "$type_e = :type",
    113: "$e = $e :double_pipe $e -> LogicalOr( lhs=$0, rhs=$2 )",
    114: "$e = $e :double_ampersand $e -> LogicalAnd( lhs=$0, rhs=$2 )",
    115: "$e = $e :double_equal $e -> Equals( lhs=$0, rhs=$2 )",
    116: "$e = $e :not_equal $e -> NotEquals( lhs=$0, rhs=$2 )",
    117: "$e = $e :lt $e -> LessThan( lhs=$0, rhs=$2 )",
    118: "$e = $e :lteq $e -> LessThanOrEqual( lhs=$0, rhs=$2 )",
    119: "$e = $e :gt $e -> GreaterThan( lhs=$0, rhs=$2 )",
    120: "$e = $e :gteq $e -> GreaterThanOrEqual( lhs=$0, rhs=$2 )",
    121: "$e = $e :plus $e -> Add( lhs=$0, rhs=$2 )",
    122: "$e = $e :dash $e -> Subtract( lhs=$0, rhs=$2 )",
    123: "$e = $e :asterisk $e -> Multiply( lhs=$0, rhs=$2 )",
    124: "$e = $e :slash $e -> Divide( lhs=$0, rhs=$2 )",
    125: "$e = $e :percent $e -> Remainder( lhs=$0, rhs=$2 )",
    126: "$e = :not $e -> LogicalNot( expression=$1 )",
    127: "$e = :plus $e -> UnaryPlus( expression=$1 )",
    128: "$e = :dash $e -> UnaryNegation( expression=$1 )",
    129: "$_gen32 = $e $_gen33",
    130: "$_gen33 = :comma $e $_gen33",
    131: "$_gen33 = :_empty",
    132: "$_gen32 = :_empty",
    133: "$e = :identifier <=> :lparen $_gen32 :rparen -> FunctionCall( name=$0, params=$2 )",
    134: "$e = :identifier <=> :lsquare $e :rsquare -> ArrayOrMapLookup( lhs=$0, rhs=$2 )",
    135: "$e = :identifier <=> :dot :identifier -> MemberAccess( lhs=$0, rhs=$2 )",
    136: "$_gen34 = $object_kv $_gen35",
    137: "$_gen35 = :comma $object_kv $_gen35",
    138: "$_gen35 = :_empty",
    139: "$_gen34 = :_empty",
    140: "$e = :object :lbrace $_gen34 :rbrace -> ObjectLiteral( map=$2 )",
    141: "$e = :lsquare $_gen32 :rsquare -> ArrayLiteral( values=$1 )",
    142: "$_gen36 = $map_kv $_gen37",
    143: "$_gen37 = :comma $map_kv $_gen37",
    144: "$_gen37 = :_empty",
    145: "$_gen36 = :_empty",
    146: "$e = :lbrace $_gen36 :rbrace -> MapLiteral( map=$1 )",
    147: "$e = :lparen $e :rparen -> $1",
    148: "$e = :string",
    149: "$e = :identifier",
    150: "$e = :boolean",
    151: "$e = :integer",
    152: "$e = :float",
}
def is_terminal(id): return isinstance(id, int) and 0 <= id <= 55
def parse(tokens, errors=None, start=None):
    if errors is None:
        errors = DefaultSyntaxErrorHandler()
    if isinstance(tokens, str):
        tokens = lex(tokens, 'string', errors)
    ctx = ParserContext(tokens, errors)
    tree = parse_document(ctx)
    if tokens.current() != None:
        raise ctx.errors.excess_tokens()
    return tree
def expect(ctx, terminal_id):
    current = ctx.tokens.current()
    if not current:
        raise ctx.errors.no_more_tokens(ctx.nonterminal, terminals[terminal_id], ctx.tokens.last())
    if current.id != terminal_id:
        raise ctx.errors.unexpected_symbol(ctx.nonterminal, current, [terminals[terminal_id]], ctx.rule)
    next = ctx.tokens.advance()
    if next and not is_terminal(next.id):
        raise ctx.errors.invalid_terminal(ctx.nonterminal, next)
    return current
# START definitions for expression parser: e
infix_binding_power_e = {
    27: 2000, # $e = $e :double_pipe $e -> LogicalOr( lhs=$0, rhs=$2 )
    2: 3000, # $e = $e :double_ampersand $e -> LogicalAnd( lhs=$0, rhs=$2 )
    43: 4000, # $e = $e :double_equal $e -> Equals( lhs=$0, rhs=$2 )
    51: 4000, # $e = $e :not_equal $e -> NotEquals( lhs=$0, rhs=$2 )
    50: 5000, # $e = $e :lt $e -> LessThan( lhs=$0, rhs=$2 )
    18: 5000, # $e = $e :lteq $e -> LessThanOrEqual( lhs=$0, rhs=$2 )
    32: 5000, # $e = $e :gt $e -> GreaterThan( lhs=$0, rhs=$2 )
    34: 5000, # $e = $e :gteq $e -> GreaterThanOrEqual( lhs=$0, rhs=$2 )
    11: 6000, # $e = $e :plus $e -> Add( lhs=$0, rhs=$2 )
    14: 6000, # $e = $e :dash $e -> Subtract( lhs=$0, rhs=$2 )
    20: 7000, # $e = $e :asterisk $e -> Multiply( lhs=$0, rhs=$2 )
    49: 7000, # $e = $e :slash $e -> Divide( lhs=$0, rhs=$2 )
    42: 7000, # $e = $e :percent $e -> Remainder( lhs=$0, rhs=$2 )
    9: 9000, # $e = :identifier <=> :lparen list(nt=$e, sep=:comma, min=0, sep_terminates=False) :rparen -> FunctionCall( name=$0, params=$2 )
    4: 10000, # $e = :identifier <=> :lsquare $e :rsquare -> ArrayOrMapLookup( lhs=$0, rhs=$2 )
    46: 11000, # $e = :identifier <=> :dot :identifier -> MemberAccess( lhs=$0, rhs=$2 )
}
prefix_binding_power_e = {
    22: 8000, # $e = :not $e -> LogicalNot( expression=$1 )
    11: 8000, # $e = :plus $e -> UnaryPlus( expression=$1 )
    14: 8000, # $e = :dash $e -> UnaryNegation( expression=$1 )
}
def get_infix_binding_power_e(terminal_id):
    try:
        return infix_binding_power_e[terminal_id]
    except:
        return 0
def get_prefix_binding_power_e(terminal_id):
    try:
        return prefix_binding_power_e[terminal_id]
    except:
        return 0
def parse_e(ctx):
    return parse_e_internal(ctx, rbp=0)
def parse_e_internal(ctx, rbp=0):
    left = nud_e(ctx)
    if isinstance(left, ParseTree):
        left.isExpr = True
        left.isNud = True
    while ctx.tokens.current() and rbp < get_infix_binding_power_e(ctx.tokens.current().id):
        left = led_e(left, ctx)
    if left:
        left.isExpr = True
    return left
def nud_e(ctx):
    tree = ParseTree(NonTerminal(109, 'e'))
    current = ctx.tokens.current()
    ctx.nonterminal = "e"
    if not current:
        return tree
    elif current.id in rule_first[126]:
        # $e = :not $e -> LogicalNot( expression=$1 )
        ctx.rule = rules[126]
        ast_parameters = OrderedDict([
            ('expression', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('LogicalNot', ast_parameters)
        tree.nudMorphemeCount = 2
        tree.add(expect(ctx, 22))
        tree.add(parse_e_internal(ctx, get_prefix_binding_power_e(22)))
        tree.isPrefix = True
    elif current.id in rule_first[127]:
        # $e = :plus $e -> UnaryPlus( expression=$1 )
        ctx.rule = rules[127]
        ast_parameters = OrderedDict([
            ('expression', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('UnaryPlus', ast_parameters)
        tree.nudMorphemeCount = 2
        tree.add(expect(ctx, 11))
        tree.add(parse_e_internal(ctx, get_prefix_binding_power_e(11)))
        tree.isPrefix = True
    elif current.id in rule_first[128]:
        # $e = :dash $e -> UnaryNegation( expression=$1 )
        ctx.rule = rules[128]
        ast_parameters = OrderedDict([
            ('expression', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('UnaryNegation', ast_parameters)
        tree.nudMorphemeCount = 2
        tree.add(expect(ctx, 14))
        tree.add(parse_e_internal(ctx, get_prefix_binding_power_e(14)))
        tree.isPrefix = True
    elif current.id in rule_first[133]:
        # $e = :identifier <=> :lparen $_gen32 :rparen -> FunctionCall( name=$0, params=$2 )
        ctx.rule = rules[133]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 33))
    elif current.id in rule_first[134]:
        # $e = :identifier <=> :lsquare $e :rsquare -> ArrayOrMapLookup( lhs=$0, rhs=$2 )
        ctx.rule = rules[134]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 33))
    elif current.id in rule_first[135]:
        # $e = :identifier <=> :dot :identifier -> MemberAccess( lhs=$0, rhs=$2 )
        ctx.rule = rules[135]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 33))
    elif current.id in rule_first[140]:
        # $e = :object :lbrace $_gen34 :rbrace -> ObjectLiteral( map=$2 )
        ctx.rule = rules[140]
        ast_parameters = OrderedDict([
            ('map', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('ObjectLiteral', ast_parameters)
        tree.nudMorphemeCount = 4
        tree.add(expect(ctx, 26))
        tree.add(expect(ctx, 15))
        tree.add(parse__gen34(ctx))
        tree.add(expect(ctx, 47))
    elif current.id in rule_first[141]:
        # $e = :lsquare $_gen32 :rsquare -> ArrayLiteral( values=$1 )
        ctx.rule = rules[141]
        ast_parameters = OrderedDict([
            ('values', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('ArrayLiteral', ast_parameters)
        tree.nudMorphemeCount = 3
        tree.add(expect(ctx, 4))
        tree.add(parse__gen32(ctx))
        tree.add(expect(ctx, 10))
    elif current.id in rule_first[146]:
        # $e = :lbrace $_gen36 :rbrace -> MapLiteral( map=$1 )
        ctx.rule = rules[146]
        ast_parameters = OrderedDict([
            ('map', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('MapLiteral', ast_parameters)
        tree.nudMorphemeCount = 3
        tree.add(expect(ctx, 15))
        tree.add(parse__gen36(ctx))
        tree.add(expect(ctx, 47))
    elif current.id in rule_first[147]:
        # $e = :lparen $e :rparen -> $1
        ctx.rule = rules[147]
        tree.astTransform = AstTransformSubstitution(1)
        tree.nudMorphemeCount = 3
        tree.add(expect(ctx, 9))
        tree.add(parse_e(ctx))
        tree.add(expect(ctx, 38))
    elif current.id in rule_first[148]:
        # $e = :string
        ctx.rule = rules[148]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 44))
    elif current.id in rule_first[149]:
        # $e = :identifier
        ctx.rule = rules[149]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 33))
    elif current.id in rule_first[150]:
        # $e = :boolean
        ctx.rule = rules[150]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 39))
    elif current.id in rule_first[151]:
        # $e = :integer
        ctx.rule = rules[151]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 25))
    elif current.id in rule_first[152]:
        # $e = :float
        ctx.rule = rules[152]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 5))
    return tree
def led_e(left, ctx):
    tree = ParseTree(NonTerminal(109, 'e'))
    current = ctx.tokens.current()
    ctx.nonterminal = "e"
    if current.id == 27: # :double_pipe
        # $e = $e :double_pipe $e -> LogicalOr( lhs=$0, rhs=$2 )
        ctx.rule = rules[113]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('LogicalOr', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 27)) # :double_pipe
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(27) - modifier))
    if current.id == 2: # :double_ampersand
        # $e = $e :double_ampersand $e -> LogicalAnd( lhs=$0, rhs=$2 )
        ctx.rule = rules[114]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('LogicalAnd', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 2)) # :double_ampersand
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(2) - modifier))
    if current.id == 43: # :double_equal
        # $e = $e :double_equal $e -> Equals( lhs=$0, rhs=$2 )
        ctx.rule = rules[115]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Equals', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 43)) # :double_equal
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(43) - modifier))
    if current.id == 51: # :not_equal
        # $e = $e :not_equal $e -> NotEquals( lhs=$0, rhs=$2 )
        ctx.rule = rules[116]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('NotEquals', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 51)) # :not_equal
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(51) - modifier))
    if current.id == 50: # :lt
        # $e = $e :lt $e -> LessThan( lhs=$0, rhs=$2 )
        ctx.rule = rules[117]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('LessThan', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 50)) # :lt
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(50) - modifier))
    if current.id == 18: # :lteq
        # $e = $e :lteq $e -> LessThanOrEqual( lhs=$0, rhs=$2 )
        ctx.rule = rules[118]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('LessThanOrEqual', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 18)) # :lteq
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(18) - modifier))
    if current.id == 32: # :gt
        # $e = $e :gt $e -> GreaterThan( lhs=$0, rhs=$2 )
        ctx.rule = rules[119]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('GreaterThan', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 32)) # :gt
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(32) - modifier))
    if current.id == 34: # :gteq
        # $e = $e :gteq $e -> GreaterThanOrEqual( lhs=$0, rhs=$2 )
        ctx.rule = rules[120]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('GreaterThanOrEqual', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 34)) # :gteq
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(34) - modifier))
    if current.id == 11: # :plus
        # $e = $e :plus $e -> Add( lhs=$0, rhs=$2 )
        ctx.rule = rules[121]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Add', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 11)) # :plus
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(11) - modifier))
    if current.id == 14: # :dash
        # $e = $e :dash $e -> Subtract( lhs=$0, rhs=$2 )
        ctx.rule = rules[122]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Subtract', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 14)) # :dash
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(14) - modifier))
    if current.id == 20: # :asterisk
        # $e = $e :asterisk $e -> Multiply( lhs=$0, rhs=$2 )
        ctx.rule = rules[123]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Multiply', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 20)) # :asterisk
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(20) - modifier))
    if current.id == 49: # :slash
        # $e = $e :slash $e -> Divide( lhs=$0, rhs=$2 )
        ctx.rule = rules[124]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Divide', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 49)) # :slash
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(49) - modifier))
    if current.id == 42: # :percent
        # $e = $e :percent $e -> Remainder( lhs=$0, rhs=$2 )
        ctx.rule = rules[125]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Remainder', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 42)) # :percent
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(42) - modifier))
    if current.id == 9: # :lparen
        # $e = :identifier <=> :lparen $_gen32 :rparen -> FunctionCall( name=$0, params=$2 )
        ctx.rule = rules[133]
        ast_parameters = OrderedDict([
            ('name', 0),
            ('params', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('FunctionCall', ast_parameters)
        tree.add(left)
        tree.add(expect(ctx, 9)) # :lparen
        tree.add(parse__gen32(ctx))
        tree.add(expect(ctx, 38)) # :rparen
    if current.id == 4: # :lsquare
        # $e = :identifier <=> :lsquare $e :rsquare -> ArrayOrMapLookup( lhs=$0, rhs=$2 )
        ctx.rule = rules[134]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('ArrayOrMapLookup', ast_parameters)
        tree.add(left)
        tree.add(expect(ctx, 4)) # :lsquare
        modifier = 0
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(4) - modifier))
        tree.add(expect(ctx, 10)) # :rsquare
    if current.id == 46: # :dot
        # $e = :identifier <=> :dot :identifier -> MemberAccess( lhs=$0, rhs=$2 )
        ctx.rule = rules[135]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('MemberAccess', ast_parameters)
        tree.add(left)
        tree.add(expect(ctx, 46)) # :dot
        tree.add(expect(ctx, 33)) # :identifier
    return tree
# END definitions for expression parser: e
# START definitions for expression parser: type_e
infix_binding_power_type_e = {
    4: 1000, # $type_e = :type <=> :lsquare list(nt=$type_e, sep=:comma, min=0, sep_terminates=False) :rsquare -> Type( name=$0, subtype=$2 )
}
prefix_binding_power_type_e = {
}
def get_infix_binding_power_type_e(terminal_id):
    try:
        return infix_binding_power_type_e[terminal_id]
    except:
        return 0
def get_prefix_binding_power_type_e(terminal_id):
    try:
        return prefix_binding_power_type_e[terminal_id]
    except:
        return 0
def parse_type_e(ctx):
    return parse_type_e_internal(ctx, rbp=0)
def parse_type_e_internal(ctx, rbp=0):
    left = nud_type_e(ctx)
    if isinstance(left, ParseTree):
        left.isExpr = True
        left.isNud = True
    while ctx.tokens.current() and rbp < get_infix_binding_power_type_e(ctx.tokens.current().id):
        left = led_type_e(left, ctx)
    if left:
        left.isExpr = True
    return left
def nud_type_e(ctx):
    tree = ParseTree(NonTerminal(85, 'type_e'))
    current = ctx.tokens.current()
    ctx.nonterminal = "type_e"
    if not current:
        return tree
    if current.id in rule_first[111]:
        # $type_e = :type <=> :lsquare $_gen30 :rsquare -> Type( name=$0, subtype=$2 )
        ctx.rule = rules[111]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 1))
    elif current.id in rule_first[112]:
        # $type_e = :type
        ctx.rule = rules[112]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 1))
    return tree
def led_type_e(left, ctx):
    tree = ParseTree(NonTerminal(85, 'type_e'))
    current = ctx.tokens.current()
    ctx.nonterminal = "type_e"
    if current.id == 4: # :lsquare
        # $type_e = :type <=> :lsquare $_gen30 :rsquare -> Type( name=$0, subtype=$2 )
        ctx.rule = rules[111]
        ast_parameters = OrderedDict([
            ('name', 0),
            ('subtype', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Type', ast_parameters)
        tree.add(left)
        tree.add(expect(ctx, 4)) # :lsquare
        tree.add(parse__gen30(ctx))
        tree.add(expect(ctx, 10)) # :rsquare
    return tree
# END definitions for expression parser: type_e
def parse_parameter_meta(ctx):
    current = ctx.tokens.current()
    rule = table[0][current.id] if current else -1
    tree = ParseTree(NonTerminal(56, 'parameter_meta'))
    ctx.nonterminal = "parameter_meta"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 49: # $parameter_meta = :parameter_meta $map -> ParameterMeta( map=$1 )
        ctx.rule = rules[49]
        ast_parameters = OrderedDict([
            ('map', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('ParameterMeta', ast_parameters)
        t = expect(ctx, 8) # :parameter_meta
        tree.add(t)
        subtree = parse_map(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[56] if x >=0],
      rules[49]
    )
def parse_sections(ctx):
    current = ctx.tokens.current()
    rule = table[1][current.id] if current else -1
    tree = ParseTree(NonTerminal(57, 'sections'))
    ctx.nonterminal = "sections"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 24: # $sections = $command
        ctx.rule = rules[24]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_command(ctx)
        tree.add(subtree)
        return tree
    elif rule == 25: # $sections = $outputs
        ctx.rule = rules[25]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_outputs(ctx)
        tree.add(subtree)
        return tree
    elif rule == 26: # $sections = $runtime
        ctx.rule = rules[26]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_runtime(ctx)
        tree.add(subtree)
        return tree
    elif rule == 27: # $sections = $parameter_meta
        ctx.rule = rules[27]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_parameter_meta(ctx)
        tree.add(subtree)
        return tree
    elif rule == 28: # $sections = $meta
        ctx.rule = rules[28]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_meta(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[57] if x >=0],
      rules[28]
    )
def parse_wf_outputs(ctx):
    current = ctx.tokens.current()
    rule = table[2][current.id] if current else -1
    tree = ParseTree(NonTerminal(58, 'wf_outputs'))
    ctx.nonterminal = "wf_outputs"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 98: # $wf_outputs = :output :lbrace $_gen27 :rbrace -> WorkflowOutputs( outputs=$2 )
        ctx.rule = rules[98]
        ast_parameters = OrderedDict([
            ('outputs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('WorkflowOutputs', ast_parameters)
        t = expect(ctx, 23) # :output
        tree.add(t)
        t = expect(ctx, 15) # :lbrace
        tree.add(t)
        subtree = parse__gen27(ctx)
        tree.add(subtree)
        t = expect(ctx, 47) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[58] if x >=0],
      rules[98]
    )
def parse__gen14(ctx):
    current = ctx.tokens.current()
    rule = table[3][current.id] if current else -1
    tree = ParseTree(NonTerminal(59, '_gen14'))
    ctx.nonterminal = "_gen14"
    tree.list = True
    if current != None and current.id in nonterminal_follow[59] and current.id not in nonterminal_first[59]:
        return tree
    if current == None:
        return tree
    if rule == 43: # $_gen14 = $output_kv $_gen14
        ctx.rule = rules[43]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_output_kv(ctx)
        tree.add(subtree)
        subtree = parse__gen14(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_import_namespace(ctx):
    current = ctx.tokens.current()
    rule = table[4][current.id] if current else -1
    tree = ParseTree(NonTerminal(60, 'import_namespace'))
    ctx.nonterminal = "import_namespace"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 14: # $import_namespace = :as :identifier -> $1
        ctx.rule = rules[14]
        tree.astTransform = AstTransformSubstitution(1)
        t = expect(ctx, 40) # :as
        tree.add(t)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[60] if x >=0],
      rules[14]
    )
def parse_alias(ctx):
    current = ctx.tokens.current()
    rule = table[5][current.id] if current else -1
    tree = ParseTree(NonTerminal(61, 'alias'))
    ctx.nonterminal = "alias"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 93: # $alias = :as :identifier -> $1
        ctx.rule = rules[93]
        tree.astTransform = AstTransformSubstitution(1)
        t = expect(ctx, 40) # :as
        tree.add(t)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[61] if x >=0],
      rules[93]
    )
def parse__gen23(ctx):
    current = ctx.tokens.current()
    rule = table[6][current.id] if current else -1
    tree = ParseTree(NonTerminal(62, '_gen23'))
    ctx.nonterminal = "_gen23"
    tree.list = True
    if current != None and current.id in nonterminal_follow[62] and current.id not in nonterminal_first[62]:
        return tree
    if current == None:
        return tree
    if rule == 82: # $_gen23 = $call_input $_gen24
        ctx.rule = rules[82]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_call_input(ctx)
        tree.add(subtree)
        subtree = parse__gen24(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen11(ctx):
    current = ctx.tokens.current()
    rule = table[7][current.id] if current else -1
    tree = ParseTree(NonTerminal(63, '_gen11'))
    ctx.nonterminal = "_gen11"
    tree.list = True
    if current != None and current.id in nonterminal_follow[63] and current.id not in nonterminal_first[63]:
        return tree
    if current == None:
        return tree
    if rule == 36: # $_gen11 = $cmd_param_kv $_gen12
        ctx.rule = rules[36]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_cmd_param_kv(ctx)
        tree.add(subtree)
        subtree = parse__gen12(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen20(ctx):
    current = ctx.tokens.current()
    rule = table[8][current.id] if current else -1
    tree = ParseTree(NonTerminal(64, '_gen20'))
    ctx.nonterminal = "_gen20"
    tree.list = True
    if current != None and current.id in nonterminal_follow[64] and current.id not in nonterminal_first[64]:
        return tree
    if current == None:
        return tree
    if rule == 67: # $_gen20 = $wf_body_element $_gen20
        ctx.rule = rules[67]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_wf_body_element(ctx)
        tree.add(subtree)
        subtree = parse__gen20(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_kv(ctx):
    current = ctx.tokens.current()
    rule = table[9][current.id] if current else -1
    tree = ParseTree(NonTerminal(65, 'kv'))
    ctx.nonterminal = "kv"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 56: # $kv = :identifier :colon $e -> RuntimeAttribute( key=$0, value=$2 )
        ctx.rule = rules[56]
        ast_parameters = OrderedDict([
            ('key', 0),
            ('value', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('RuntimeAttribute', ast_parameters)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 12) # :colon
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[65] if x >=0],
      rules[56]
    )
def parse__gen32(ctx):
    current = ctx.tokens.current()
    rule = table[10][current.id] if current else -1
    tree = ParseTree(NonTerminal(66, '_gen32'))
    ctx.nonterminal = "_gen32"
    tree.list = True
    if current != None and current.id in nonterminal_follow[66] and current.id not in nonterminal_first[66]:
        return tree
    if current == None:
        return tree
    if rule == 129: # $_gen32 = $e $_gen33
        ctx.rule = rules[129]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_e(ctx)
        tree.add(subtree)
        subtree = parse__gen33(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_scatter(ctx):
    current = ctx.tokens.current()
    rule = table[11][current.id] if current else -1
    tree = ParseTree(NonTerminal(67, 'scatter'))
    ctx.nonterminal = "scatter"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 105: # $scatter = :scatter :lparen :identifier :in $e :rparen :lbrace $_gen19 :rbrace -> Scatter( item=$2, collection=$4, body=$7 )
        ctx.rule = rules[105]
        ast_parameters = OrderedDict([
            ('item', 2),
            ('collection', 4),
            ('body', 7),
        ])
        tree.astTransform = AstTransformNodeCreator('Scatter', ast_parameters)
        t = expect(ctx, 13) # :scatter
        tree.add(t)
        t = expect(ctx, 9) # :lparen
        tree.add(t)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 28) # :in
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 38) # :rparen
        tree.add(t)
        t = expect(ctx, 15) # :lbrace
        tree.add(t)
        subtree = parse__gen19(ctx)
        tree.add(subtree)
        t = expect(ctx, 47) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[67] if x >=0],
      rules[105]
    )
def parse__gen26(ctx):
    current = ctx.tokens.current()
    rule = table[12][current.id] if current else -1
    tree = ParseTree(NonTerminal(68, '_gen26'))
    ctx.nonterminal = "_gen26"
    tree.list = True
    if current != None and current.id in nonterminal_follow[68] and current.id not in nonterminal_first[68]:
        return tree
    if current == None:
        return tree
    if rule == 88: # $_gen26 = :comma $mapping $_gen26
        ctx.rule = rules[88]
        tree.astTransform = AstTransformSubstitution(0)
        t = expect(ctx, 37) # :comma
        tree.add(t)
        tree.listSeparator = t
        subtree = parse_mapping(ctx)
        tree.add(subtree)
        subtree = parse__gen26(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_wf_output_wildcard(ctx):
    current = ctx.tokens.current()
    rule = table[13][current.id] if current else -1
    tree = ParseTree(NonTerminal(69, 'wf_output_wildcard'))
    ctx.nonterminal = "wf_output_wildcard"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 102: # $wf_output_wildcard = :dot :asterisk -> $1
        ctx.rule = rules[102]
        tree.astTransform = AstTransformSubstitution(1)
        t = expect(ctx, 46) # :dot
        tree.add(t)
        t = expect(ctx, 20) # :asterisk
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[69] if x >=0],
      rules[102]
    )
def parse_output_kv(ctx):
    current = ctx.tokens.current()
    rule = table[14][current.id] if current else -1
    tree = ParseTree(NonTerminal(70, 'output_kv'))
    ctx.nonterminal = "output_kv"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 47: # $output_kv = $type_e :identifier :equal $e -> Output( type=$0, var=$1, expression=$3 )
        ctx.rule = rules[47]
        ast_parameters = OrderedDict([
            ('type', 0),
            ('var', 1),
            ('expression', 3),
        ])
        tree.astTransform = AstTransformNodeCreator('Output', ast_parameters)
        subtree = parse_type_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 52) # :equal
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[70] if x >=0],
      rules[47]
    )
def parse_outputs(ctx):
    current = ctx.tokens.current()
    rule = table[15][current.id] if current else -1
    tree = ParseTree(NonTerminal(71, 'outputs'))
    ctx.nonterminal = "outputs"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 46: # $outputs = :output :lbrace $_gen13 :rbrace -> Outputs( attributes=$2 )
        ctx.rule = rules[46]
        ast_parameters = OrderedDict([
            ('attributes', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Outputs', ast_parameters)
        t = expect(ctx, 23) # :output
        tree.add(t)
        t = expect(ctx, 15) # :lbrace
        tree.add(t)
        subtree = parse__gen13(ctx)
        tree.add(subtree)
        t = expect(ctx, 47) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[71] if x >=0],
      rules[46]
    )
def parse__gen24(ctx):
    current = ctx.tokens.current()
    rule = table[16][current.id] if current else -1
    tree = ParseTree(NonTerminal(72, '_gen24'))
    ctx.nonterminal = "_gen24"
    tree.list = True
    if current != None and current.id in nonterminal_follow[72] and current.id not in nonterminal_first[72]:
        return tree
    if current == None:
        return tree
    if rule == 83: # $_gen24 = $call_input $_gen24
        ctx.rule = rules[83]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_call_input(ctx)
        tree.add(subtree)
        subtree = parse__gen24(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_wf_output(ctx):
    current = ctx.tokens.current()
    rule = table[17][current.id] if current else -1
    tree = ParseTree(NonTerminal(73, 'wf_output'))
    ctx.nonterminal = "wf_output"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 101: # $wf_output = :fqn $_gen29 -> WorkflowOutput( fqn=$0, wildcard=$1 )
        ctx.rule = rules[101]
        ast_parameters = OrderedDict([
            ('fqn', 0),
            ('wildcard', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('WorkflowOutput', ast_parameters)
        t = expect(ctx, 41) # :fqn
        tree.add(t)
        subtree = parse__gen29(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[73] if x >=0],
      rules[101]
    )
def parse_workflow_or_task(ctx):
    current = ctx.tokens.current()
    rule = table[18][current.id] if current else -1
    tree = ParseTree(NonTerminal(74, 'workflow_or_task'))
    ctx.nonterminal = "workflow_or_task"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 9: # $workflow_or_task = $workflow
        ctx.rule = rules[9]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_workflow(ctx)
        tree.add(subtree)
        return tree
    elif rule == 10: # $workflow_or_task = $task
        ctx.rule = rules[10]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_task(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[74] if x >=0],
      rules[10]
    )
def parse__gen28(ctx):
    current = ctx.tokens.current()
    rule = table[19][current.id] if current else -1
    tree = ParseTree(NonTerminal(75, '_gen28'))
    ctx.nonterminal = "_gen28"
    tree.list = True
    if current != None and current.id in nonterminal_follow[75] and current.id not in nonterminal_first[75]:
        return tree
    if current == None:
        return tree
    if rule == 95: # $_gen28 = :comma $wf_output $_gen28
        ctx.rule = rules[95]
        tree.astTransform = AstTransformSubstitution(0)
        t = expect(ctx, 37) # :comma
        tree.add(t)
        tree.listSeparator = t
        subtree = parse_wf_output(ctx)
        tree.add(subtree)
        subtree = parse__gen28(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_call(ctx):
    current = ctx.tokens.current()
    rule = table[20][current.id] if current else -1
    tree = ParseTree(NonTerminal(76, 'call'))
    ctx.nonterminal = "call"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 81: # $call = :call :fqn $_gen21 $_gen22 -> Call( task=$1, alias=$2, body=$3 )
        ctx.rule = rules[81]
        ast_parameters = OrderedDict([
            ('task', 1),
            ('alias', 2),
            ('body', 3),
        ])
        tree.astTransform = AstTransformNodeCreator('Call', ast_parameters)
        t = expect(ctx, 36) # :call
        tree.add(t)
        t = expect(ctx, 41) # :fqn
        tree.add(t)
        subtree = parse__gen21(ctx)
        tree.add(subtree)
        subtree = parse__gen22(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[76] if x >=0],
      rules[81]
    )
def parse__gen17(ctx):
    current = ctx.tokens.current()
    rule = table[21][current.id] if current else -1
    tree = ParseTree(NonTerminal(77, '_gen17'))
    ctx.nonterminal = "_gen17"
    tree.list = False
    if current != None and current.id in nonterminal_follow[77] and current.id not in nonterminal_first[77]:
        return tree
    if current == None:
        return tree
    if rule == 57: # $_gen17 = $postfix_quantifier
        ctx.rule = rules[57]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_postfix_quantifier(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_while_loop(ctx):
    current = ctx.tokens.current()
    rule = table[22][current.id] if current else -1
    tree = ParseTree(NonTerminal(78, 'while_loop'))
    ctx.nonterminal = "while_loop"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 103: # $while_loop = :while :lparen $e :rparen :lbrace $_gen19 :rbrace -> WhileLoop( expression=$2, body=$5 )
        ctx.rule = rules[103]
        ast_parameters = OrderedDict([
            ('expression', 2),
            ('body', 5),
        ])
        tree.astTransform = AstTransformNodeCreator('WhileLoop', ast_parameters)
        t = expect(ctx, 45) # :while
        tree.add(t)
        t = expect(ctx, 9) # :lparen
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 38) # :rparen
        tree.add(t)
        t = expect(ctx, 15) # :lbrace
        tree.add(t)
        subtree = parse__gen19(ctx)
        tree.add(subtree)
        t = expect(ctx, 47) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[78] if x >=0],
      rules[103]
    )
def parse_postfix_quantifier(ctx):
    current = ctx.tokens.current()
    rule = table[23][current.id] if current else -1
    tree = ParseTree(NonTerminal(79, 'postfix_quantifier'))
    ctx.nonterminal = "postfix_quantifier"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 63: # $postfix_quantifier = :qmark
        ctx.rule = rules[63]
        tree.astTransform = AstTransformSubstitution(0)
        t = expect(ctx, 17) # :qmark
        tree.add(t)
        return tree
    elif rule == 64: # $postfix_quantifier = :plus
        ctx.rule = rules[64]
        tree.astTransform = AstTransformSubstitution(0)
        t = expect(ctx, 11) # :plus
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[79] if x >=0],
      rules[64]
    )
def parse__gen18(ctx):
    current = ctx.tokens.current()
    rule = table[24][current.id] if current else -1
    tree = ParseTree(NonTerminal(80, '_gen18'))
    ctx.nonterminal = "_gen18"
    tree.list = False
    if current != None and current.id in nonterminal_follow[80] and current.id not in nonterminal_first[80]:
        return tree
    if current == None:
        return tree
    if rule == 59: # $_gen18 = $setter
        ctx.rule = rules[59]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_setter(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_wf_body_element(ctx):
    current = ctx.tokens.current()
    rule = table[25][current.id] if current else -1
    tree = ParseTree(NonTerminal(81, 'wf_body_element'))
    ctx.nonterminal = "wf_body_element"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 71: # $wf_body_element = $call
        ctx.rule = rules[71]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_call(ctx)
        tree.add(subtree)
        return tree
    elif rule == 72: # $wf_body_element = $declaration
        ctx.rule = rules[72]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_declaration(ctx)
        tree.add(subtree)
        return tree
    elif rule == 73: # $wf_body_element = $while_loop
        ctx.rule = rules[73]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_while_loop(ctx)
        tree.add(subtree)
        return tree
    elif rule == 74: # $wf_body_element = $if_stmt
        ctx.rule = rules[74]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_if_stmt(ctx)
        tree.add(subtree)
        return tree
    elif rule == 75: # $wf_body_element = $scatter
        ctx.rule = rules[75]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_scatter(ctx)
        tree.add(subtree)
        return tree
    elif rule == 76: # $wf_body_element = $wf_outputs
        ctx.rule = rules[76]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_wf_outputs(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[81] if x >=0],
      rules[76]
    )
def parse__gen29(ctx):
    current = ctx.tokens.current()
    rule = table[26][current.id] if current else -1
    tree = ParseTree(NonTerminal(82, '_gen29'))
    ctx.nonterminal = "_gen29"
    tree.list = False
    if current != None and current.id in nonterminal_follow[82] and current.id not in nonterminal_first[82]:
        return tree
    if current == None:
        return tree
    if rule == 99: # $_gen29 = $wf_output_wildcard
        ctx.rule = rules[99]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_wf_output_wildcard(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen30(ctx):
    current = ctx.tokens.current()
    rule = table[27][current.id] if current else -1
    tree = ParseTree(NonTerminal(83, '_gen30'))
    ctx.nonterminal = "_gen30"
    tree.list = True
    if current != None and current.id in nonterminal_follow[83] and current.id not in nonterminal_first[83]:
        return tree
    if current == None:
        return tree
    if rule == 107: # $_gen30 = $type_e $_gen31
        ctx.rule = rules[107]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_type_e(ctx)
        tree.add(subtree)
        subtree = parse__gen31(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen16(ctx):
    current = ctx.tokens.current()
    rule = table[28][current.id] if current else -1
    tree = ParseTree(NonTerminal(84, '_gen16'))
    ctx.nonterminal = "_gen16"
    tree.list = True
    if current != None and current.id in nonterminal_follow[84] and current.id not in nonterminal_first[84]:
        return tree
    if current == None:
        return tree
    if rule == 52: # $_gen16 = $kv $_gen16
        ctx.rule = rules[52]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_kv(ctx)
        tree.add(subtree)
        subtree = parse__gen16(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_map(ctx):
    current = ctx.tokens.current()
    rule = table[30][current.id] if current else -1
    tree = ParseTree(NonTerminal(86, 'map'))
    ctx.nonterminal = "map"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 55: # $map = :lbrace $_gen15 :rbrace -> $1
        ctx.rule = rules[55]
        tree.astTransform = AstTransformSubstitution(1)
        t = expect(ctx, 15) # :lbrace
        tree.add(t)
        subtree = parse__gen15(ctx)
        tree.add(subtree)
        t = expect(ctx, 47) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[86] if x >=0],
      rules[55]
    )
def parse__gen13(ctx):
    current = ctx.tokens.current()
    rule = table[31][current.id] if current else -1
    tree = ParseTree(NonTerminal(87, '_gen13'))
    ctx.nonterminal = "_gen13"
    tree.list = True
    if current != None and current.id in nonterminal_follow[87] and current.id not in nonterminal_first[87]:
        return tree
    if current == None:
        return tree
    if rule == 42: # $_gen13 = $output_kv $_gen14
        ctx.rule = rules[42]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_output_kv(ctx)
        tree.add(subtree)
        subtree = parse__gen14(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_mapping(ctx):
    current = ctx.tokens.current()
    rule = table[32][current.id] if current else -1
    tree = ParseTree(NonTerminal(88, 'mapping'))
    ctx.nonterminal = "mapping"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 92: # $mapping = :identifier :equal $e -> IOMapping( key=$0, value=$2 )
        ctx.rule = rules[92]
        ast_parameters = OrderedDict([
            ('key', 0),
            ('value', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('IOMapping', ast_parameters)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 52) # :equal
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[88] if x >=0],
      rules[92]
    )
def parse__gen9(ctx):
    current = ctx.tokens.current()
    rule = table[33][current.id] if current else -1
    tree = ParseTree(NonTerminal(89, '_gen9'))
    ctx.nonterminal = "_gen9"
    tree.list = True
    if current != None and current.id in nonterminal_follow[89] and current.id not in nonterminal_first[89]:
        return tree
    if current == None:
        return tree
    if rule == 29: # $_gen9 = $command_part $_gen10
        ctx.rule = rules[29]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_command_part(ctx)
        tree.add(subtree)
        subtree = parse__gen10(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen0(ctx):
    current = ctx.tokens.current()
    rule = table[34][current.id] if current else -1
    tree = ParseTree(NonTerminal(90, '_gen0'))
    ctx.nonterminal = "_gen0"
    tree.list = True
    if current != None and current.id in nonterminal_follow[90] and current.id not in nonterminal_first[90]:
        return tree
    if current == None:
        return tree
    if rule == 0: # $_gen0 = $import $_gen1
        ctx.rule = rules[0]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_import(ctx)
        tree.add(subtree)
        subtree = parse__gen1(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen22(ctx):
    current = ctx.tokens.current()
    rule = table[35][current.id] if current else -1
    tree = ParseTree(NonTerminal(91, '_gen22'))
    ctx.nonterminal = "_gen22"
    tree.list = False
    if current != None and current.id in nonterminal_follow[91] and current.id not in nonterminal_first[91]:
        return tree
    if current == None:
        return tree
    if rule == 79: # $_gen22 = $call_body
        ctx.rule = rules[79]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_call_body(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_command_part(ctx):
    current = ctx.tokens.current()
    rule = table[36][current.id] if current else -1
    tree = ParseTree(NonTerminal(92, 'command_part'))
    ctx.nonterminal = "command_part"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 34: # $command_part = :cmd_part
        ctx.rule = rules[34]
        tree.astTransform = AstTransformSubstitution(0)
        t = expect(ctx, 6) # :cmd_part
        tree.add(t)
        return tree
    elif rule == 35: # $command_part = $cmd_param
        ctx.rule = rules[35]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_cmd_param(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[92] if x >=0],
      rules[35]
    )
def parse__gen12(ctx):
    current = ctx.tokens.current()
    rule = table[37][current.id] if current else -1
    tree = ParseTree(NonTerminal(93, '_gen12'))
    ctx.nonterminal = "_gen12"
    tree.list = True
    if current != None and current.id in nonterminal_follow[93] and current.id not in nonterminal_first[93]:
        return tree
    if current == None:
        return tree
    if rule == 37: # $_gen12 = $cmd_param_kv $_gen12
        ctx.rule = rules[37]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_cmd_param_kv(ctx)
        tree.add(subtree)
        subtree = parse__gen12(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_call_input(ctx):
    current = ctx.tokens.current()
    rule = table[38][current.id] if current else -1
    tree = ParseTree(NonTerminal(94, 'call_input'))
    ctx.nonterminal = "call_input"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 91: # $call_input = :input :colon $_gen25 -> Inputs( map=$2 )
        ctx.rule = rules[91]
        ast_parameters = OrderedDict([
            ('map', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Inputs', ast_parameters)
        t = expect(ctx, 48) # :input
        tree.add(t)
        t = expect(ctx, 12) # :colon
        tree.add(t)
        subtree = parse__gen25(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[94] if x >=0],
      rules[91]
    )
def parse__gen31(ctx):
    current = ctx.tokens.current()
    rule = table[39][current.id] if current else -1
    tree = ParseTree(NonTerminal(95, '_gen31'))
    ctx.nonterminal = "_gen31"
    tree.list = True
    if current != None and current.id in nonterminal_follow[95] and current.id not in nonterminal_first[95]:
        return tree
    if current == None:
        return tree
    if rule == 108: # $_gen31 = :comma $type_e $_gen31
        ctx.rule = rules[108]
        tree.astTransform = AstTransformSubstitution(0)
        t = expect(ctx, 37) # :comma
        tree.add(t)
        tree.listSeparator = t
        subtree = parse_type_e(ctx)
        tree.add(subtree)
        subtree = parse__gen31(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_map_kv(ctx):
    current = ctx.tokens.current()
    rule = table[40][current.id] if current else -1
    tree = ParseTree(NonTerminal(96, 'map_kv'))
    ctx.nonterminal = "map_kv"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 65: # $map_kv = $e :colon $e -> MapLiteralKv( key=$0, value=$2 )
        ctx.rule = rules[65]
        ast_parameters = OrderedDict([
            ('key', 0),
            ('value', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('MapLiteralKv', ast_parameters)
        subtree = parse_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 12) # :colon
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[96] if x >=0],
      rules[65]
    )
def parse_call_body(ctx):
    current = ctx.tokens.current()
    rule = table[41][current.id] if current else -1
    tree = ParseTree(NonTerminal(97, 'call_body'))
    ctx.nonterminal = "call_body"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 86: # $call_body = :lbrace $_gen5 $_gen23 :rbrace -> CallBody( declarations=$1, io=$2 )
        ctx.rule = rules[86]
        ast_parameters = OrderedDict([
            ('declarations', 1),
            ('io', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('CallBody', ast_parameters)
        t = expect(ctx, 15) # :lbrace
        tree.add(t)
        subtree = parse__gen5(ctx)
        tree.add(subtree)
        subtree = parse__gen23(ctx)
        tree.add(subtree)
        t = expect(ctx, 47) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[97] if x >=0],
      rules[86]
    )
def parse_cmd_param(ctx):
    current = ctx.tokens.current()
    rule = table[42][current.id] if current else -1
    tree = ParseTree(NonTerminal(98, 'cmd_param'))
    ctx.nonterminal = "cmd_param"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 40: # $cmd_param = :cmd_param_start $_gen11 $e :cmd_param_end -> CommandParameter( attributes=$1, expr=$2 )
        ctx.rule = rules[40]
        ast_parameters = OrderedDict([
            ('attributes', 1),
            ('expr', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('CommandParameter', ast_parameters)
        t = expect(ctx, 24) # :cmd_param_start
        tree.add(t)
        subtree = parse__gen11(ctx)
        tree.add(subtree)
        subtree = parse_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 16) # :cmd_param_end
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[98] if x >=0],
      rules[40]
    )
def parse_object_kv(ctx):
    current = ctx.tokens.current()
    rule = table[43][current.id] if current else -1
    tree = ParseTree(NonTerminal(99, 'object_kv'))
    ctx.nonterminal = "object_kv"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 106: # $object_kv = :identifier :colon $e -> ObjectKV( key=$0, value=$2 )
        ctx.rule = rules[106]
        ast_parameters = OrderedDict([
            ('key', 0),
            ('value', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('ObjectKV', ast_parameters)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 12) # :colon
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[99] if x >=0],
      rules[106]
    )
def parse_task(ctx):
    current = ctx.tokens.current()
    rule = table[44][current.id] if current else -1
    tree = ParseTree(NonTerminal(100, 'task'))
    ctx.nonterminal = "task"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 23: # $task = :task :identifier :lbrace $_gen5 $_gen7 :rbrace -> Task( name=$1, declarations=$3, sections=$4 )
        ctx.rule = rules[23]
        ast_parameters = OrderedDict([
            ('name', 1),
            ('declarations', 3),
            ('sections', 4),
        ])
        tree.astTransform = AstTransformNodeCreator('Task', ast_parameters)
        t = expect(ctx, 54) # :task
        tree.add(t)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 15) # :lbrace
        tree.add(t)
        subtree = parse__gen5(ctx)
        tree.add(subtree)
        subtree = parse__gen7(ctx)
        tree.add(subtree)
        t = expect(ctx, 47) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[100] if x >=0],
      rules[23]
    )
def parse__gen8(ctx):
    current = ctx.tokens.current()
    rule = table[45][current.id] if current else -1
    tree = ParseTree(NonTerminal(101, '_gen8'))
    ctx.nonterminal = "_gen8"
    tree.list = True
    if current != None and current.id in nonterminal_follow[101] and current.id not in nonterminal_first[101]:
        return tree
    if current == None:
        return tree
    if rule == 20: # $_gen8 = $sections $_gen8
        ctx.rule = rules[20]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_sections(ctx)
        tree.add(subtree)
        subtree = parse__gen8(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen4(ctx):
    current = ctx.tokens.current()
    rule = table[46][current.id] if current else -1
    tree = ParseTree(NonTerminal(102, '_gen4'))
    ctx.nonterminal = "_gen4"
    tree.list = False
    if current != None and current.id in nonterminal_follow[102] and current.id not in nonterminal_first[102]:
        return tree
    if current == None:
        return tree
    if rule == 11: # $_gen4 = $import_namespace
        ctx.rule = rules[11]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_import_namespace(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen2(ctx):
    current = ctx.tokens.current()
    rule = table[47][current.id] if current else -1
    tree = ParseTree(NonTerminal(103, '_gen2'))
    ctx.nonterminal = "_gen2"
    tree.list = True
    if current != None and current.id in nonterminal_follow[103] and current.id not in nonterminal_first[103]:
        return tree
    if current == None:
        return tree
    if rule == 4: # $_gen2 = $workflow_or_task $_gen3
        ctx.rule = rules[4]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_workflow_or_task(ctx)
        tree.add(subtree)
        subtree = parse__gen3(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen15(ctx):
    current = ctx.tokens.current()
    rule = table[48][current.id] if current else -1
    tree = ParseTree(NonTerminal(104, '_gen15'))
    ctx.nonterminal = "_gen15"
    tree.list = True
    if current != None and current.id in nonterminal_follow[104] and current.id not in nonterminal_first[104]:
        return tree
    if current == None:
        return tree
    if rule == 51: # $_gen15 = $kv $_gen16
        ctx.rule = rules[51]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_kv(ctx)
        tree.add(subtree)
        subtree = parse__gen16(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_import(ctx):
    current = ctx.tokens.current()
    rule = table[49][current.id] if current else -1
    tree = ParseTree(NonTerminal(105, 'import'))
    ctx.nonterminal = "import"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 13: # $import = :import :string $_gen4 -> Import( uri=$1, namespace=$2 )
        ctx.rule = rules[13]
        ast_parameters = OrderedDict([
            ('uri', 1),
            ('namespace', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Import', ast_parameters)
        t = expect(ctx, 7) # :import
        tree.add(t)
        t = expect(ctx, 44) # :string
        tree.add(t)
        subtree = parse__gen4(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[105] if x >=0],
      rules[13]
    )
def parse__gen21(ctx):
    current = ctx.tokens.current()
    rule = table[50][current.id] if current else -1
    tree = ParseTree(NonTerminal(106, '_gen21'))
    ctx.nonterminal = "_gen21"
    tree.list = False
    if current != None and current.id in nonterminal_follow[106] and current.id not in nonterminal_first[106]:
        return tree
    if current == None:
        return tree
    if rule == 77: # $_gen21 = $alias
        ctx.rule = rules[77]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_alias(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen5(ctx):
    current = ctx.tokens.current()
    rule = table[51][current.id] if current else -1
    tree = ParseTree(NonTerminal(107, '_gen5'))
    ctx.nonterminal = "_gen5"
    tree.list = True
    if current != None and current.id in nonterminal_follow[107] and current.id not in nonterminal_first[107]:
        return tree
    if current == None:
        return tree
    if rule == 15: # $_gen5 = $declaration $_gen6
        ctx.rule = rules[15]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_declaration(ctx)
        tree.add(subtree)
        subtree = parse__gen6(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen33(ctx):
    current = ctx.tokens.current()
    rule = table[52][current.id] if current else -1
    tree = ParseTree(NonTerminal(108, '_gen33'))
    ctx.nonterminal = "_gen33"
    tree.list = True
    if current != None and current.id in nonterminal_follow[108] and current.id not in nonterminal_first[108]:
        return tree
    if current == None:
        return tree
    if rule == 130: # $_gen33 = :comma $e $_gen33
        ctx.rule = rules[130]
        tree.astTransform = AstTransformSubstitution(0)
        t = expect(ctx, 37) # :comma
        tree.add(t)
        tree.listSeparator = t
        subtree = parse_e(ctx)
        tree.add(subtree)
        subtree = parse__gen33(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen25(ctx):
    current = ctx.tokens.current()
    rule = table[54][current.id] if current else -1
    tree = ParseTree(NonTerminal(110, '_gen25'))
    ctx.nonterminal = "_gen25"
    tree.list = True
    if current != None and current.id in nonterminal_follow[110] and current.id not in nonterminal_first[110]:
        return tree
    if current == None:
        return tree
    if rule == 87: # $_gen25 = $mapping $_gen26
        ctx.rule = rules[87]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_mapping(ctx)
        tree.add(subtree)
        subtree = parse__gen26(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_command(ctx):
    current = ctx.tokens.current()
    rule = table[55][current.id] if current else -1
    tree = ParseTree(NonTerminal(111, 'command'))
    ctx.nonterminal = "command"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 33: # $command = :raw_command :raw_cmd_start $_gen9 :raw_cmd_end -> RawCommand( parts=$2 )
        ctx.rule = rules[33]
        ast_parameters = OrderedDict([
            ('parts', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('RawCommand', ast_parameters)
        t = expect(ctx, 19) # :raw_command
        tree.add(t)
        t = expect(ctx, 30) # :raw_cmd_start
        tree.add(t)
        subtree = parse__gen9(ctx)
        tree.add(subtree)
        t = expect(ctx, 35) # :raw_cmd_end
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[111] if x >=0],
      rules[33]
    )
def parse__gen10(ctx):
    current = ctx.tokens.current()
    rule = table[56][current.id] if current else -1
    tree = ParseTree(NonTerminal(112, '_gen10'))
    ctx.nonterminal = "_gen10"
    tree.list = True
    if current != None and current.id in nonterminal_follow[112] and current.id not in nonterminal_first[112]:
        return tree
    if current == None:
        return tree
    if rule == 30: # $_gen10 = $command_part $_gen10
        ctx.rule = rules[30]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_command_part(ctx)
        tree.add(subtree)
        subtree = parse__gen10(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_cmd_param_kv(ctx):
    current = ctx.tokens.current()
    rule = table[57][current.id] if current else -1
    tree = ParseTree(NonTerminal(113, 'cmd_param_kv'))
    ctx.nonterminal = "cmd_param_kv"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 41: # $cmd_param_kv = :cmd_attr_hint :identifier :equal $e -> CommandParameterAttr( key=$1, value=$3 )
        ctx.rule = rules[41]
        ast_parameters = OrderedDict([
            ('key', 1),
            ('value', 3),
        ])
        tree.astTransform = AstTransformNodeCreator('CommandParameterAttr', ast_parameters)
        t = expect(ctx, 29) # :cmd_attr_hint
        tree.add(t)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 52) # :equal
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[113] if x >=0],
      rules[41]
    )
def parse__gen36(ctx):
    current = ctx.tokens.current()
    rule = table[58][current.id] if current else -1
    tree = ParseTree(NonTerminal(114, '_gen36'))
    ctx.nonterminal = "_gen36"
    tree.list = True
    if current != None and current.id in nonterminal_follow[114] and current.id not in nonterminal_first[114]:
        return tree
    if current == None:
        return tree
    if rule == 142: # $_gen36 = $map_kv $_gen37
        ctx.rule = rules[142]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_map_kv(ctx)
        tree.add(subtree)
        subtree = parse__gen37(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen27(ctx):
    current = ctx.tokens.current()
    rule = table[59][current.id] if current else -1
    tree = ParseTree(NonTerminal(115, '_gen27'))
    ctx.nonterminal = "_gen27"
    tree.list = True
    if current != None and current.id in nonterminal_follow[115] and current.id not in nonterminal_first[115]:
        return tree
    if current == None:
        return tree
    if rule == 94: # $_gen27 = $wf_output $_gen28
        ctx.rule = rules[94]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_wf_output(ctx)
        tree.add(subtree)
        subtree = parse__gen28(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_meta(ctx):
    current = ctx.tokens.current()
    rule = table[60][current.id] if current else -1
    tree = ParseTree(NonTerminal(116, 'meta'))
    ctx.nonterminal = "meta"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 50: # $meta = :meta $map -> Meta( map=$1 )
        ctx.rule = rules[50]
        ast_parameters = OrderedDict([
            ('map', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('Meta', ast_parameters)
        t = expect(ctx, 31) # :meta
        tree.add(t)
        subtree = parse_map(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[116] if x >=0],
      rules[50]
    )
def parse__gen34(ctx):
    current = ctx.tokens.current()
    rule = table[61][current.id] if current else -1
    tree = ParseTree(NonTerminal(117, '_gen34'))
    ctx.nonterminal = "_gen34"
    tree.list = True
    if current != None and current.id in nonterminal_follow[117] and current.id not in nonterminal_first[117]:
        return tree
    if current == None:
        return tree
    if rule == 136: # $_gen34 = $object_kv $_gen35
        ctx.rule = rules[136]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_object_kv(ctx)
        tree.add(subtree)
        subtree = parse__gen35(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_runtime(ctx):
    current = ctx.tokens.current()
    rule = table[62][current.id] if current else -1
    tree = ParseTree(NonTerminal(118, 'runtime'))
    ctx.nonterminal = "runtime"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 48: # $runtime = :runtime $map -> Runtime( map=$1 )
        ctx.rule = rules[48]
        ast_parameters = OrderedDict([
            ('map', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('Runtime', ast_parameters)
        t = expect(ctx, 0) # :runtime
        tree.add(t)
        subtree = parse_map(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[118] if x >=0],
      rules[48]
    )
def parse_declaration(ctx):
    current = ctx.tokens.current()
    rule = table[63][current.id] if current else -1
    tree = ParseTree(NonTerminal(119, 'declaration'))
    ctx.nonterminal = "declaration"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 61: # $declaration = $type_e $_gen17 :identifier $_gen18 -> Declaration( type=$0, postfix=$1, name=$2, expression=$3 )
        ctx.rule = rules[61]
        ast_parameters = OrderedDict([
            ('type', 0),
            ('postfix', 1),
            ('name', 2),
            ('expression', 3),
        ])
        tree.astTransform = AstTransformNodeCreator('Declaration', ast_parameters)
        subtree = parse_type_e(ctx)
        tree.add(subtree)
        subtree = parse__gen17(ctx)
        tree.add(subtree)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        subtree = parse__gen18(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[119] if x >=0],
      rules[61]
    )
def parse__gen35(ctx):
    current = ctx.tokens.current()
    rule = table[64][current.id] if current else -1
    tree = ParseTree(NonTerminal(120, '_gen35'))
    ctx.nonterminal = "_gen35"
    tree.list = True
    if current != None and current.id in nonterminal_follow[120] and current.id not in nonterminal_first[120]:
        return tree
    if current == None:
        return tree
    if rule == 137: # $_gen35 = :comma $object_kv $_gen35
        ctx.rule = rules[137]
        tree.astTransform = AstTransformSubstitution(0)
        t = expect(ctx, 37) # :comma
        tree.add(t)
        tree.listSeparator = t
        subtree = parse_object_kv(ctx)
        tree.add(subtree)
        subtree = parse__gen35(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen6(ctx):
    current = ctx.tokens.current()
    rule = table[65][current.id] if current else -1
    tree = ParseTree(NonTerminal(121, '_gen6'))
    ctx.nonterminal = "_gen6"
    tree.list = True
    if current != None and current.id in nonterminal_follow[121] and current.id not in nonterminal_first[121]:
        return tree
    if current == None:
        return tree
    if rule == 16: # $_gen6 = $declaration $_gen6
        ctx.rule = rules[16]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_declaration(ctx)
        tree.add(subtree)
        subtree = parse__gen6(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_setter(ctx):
    current = ctx.tokens.current()
    rule = table[66][current.id] if current else -1
    tree = ParseTree(NonTerminal(122, 'setter'))
    ctx.nonterminal = "setter"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 62: # $setter = :equal $e -> $1
        ctx.rule = rules[62]
        tree.astTransform = AstTransformSubstitution(1)
        t = expect(ctx, 52) # :equal
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[122] if x >=0],
      rules[62]
    )
def parse__gen1(ctx):
    current = ctx.tokens.current()
    rule = table[67][current.id] if current else -1
    tree = ParseTree(NonTerminal(123, '_gen1'))
    ctx.nonterminal = "_gen1"
    tree.list = True
    if current != None and current.id in nonterminal_follow[123] and current.id not in nonterminal_first[123]:
        return tree
    if current == None:
        return tree
    if rule == 1: # $_gen1 = $import $_gen1
        ctx.rule = rules[1]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_import(ctx)
        tree.add(subtree)
        subtree = parse__gen1(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen37(ctx):
    current = ctx.tokens.current()
    rule = table[68][current.id] if current else -1
    tree = ParseTree(NonTerminal(124, '_gen37'))
    ctx.nonterminal = "_gen37"
    tree.list = True
    if current != None and current.id in nonterminal_follow[124] and current.id not in nonterminal_first[124]:
        return tree
    if current == None:
        return tree
    if rule == 143: # $_gen37 = :comma $map_kv $_gen37
        ctx.rule = rules[143]
        tree.astTransform = AstTransformSubstitution(0)
        t = expect(ctx, 37) # :comma
        tree.add(t)
        tree.listSeparator = t
        subtree = parse_map_kv(ctx)
        tree.add(subtree)
        subtree = parse__gen37(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen7(ctx):
    current = ctx.tokens.current()
    rule = table[69][current.id] if current else -1
    tree = ParseTree(NonTerminal(125, '_gen7'))
    ctx.nonterminal = "_gen7"
    tree.list = True
    if current != None and current.id in nonterminal_follow[125] and current.id not in nonterminal_first[125]:
        return tree
    if current == None:
        return tree
    if rule == 19: # $_gen7 = $sections $_gen8
        ctx.rule = rules[19]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_sections(ctx)
        tree.add(subtree)
        subtree = parse__gen8(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen19(ctx):
    current = ctx.tokens.current()
    rule = table[70][current.id] if current else -1
    tree = ParseTree(NonTerminal(126, '_gen19'))
    ctx.nonterminal = "_gen19"
    tree.list = True
    if current != None and current.id in nonterminal_follow[126] and current.id not in nonterminal_first[126]:
        return tree
    if current == None:
        return tree
    if rule == 66: # $_gen19 = $wf_body_element $_gen20
        ctx.rule = rules[66]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_wf_body_element(ctx)
        tree.add(subtree)
        subtree = parse__gen20(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen3(ctx):
    current = ctx.tokens.current()
    rule = table[71][current.id] if current else -1
    tree = ParseTree(NonTerminal(127, '_gen3'))
    ctx.nonterminal = "_gen3"
    tree.list = True
    if current != None and current.id in nonterminal_follow[127] and current.id not in nonterminal_first[127]:
        return tree
    if current == None:
        return tree
    if rule == 5: # $_gen3 = $workflow_or_task $_gen3
        ctx.rule = rules[5]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_workflow_or_task(ctx)
        tree.add(subtree)
        subtree = parse__gen3(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_workflow(ctx):
    current = ctx.tokens.current()
    rule = table[72][current.id] if current else -1
    tree = ParseTree(NonTerminal(128, 'workflow'))
    ctx.nonterminal = "workflow"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 70: # $workflow = :workflow :identifier :lbrace $_gen19 :rbrace -> Workflow( name=$1, body=$3 )
        ctx.rule = rules[70]
        ast_parameters = OrderedDict([
            ('name', 1),
            ('body', 3),
        ])
        tree.astTransform = AstTransformNodeCreator('Workflow', ast_parameters)
        t = expect(ctx, 53) # :workflow
        tree.add(t)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 15) # :lbrace
        tree.add(t)
        subtree = parse__gen19(ctx)
        tree.add(subtree)
        t = expect(ctx, 47) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[128] if x >=0],
      rules[70]
    )
def parse_if_stmt(ctx):
    current = ctx.tokens.current()
    rule = table[73][current.id] if current else -1
    tree = ParseTree(NonTerminal(129, 'if_stmt'))
    ctx.nonterminal = "if_stmt"
    tree.list = False
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 104: # $if_stmt = :if :lparen $e :rparen :lbrace $_gen19 :rbrace -> If( expression=$2, body=$5 )
        ctx.rule = rules[104]
        ast_parameters = OrderedDict([
            ('expression', 2),
            ('body', 5),
        ])
        tree.astTransform = AstTransformNodeCreator('If', ast_parameters)
        t = expect(ctx, 21) # :if
        tree.add(t)
        t = expect(ctx, 9) # :lparen
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 38) # :rparen
        tree.add(t)
        t = expect(ctx, 15) # :lbrace
        tree.add(t)
        subtree = parse__gen19(ctx)
        tree.add(subtree)
        t = expect(ctx, 47) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[129] if x >=0],
      rules[104]
    )
def parse_document(ctx):
    current = ctx.tokens.current()
    rule = table[74][current.id] if current else -1
    tree = ParseTree(NonTerminal(130, 'document'))
    ctx.nonterminal = "document"
    tree.list = False
    if current != None and current.id in nonterminal_follow[130] and current.id not in nonterminal_first[130]:
        return tree
    if current == None:
        return tree
    if rule == 8: # $document = $_gen0 $_gen2 -> Document( imports=$0, definitions=$1 )
        ctx.rule = rules[8]
        ast_parameters = OrderedDict([
            ('imports', 0),
            ('definitions', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('Document', ast_parameters)
        subtree = parse__gen0(ctx)
        tree.add(subtree)
        subtree = parse__gen2(ctx)
        tree.add(subtree)
        return tree
    return tree
# Lexer Code #
# START USER CODE
def init():
    return {
        'context': None,
        'replacements': {
            re.compile(r"\\n"): 0x000A,
            re.compile(r"\\r"): 0x000D,
            re.compile(r"\\b"): 0x0008,
            re.compile(r"\\t"): 0x0009,
            re.compile(r"\\a"): 0x0007,
            re.compile(r"\\v"): 0x000B,
            re.compile(r'\\"'): 0x0022,
            re.compile(r"\\'"): 0x0027,
            re.compile(r"\\\?"): 0x003F
        },
        'escapes': {
            re.compile(r'(\\([0-7]{1,3}))'): 8,
            re.compile(r'(\\[xX]([0-9a-fA-F]{1,4}))'): 16,
            re.compile(r'(\\[uU]([0-9a-fA-F]{4}))'): 16
        }
    }
def workflow(ctx, terminal, source_string, line, col):
    ctx.user_context['context'] = 'workflow'
    default_action(ctx, terminal, source_string, line, col)
def task(ctx, terminal, source_string, line, col):
    ctx.user_context['context'] = 'task'
    default_action(ctx, terminal, source_string, line, col)
def output(ctx, terminal, source_string, line, col):
    if ctx.user_context['context'] == 'workflow':
        ctx.stack.append('wf_output')
    default_action(ctx, terminal, source_string, line, col)
def unescape(ctx, terminal, source_string, line, col):
    for regex, c in ctx.user_context['replacements'].items():
        source_string = regex.sub(chr(c), source_string)
    source_string = source_string.replace("\\\\", "\\")
    for regex, base in ctx.user_context['escapes'].items():
        for escape_sequence, number in regex.findall(source_string):
            source_string = source_string.replace(escape_sequence, unichr(int(number, base)))
    default_action(ctx, terminal, source_string[1:-1], line, col)
# END USER CODE
def emit(ctx, terminal, source_string, line, col):
    if terminal:
        ctx.tokens.append(Terminal(terminals[terminal], terminal, source_string, ctx.resource, line, col))
def default_action(ctx, terminal, source_string, line, col):
    emit(ctx, terminal, source_string, line, col)
def destroy(context):
    pass
class LexerStackPush:
    def __init__(self, mode):
        self.mode = mode
class LexerAction:
    def __init__(self, action):
        self.action = action
class LexerContext:
    def __init__(self, string, resource, errors, user_context):
        self.__dict__.update(locals())
        self.stack = ['default']
        self.line = 1
        self.col = 1
        self.tokens = []
        self.user_context = user_context
        self.re_match = None # https://docs.python.org/3/library/re.html#match-objects
class HermesLexer:
    regex = {
        'default': OrderedDict([
          (re.compile(r'\s+'), [
              # (terminal, group, function)
          ]),
          (re.compile(r'/\*(.*?)\*/', re.DOTALL), [
              # (terminal, group, function)
          ]),
          (re.compile(r'#.*'), [
              # (terminal, group, function)
          ]),
          (re.compile(r'task(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('task', 0, task),
          ]),
          (re.compile(r'(call)\s+'), [
              # (terminal, group, function)
              ('call', 1, None),
              LexerStackPush('task_fqn'),
          ]),
          (re.compile(r'workflow(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('workflow', 0, workflow),
          ]),
          (re.compile(r'import(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('import', 0, None),
          ]),
          (re.compile(r'input(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('input', 0, None),
          ]),
          (re.compile(r'output(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('output', 0, output),
          ]),
          (re.compile(r'as(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('as', 0, None),
          ]),
          (re.compile(r'if(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('if', 0, None),
          ]),
          (re.compile(r'while(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('while', 0, None),
          ]),
          (re.compile(r'runtime(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('runtime', 0, None),
          ]),
          (re.compile(r'scatter(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('scatter', 0, None),
              LexerStackPush('scatter'),
          ]),
          (re.compile(r'command\s*(?=<<<)'), [
              # (terminal, group, function)
              ('raw_command', 0, None),
              LexerStackPush('raw_command2'),
          ]),
          (re.compile(r'command\s*(?=\{)'), [
              # (terminal, group, function)
              ('raw_command', 0, None),
              LexerStackPush('raw_command'),
          ]),
          (re.compile(r'parameter_meta(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('parameter_meta', 0, None),
          ]),
          (re.compile(r'meta(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('meta', 0, None),
          ]),
          (re.compile(r'(true|false)(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('boolean', 0, None),
          ]),
          (re.compile(r'(object)\s*(\{)'), [
              # (terminal, group, function)
              ('object', 0, None),
              ('lbrace', 0, None),
          ]),
          (re.compile(r'(Array|Map|Object|Boolean|Int|Float|Uri|File|String)(?![a-zA-Z0-9_])(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('type', 0, None),
          ]),
          (re.compile(r'[a-zA-Z]([a-zA-Z0-9_])*'), [
              # (terminal, group, function)
              ('identifier', 0, None),
          ]),
          (re.compile(r'"([^\\\"\n]|\\[\\"\'nrbtfav\?]|\\[0-7]{1,3}|\\x[0-9a-fA-F]+|\\[uU]([0-9a-fA-F]{4})([0-9a-fA-F]{4})?)*"'), [
              # (terminal, group, function)
              ('string', 0, unescape),
          ]),
          (re.compile(r'\'([^\\\'\n]|\\[\\"\'nrbtfav\?]|\\[0-7]{1,3}|\\x[0-9a-fA-F]+|\\[uU]([0-9a-fA-F]{4})([0-9a-fA-F]{4})?)*\''), [
              # (terminal, group, function)
              ('string', 0, unescape),
          ]),
          (re.compile(r':'), [
              # (terminal, group, function)
              ('colon', 0, None),
          ]),
          (re.compile(r','), [
              # (terminal, group, function)
              ('comma', 0, None),
          ]),
          (re.compile(r'=='), [
              # (terminal, group, function)
              ('double_equal', 0, None),
          ]),
          (re.compile(r'\|\|'), [
              # (terminal, group, function)
              ('double_pipe', 0, None),
          ]),
          (re.compile(r'\&\&'), [
              # (terminal, group, function)
              ('double_ampersand', 0, None),
          ]),
          (re.compile(r'!='), [
              # (terminal, group, function)
              ('not_equal', 0, None),
          ]),
          (re.compile(r'='), [
              # (terminal, group, function)
              ('equal', 0, None),
          ]),
          (re.compile(r'\.'), [
              # (terminal, group, function)
              ('dot', 0, None),
          ]),
          (re.compile(r'\{'), [
              # (terminal, group, function)
              ('lbrace', 0, None),
          ]),
          (re.compile(r'\}'), [
              # (terminal, group, function)
              ('rbrace', 0, None),
          ]),
          (re.compile(r'\('), [
              # (terminal, group, function)
              ('lparen', 0, None),
          ]),
          (re.compile(r'\)'), [
              # (terminal, group, function)
              ('rparen', 0, None),
          ]),
          (re.compile(r'\['), [
              # (terminal, group, function)
              ('lsquare', 0, None),
          ]),
          (re.compile(r'\]'), [
              # (terminal, group, function)
              ('rsquare', 0, None),
          ]),
          (re.compile(r'\+'), [
              # (terminal, group, function)
              ('plus', 0, None),
          ]),
          (re.compile(r'\*'), [
              # (terminal, group, function)
              ('asterisk', 0, None),
          ]),
          (re.compile(r'-'), [
              # (terminal, group, function)
              ('dash', 0, None),
          ]),
          (re.compile(r'/'), [
              # (terminal, group, function)
              ('slash', 0, None),
          ]),
          (re.compile(r'%'), [
              # (terminal, group, function)
              ('percent', 0, None),
          ]),
          (re.compile(r'<='), [
              # (terminal, group, function)
              ('lteq', 0, None),
          ]),
          (re.compile(r'<'), [
              # (terminal, group, function)
              ('lt', 0, None),
          ]),
          (re.compile(r'>='), [
              # (terminal, group, function)
              ('gteq', 0, None),
          ]),
          (re.compile(r'>'), [
              # (terminal, group, function)
              ('gt', 0, None),
          ]),
          (re.compile(r'!'), [
              # (terminal, group, function)
              ('not', 0, None),
          ]),
          (re.compile(r'\?'), [
              # (terminal, group, function)
              ('qmark', 0, None),
          ]),
          (re.compile(r'-?[0-9]+\.[0-9]+'), [
              # (terminal, group, function)
              ('float', 0, None),
          ]),
          (re.compile(r'[0-9]+'), [
              # (terminal, group, function)
              ('integer', 0, None),
          ]),
        ]),
        'wf_output': OrderedDict([
          (re.compile(r'\s+'), [
              # (terminal, group, function)
          ]),
          (re.compile(r'\{'), [
              # (terminal, group, function)
              ('lbrace', 0, None),
          ]),
          (re.compile(r'\}'), [
              # (terminal, group, function)
              ('rbrace', 0, None),
              LexerAction('pop'),
          ]),
          (re.compile(r','), [
              # (terminal, group, function)
              ('comma', 0, None),
          ]),
          (re.compile(r'\.'), [
              # (terminal, group, function)
              ('dot', 0, None),
          ]),
          (re.compile(r'\*'), [
              # (terminal, group, function)
              ('asterisk', 0, None),
          ]),
          (re.compile(r'[a-zA-Z]([a-zA-Z0-9_])*(\.[a-zA-Z]([a-zA-Z0-9_])*)*'), [
              # (terminal, group, function)
              ('fqn', 0, None),
          ]),
        ]),
        'task_fqn': OrderedDict([
          (re.compile(r'\s+'), [
              # (terminal, group, function)
          ]),
          (re.compile(r'[a-zA-Z]([a-zA-Z0-9_])*(\.[a-zA-Z]([a-zA-Z0-9_])*)*'), [
              # (terminal, group, function)
              ('fqn', 0, None),
              LexerAction('pop'),
          ]),
        ]),
        'scatter': OrderedDict([
          (re.compile(r'\s+'), [
              # (terminal, group, function)
          ]),
          (re.compile(r'\)'), [
              # (terminal, group, function)
              ('rparen', 0, None),
              LexerAction('pop'),
          ]),
          (re.compile(r'\('), [
              # (terminal, group, function)
              ('lparen', 0, None),
          ]),
          (re.compile(r'\.'), [
              # (terminal, group, function)
              ('dot', 0, None),
          ]),
          (re.compile(r'\['), [
              # (terminal, group, function)
              ('lsquare', 0, None),
          ]),
          (re.compile(r'\]'), [
              # (terminal, group, function)
              ('rsquare', 0, None),
          ]),
          (re.compile(r'in(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('in', 0, None),
          ]),
          (re.compile(r'[a-zA-Z]([a-zA-Z0-9_])*'), [
              # (terminal, group, function)
              ('identifier', 0, None),
          ]),
        ]),
        'raw_command': OrderedDict([
          (re.compile(r'\{'), [
              # (terminal, group, function)
              ('raw_cmd_start', 0, None),
          ]),
          (re.compile(r'\}'), [
              # (terminal, group, function)
              ('raw_cmd_end', 0, None),
              LexerAction('pop'),
          ]),
          (re.compile(r'\$\{'), [
              # (terminal, group, function)
              ('cmd_param_start', 0, None),
              LexerStackPush('cmd_param'),
          ]),
          (re.compile(r'(.*?)(?=\$\{|\})', re.DOTALL), [
              # (terminal, group, function)
              ('cmd_part', 0, None),
          ]),
        ]),
        'raw_command2': OrderedDict([
          (re.compile(r'<<<'), [
              # (terminal, group, function)
              ('raw_cmd_start', 0, None),
          ]),
          (re.compile(r'>>>'), [
              # (terminal, group, function)
              ('raw_cmd_end', 0, None),
              LexerAction('pop'),
          ]),
          (re.compile(r'\$\{'), [
              # (terminal, group, function)
              ('cmd_param_start', 0, None),
              LexerStackPush('cmd_param'),
          ]),
          (re.compile(r'(.*?)(?=\$\{|>>>)', re.DOTALL), [
              # (terminal, group, function)
              ('cmd_part', 0, None),
          ]),
        ]),
        'cmd_param': OrderedDict([
          (re.compile(r'\s+'), [
              # (terminal, group, function)
          ]),
          (re.compile(r'\}'), [
              # (terminal, group, function)
              ('cmd_param_end', 0, None),
              LexerAction('pop'),
          ]),
          (re.compile(r'\['), [
              # (terminal, group, function)
              ('lsquare', 0, None),
          ]),
          (re.compile(r'\]'), [
              # (terminal, group, function)
              ('rsquare', 0, None),
          ]),
          (re.compile(r'='), [
              # (terminal, group, function)
              ('equal', 0, None),
          ]),
          (re.compile(r'\+'), [
              # (terminal, group, function)
              ('plus', 0, None),
          ]),
          (re.compile(r'\*'), [
              # (terminal, group, function)
              ('asterisk', 0, None),
          ]),
          (re.compile(r'[0-9]+'), [
              # (terminal, group, function)
              ('integer', 0, None),
          ]),
          (re.compile(r'(true|false)(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('boolean', 0, None),
          ]),
          (re.compile(r'(Array|Map|Object|Boolean|Int|Float|Uri|File|String)(?![a-zA-Z0-9_])(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('type', 0, None),
          ]),
          (re.compile(r'[a-zA-Z]([a-zA-Z0-9_])*(?=\s*=)'), [
              # (terminal, group, function)
              ('cmd_attr_hint', None, None),
              ('identifier', 0, None),
          ]),
          (re.compile(r'[a-zA-Z]([a-zA-Z0-9_])*'), [
              # (terminal, group, function)
              ('identifier', 0, None),
          ]),
          (re.compile(r':'), [
              # (terminal, group, function)
              ('colon', 0, None),
          ]),
          (re.compile(r','), [
              # (terminal, group, function)
              ('comma', 0, None),
          ]),
          (re.compile(r'\.'), [
              # (terminal, group, function)
              ('dot', 0, None),
          ]),
          (re.compile(r'=='), [
              # (terminal, group, function)
              ('double_equal', 0, None),
          ]),
          (re.compile(r'\|\|'), [
              # (terminal, group, function)
              ('double_pipe', 0, None),
          ]),
          (re.compile(r'\&\&'), [
              # (terminal, group, function)
              ('double_ampersand', 0, None),
          ]),
          (re.compile(r'!='), [
              # (terminal, group, function)
              ('not_equal', 0, None),
          ]),
          (re.compile(r'='), [
              # (terminal, group, function)
              ('equal', 0, None),
          ]),
          (re.compile(r'\.'), [
              # (terminal, group, function)
              ('dot', 0, None),
          ]),
          (re.compile(r'\{'), [
              # (terminal, group, function)
              ('lbrace', 0, None),
          ]),
          (re.compile(r'\('), [
              # (terminal, group, function)
              ('lparen', 0, None),
          ]),
          (re.compile(r'\)'), [
              # (terminal, group, function)
              ('rparen', 0, None),
          ]),
          (re.compile(r'\['), [
              # (terminal, group, function)
              ('lsquare', 0, None),
          ]),
          (re.compile(r'\]'), [
              # (terminal, group, function)
              ('rsquare', 0, None),
          ]),
          (re.compile(r'\+'), [
              # (terminal, group, function)
              ('plus', 0, None),
          ]),
          (re.compile(r'\*'), [
              # (terminal, group, function)
              ('asterisk', 0, None),
          ]),
          (re.compile(r'-'), [
              # (terminal, group, function)
              ('dash', 0, None),
          ]),
          (re.compile(r'/'), [
              # (terminal, group, function)
              ('slash', 0, None),
          ]),
          (re.compile(r'%'), [
              # (terminal, group, function)
              ('percent', 0, None),
          ]),
          (re.compile(r'<='), [
              # (terminal, group, function)
              ('lteq', 0, None),
          ]),
          (re.compile(r'<'), [
              # (terminal, group, function)
              ('lt', 0, None),
          ]),
          (re.compile(r'>='), [
              # (terminal, group, function)
              ('gteq', 0, None),
          ]),
          (re.compile(r'>'), [
              # (terminal, group, function)
              ('gt', 0, None),
          ]),
          (re.compile(r'!'), [
              # (terminal, group, function)
              ('not', 0, None),
          ]),
          (re.compile(r'"([^\\\"\n]|\\[\\"\'nrbtfav\?]|\\[0-7]{1,3}|\\x[0-9a-fA-F]+|\\[uU]([0-9a-fA-F]{4})([0-9a-fA-F]{4})?)*"'), [
              # (terminal, group, function)
              ('string', 0, unescape),
          ]),
          (re.compile(r'\'([^\\\'\n]|\\[\\"\'nrbtfav\?]|\\[0-7]{1,3}|\\x[0-9a-fA-F]+|\\[uU]([0-9a-fA-F]{4})([0-9a-fA-F]{4})?)*\''), [
              # (terminal, group, function)
              ('string', 0, unescape),
          ]),
          (re.compile(r'-?[0-9]+\.[0-9]+'), [
              # (terminal, group, function)
              ('float', 0, None),
          ]),
          (re.compile(r'[0-9]+'), [
              # (terminal, group, function)
              ('integer', 0, None),
          ]),
        ]),
    }
    def _advance_line_col(self, string, length, line, col):
        for i in range(length):
            if string[i] == '\n':
                line += 1
                col = 1
            else:
                col += 1
        return (line, col)
    def _advance_string(self, ctx, string):
        (ctx.line, ctx.col) = self._advance_line_col(string, len(string), ctx.line, ctx.col)
        ctx.string = ctx.string[len(string):]
    def _next(self, ctx, debug=False):
        for regex, outputs in self.regex[ctx.stack[-1]].items():
            if debug:
                from xtermcolor import colorize
                token_count = len(ctx.tokens)
                print('{1} ({2}, {3}) regex: {0}'.format(
                    colorize(regex.pattern, ansi=40), colorize(ctx.string[:20].replace('\n', '\\n'), ansi=15), ctx.line, ctx.col)
                )
            match = regex.match(ctx.string)
            if match:
                ctx.re_match = match
                for output in outputs:
                    if isinstance(output, tuple):
                        (terminal, group, function) = output
                        function = function if function else default_action
                        source_string = match.group(group) if group is not None else ''
                        (group_line, group_col) = self._advance_line_col(ctx.string, match.start(group) if group else 0, ctx.line, ctx.col)
                        function(
                            ctx,
                            terminal,
                            source_string,
                            group_line,
                            group_col
                        )
                        if debug:
                            print('    matched: {}'.format(colorize(match.group(0).replace('\n', '\\n'), ansi=3)))
                            for token in ctx.tokens[token_count:]:
                                print('    emit: [{}] [{}, {}] [{}] stack:{} context:{}'.format(
                                    colorize(token.str, ansi=9),
                                    colorize(str(token.line), ansi=5),
                                    colorize(str(token.col), ansi=5),
                                    colorize(token.source_string, ansi=3),
                                    colorize(str(ctx.stack), ansi=4),
                                    colorize(str(ctx.user_context), ansi=13)
                                ))
                            token_count = len(ctx.tokens)
                    if isinstance(output, LexerStackPush):
                        ctx.stack.append(output.mode)
                        if debug:
                            print('    push on stack: {}'.format(colorize(output.mode, ansi=4)))
                    if isinstance(output, LexerAction):
                        if output.action == 'pop':
                            mode = ctx.stack.pop()
                            if debug:
                                print('    pop off stack: {}'.format(colorize(mode, ansi=4)))
                self._advance_string(ctx, match.group(0))
                return len(match.group(0)) > 0
        return False
    def lex(self, string, resource, errors=None, debug=False):
        if errors is None:
            errors = DefaultSyntaxErrorHandler()
        string_copy = string
        user_context = init()
        ctx = LexerContext(string, resource, errors, user_context)
        while len(ctx.string):
            matched = self._next(ctx, debug)
            if matched == False:
                raise ctx.errors.unrecognized_token(string_copy, ctx.line, ctx.col)
        destroy(ctx.user_context)
        return ctx.tokens
def lex(source, resource, errors=None, debug=False):
    return TokenStream(HermesLexer().lex(source, resource, errors, debug))
