
# This file was generated by Hermes Parser Generator on Wed Dec 23 14:50:03 2020
# 
# Hermes command: hermes generate grammar.hgr --language=python --name=wdl --header --directory wdlparse/draft2
# Run from: ../.. (relative to this file)
# Hermes version: hermes-parser 2.0rc6
# 
# !!! 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.list_separator_id = 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 is_compound_nud(self):
      return isinstance(self.children[0], ParseTree) and \
             self.children[0].isNud and \
             not self.children[0].isPrefix and \
             not self.isExprNud and \
             not self.isInfix
  def ast(self):
      if self.list == True:
          r = AstList()
          if len(self.children) == 0:
              return r
          for child in self.children:
              if isinstance(child, Terminal) and self.list_separator_id is not None and child.id == self.list_separator_id:
                  continue
              r.append(child.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 self.is_compound_nud():
                      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)]) + '^'
        ))
    def missing_list_items(self, method, required, found, last):
        return self._error("List for {} requires {} items but only {} were found.".format(method, required, found))
    def missing_terminator(self, method, terminator, last):
        return self._error("List for "+method+" is missing a terminator")
class ParserContext:
  def __init__(self, tokens, errors):
    self.__dict__.update(locals())
    self.nonterminal_string = None
    self.rule_string = None
# Parser Code #
terminals = {
    0: 'dot',
    1: 'scatter',
    2: 'import',
    3: 'lteq',
    4: 'in',
    5: 'cmd_param_end',
    6: 'double_pipe',
    7: 'fqn',
    8: 'lbrace',
    9: 'asterisk',
    10: 'lsquare',
    11: 'plus',
    12: 'task',
    13: 'if',
    14: 'float',
    15: 'lparen',
    16: 'while',
    17: 'rbrace',
    18: 'runtime',
    19: 'cmd_param_start',
    20: 'double_ampersand',
    21: 'integer',
    22: 'rparen',
    23: 'raw_cmd_end',
    24: 'call',
    25: 'input',
    26: 'type_e',
    27: 'double_equal',
    28: 'lt',
    29: 'not',
    30: 'gteq',
    31: 'gt',
    32: 'output',
    33: 'identifier',
    34: 'then',
    35: 'else',
    36: 'slash',
    37: 'cmd_attr_hint',
    38: 'e',
    39: 'boolean',
    40: 'equal',
    41: 'object',
    42: 'meta',
    43: 'raw_command',
    44: 'raw_cmd_start',
    45: 'cmd_part',
    46: 'rsquare',
    47: 'as',
    48: 'not_equal',
    49: 'parameter_meta',
    50: 'qmark',
    51: 'dash',
    52: 'percent',
    53: 'workflow',
    54: 'type',
    55: 'string',
    56: 'colon',
    57: 'comma',
    'dot': 0,
    'scatter': 1,
    'import': 2,
    'lteq': 3,
    'in': 4,
    'cmd_param_end': 5,
    'double_pipe': 6,
    'fqn': 7,
    'lbrace': 8,
    'asterisk': 9,
    'lsquare': 10,
    'plus': 11,
    'task': 12,
    'if': 13,
    'float': 14,
    'lparen': 15,
    'while': 16,
    'rbrace': 17,
    'runtime': 18,
    'cmd_param_start': 19,
    'double_ampersand': 20,
    'integer': 21,
    'rparen': 22,
    'raw_cmd_end': 23,
    'call': 24,
    'input': 25,
    'type_e': 26,
    'double_equal': 27,
    'lt': 28,
    'not': 29,
    'gteq': 30,
    'gt': 31,
    'output': 32,
    'identifier': 33,
    'then': 34,
    'else': 35,
    'slash': 36,
    'cmd_attr_hint': 37,
    'e': 38,
    'boolean': 39,
    'equal': 40,
    'object': 41,
    'meta': 42,
    'raw_command': 43,
    'raw_cmd_start': 44,
    'cmd_part': 45,
    'rsquare': 46,
    'as': 47,
    'not_equal': 48,
    'parameter_meta': 49,
    'qmark': 50,
    'dash': 51,
    'percent': 52,
    'workflow': 53,
    'type': 54,
    'string': 55,
    'colon': 56,
    'comma': 57,
}
# table[nonterminal][terminal] = rule
table = [
    [-1, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 35, 35, -1, -1, 35, 35, 35, -1, -1, -1, -1, -1, 35, 35, 35, -1, -1, -1, -1, -1, 35, -1, -1, -1, -1, -1, -1, -1, 34, -1, 35, 35, -1, -1, -1, -1, -1, 35, -1, -1, -1, 35, 35, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 13, -1, -1, -1, -1, -1, 16, -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, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 59, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, 52, -1, -1, -1, -1, -1, -1, 51, -1, -1, -1, -1, 52, -1, -1, 52, 52, -1, -1, -1, -1, -1, -1, 52, -1, 52, -1, -1, -1, -1, -1, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, 52, -1, -1, -1, -1, -1, -1, 52, -1, -1, -1, -1, 52, -1, -1, -1],
    [-1, -1, -1, -1, -1, -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, -1, -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, -1, -1, -1, -1, -1, -1, 38, -1, 38, 38, -1, 38, 38, 38, -1, -1, -1, -1, -1, 38, -1, -1, -1, -1, -1, -1, -1, 38, -1, -1, -1, 38, -1, -1, -1, -1, 38, 38, -1, 38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, 7, 7, -1, -1, -1],
    [-1, 45, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, -1, -1, 43, -1, -1, -1, -1, -1, -1, -1, 41, -1, 42, -1, -1, -1, -1, -1, 46, -1, -1, -1, -1, -1, -1, -1, -1, -1, 48, -1, -1, -1, -1, -1, -1, 47, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [65, -1, -1, -1, -1, -1, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 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, 3, 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, 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, 50, -1, -1, -1, -1, 50, -1, -1, 50, 50, -1, -1, -1, -1, -1, -1, 50, -1, 50, -1, -1, -1, -1, -1, 50, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, -1, -1, -1, -1, 49, -1, 50, -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, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -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, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 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, 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, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, 72, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 36, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, 63, -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, 62, -1, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
]
nonterminal_first = {
    58: [40, -1],
    59: [32, 42, 43, 18, 49],
    60: [8],
    61: [7],
    62: [47],
    63: [2],
    64: [32],
    65: [12],
    66: [45, 19],
    67: [8, -1],
    68: [26, 54],
    69: [13, 33, 15, 14, 10, 21, 51, 41, 38, 29, 39, 8, 55, 11],
    70: [33, -1],
    71: [37, -1],
    72: [26, 54],
    73: [-1, 26, 53, 54, 12],
    74: [33, 38, 39, 8, 10, 11, 41, 13, 14, 15, -1, 21, 51, 29, 55],
    75: [42],
    76: [47, -1],
    77: [13, 32, 42, 16, 1, 49, 24, 26, 54],
    78: [26, -1, 54],
    79: [8],
    80: [0, -1],
    81: [7, 26, -1, 54],
    82: [47],
    83: [26, 53, 54, 12],
    84: [40],
    85: [33, -1],
    86: [47, -1],
    87: [2, -1],
    88: [32, 42, 43, -1, 18, 49],
    89: [43],
    90: [-1, 45, 19],
    91: [18],
    92: [26, 54],
    93: [26, -1, 54],
    94: [37],
    95: [33],
    96: [24],
    97: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    98: [25, -1],
    99: [33],
    100: [26, 12, 53, -1, 2, 54],
    101: [49],
    102: [33, -1],
    103: [32],
    104: [16],
    105: [33],
    106: [13],
    107: [53],
    108: [26, 54],
    109: [1],
    110: [42],
    111: [26, -1, 54],
    112: [33, 38, 39, 8, 10, 11, 41, 13, 14, 15, -1, 21, 51, 29, 55],
    113: [19],
    114: [49],
    115: [25],
    116: [7, 26, 54],
    117: [0],
    118: [13, 32, 42, 16, 1, -1, 49, 24, 26, 54],
}
nonterminal_follow = {
    58: [32, 1, 12, 13, 42, 16, 43, 17, 18, 49, 24, 25, 26, 53, 54, -1],
    59: [32, 42, 43, 17, 18, 49],
    60: [32, 1, 13, 42, 16, 17, 49, 24, 26, 54],
    61: [7, 26, 54, 17],
    62: [32, 1, 8, 13, 42, 16, 17, 49, 24, 26, 54],
    63: [26, 53, 54, 2, -1, 12],
    64: [32, 1, 13, 42, 16, 17, 49, 24, 26, 54],
    65: [26, 53, 54, -1, 12],
    66: [23, 45, 19],
    67: [32, 1, 13, 42, 16, 17, 49, 24, 26, 54],
    68: [7, 26, 54, 17],
    69: [17, 57],
    70: [17],
    71: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    72: [46, 33, 57],
    73: [-1],
    74: [46, 22],
    75: [32, 1, 13, 42, 16, 17, 49, 24, 26, 54],
    76: [26, 53, 54, 2, -1, 12],
    77: [32, 1, 13, 42, 16, 17, 49, 24, 26, 54],
    78: [32, 42, 25, 43, 18, 49],
    79: [32, 42, 13, 43, 16, 1, 17, 18, 49, 24, 26, 54],
    80: [7, 26, 54, 17],
    81: [17],
    82: [26, 53, 54, 2, -1, 12],
    83: [26, 53, 54, -1, 12],
    84: [32, 1, 12, 13, 42, 16, 43, 17, 18, 49, 24, 25, 26, 53, 54, -1],
    85: [25, 17],
    86: [32, 1, 8, 13, 42, 16, 17, 49, 24, 26, 54],
    87: [26, 53, 54, -1, 12],
    88: [17],
    89: [32, 42, 43, 17, 18, 49],
    90: [23],
    91: [32, 42, 43, 17, 18, 49],
    92: [26, 54, 17],
    93: [17],
    94: [33, 37, 38, 39, 8, 10, 41, 11, 13, 14, 15, 21, 51, 29, 55],
    95: [17, 57],
    96: [32, 1, 13, 42, 16, 17, 49, 24, 26, 54],
    97: [1, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 24, 27, 25, 26, 28, 29, -1, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, 43, 46, 51, 48, 49, 52, 53, 54, 55, 56, 57],
    98: [17],
    99: [33, 17],
    100: [-1],
    101: [32, 42, 43, 17, 18, 49],
    102: [17],
    103: [32, 42, 43, 17, 18, 49],
    104: [32, 1, 13, 42, 16, 17, 49, 24, 26, 54],
    105: [25, 17, 57],
    106: [32, 1, 13, 42, 16, 17, 49, 24, 26, 54],
    107: [26, 53, 54, -1, 12],
    108: [32, 1, 12, 13, 42, 16, 43, 17, 18, 49, 24, 25, 26, 53, 54, -1],
    109: [32, 1, 13, 42, 16, 17, 49, 24, 26, 54],
    110: [32, 42, 43, 17, 18, 49],
    111: [46],
    112: [17],
    113: [23, 45, 19],
    114: [32, 1, 13, 42, 16, 17, 49, 24, 26, 54],
    115: [25, 17],
    116: [7, 26, 54, 17],
    117: [7, 26, 54, 17],
    118: [17],
}
rule_first = {
    0: [2, -1],
    1: [-1, 26, 53, 54, 12],
    2: [26, -1, 53, 54, 2, 12],
    3: [53],
    4: [12],
    5: [26, 54],
    6: [47],
    7: [-1],
    8: [2],
    9: [47],
    10: [26, -1, 54],
    11: [32, 42, 43, -1, 18, 49],
    12: [12],
    13: [43],
    14: [32],
    15: [18],
    16: [49],
    17: [42],
    18: [45, 19, -1],
    19: [43],
    20: [45],
    21: [19],
    22: [37, -1],
    23: [19],
    24: [37],
    25: [26, -1, 54],
    26: [32],
    27: [26, 54],
    28: [18],
    29: [49],
    30: [42],
    31: [33, -1],
    32: [8],
    33: [33],
    34: [40],
    35: [-1],
    36: [26, 54],
    37: [40],
    38: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    39: [13, 32, 42, 16, 1, -1, 49, 24, 26, 54],
    40: [53],
    41: [24],
    42: [26, 54],
    43: [16],
    44: [13],
    45: [1],
    46: [32],
    47: [49],
    48: [42],
    49: [47],
    50: [-1],
    51: [8],
    52: [-1],
    53: [24],
    54: [25, -1],
    55: [8],
    56: [33, -1],
    57: [25],
    58: [33],
    59: [47],
    60: [7, 26, -1, 54],
    61: [32],
    62: [26, 54],
    63: [7],
    64: [26, 54],
    65: [0],
    66: [-1],
    67: [7],
    68: [0],
    69: [49],
    70: [42],
    71: [16],
    72: [13],
    73: [1],
    74: [33],
    75: [26, -1, 54],
    76: [54],
    77: [54],
    78: [54],
    79: [54],
    80: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    81: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    82: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    83: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    84: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    85: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    86: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    87: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    88: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    89: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    90: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    91: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    92: [13, 33, 15, 14, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    93: [29],
    94: [11],
    95: [51],
    96: [13, 33, 15, 14, -1, 55, 21, 51, 38, 29, 39, 8, 10, 11, 41],
    97: [33],
    98: [33],
    99: [33],
    100: [33, -1],
    101: [41],
    102: [10],
    103: [13, 33, 15, 14, 10, -1, 21, 51, 41, 38, 29, 39, 8, 55, 11],
    104: [8],
    105: [15],
    106: [13],
    107: [55],
    108: [33],
    109: [39],
    110: [21],
    111: [14],
}
nonterminal_rules = {
    58: [
        "$_gen9 = $setter",
        "$_gen9 = :_empty",
    ],
    59: [
        "$sections = $command",
        "$sections = $outputs",
        "$sections = $runtime",
        "$sections = $parameter_meta",
        "$sections = $meta",
    ],
    60: [
        "$call_body = :lbrace $_gen3 $_gen13 :rbrace -> CallBody( declarations=$1, io=$2 )",
    ],
    61: [
        "$wf_output_wildcard_syntax = :fqn $_gen16 -> WorkflowOutputWildcard( fqn=$0, wildcard=$1 )",
    ],
    62: [
        "$alias = :as :identifier -> $1",
    ],
    63: [
        "$import = :import :string $_gen2 -> Import( uri=$1, namespace=$2 )",
    ],
    64: [
        "$wf_outputs = :output :lbrace $_gen15 :rbrace -> WorkflowOutputs( outputs=$2 )",
    ],
    65: [
        "$task = :task :identifier :lbrace $_gen3 $_gen4 :rbrace -> Task( name=$1, declarations=$3, sections=$4 )",
    ],
    66: [
        "$command_part = :cmd_part",
        "$command_part = $cmd_param",
    ],
    67: [
        "$_gen12 = $call_body",
        "$_gen12 = :_empty",
    ],
    68: [
        "$wf_output_declaration_syntax = $type_e :identifier :equal $e -> WorkflowOutputDeclaration( type=$0, name=$1, expression=$3 )",
    ],
    69: [
        "$map_kv = $e :colon $e -> MapLiteralKv( key=$0, value=$2 )",
    ],
    70: [
        "$_gen19 = list($object_kv, :comma)",
    ],
    71: [
        "$_gen6 = list($cmd_param_kv)",
    ],
    72: [
        "$type_e = :type <=> :lsquare $_gen17 :rsquare -> Type( name=$0, subtype=$2 )",
        "$type_e = :type <=> :qmark -> OptionalType( innerType=$0 )",
        "$type_e = :type <=> :plus -> NonEmptyType( innerType=$0 )",
        "$type_e = :type",
    ],
    73: [
        "$_gen1 = list($workflow_or_task_or_decl)",
    ],
    74: [
        "$_gen18 = list($e, :comma)",
    ],
    75: [
        "$wf_meta = :meta $map -> Meta( map=$1 )",
    ],
    76: [
        "$_gen2 = $import_namespace",
        "$_gen2 = :_empty",
    ],
    77: [
        "$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",
        "$wf_body_element = $wf_parameter_meta",
        "$wf_body_element = $wf_meta",
    ],
    78: [
        "$_gen3 = list($declaration)",
    ],
    79: [
        "$map = :lbrace $_gen8 :rbrace -> $1",
    ],
    80: [
        "$_gen16 = $wf_output_wildcard",
        "$_gen16 = :_empty",
    ],
    81: [
        "$_gen15 = list($wf_output)",
    ],
    82: [
        "$import_namespace = :as :identifier -> $1",
    ],
    83: [
        "$workflow_or_task_or_decl = $workflow",
        "$workflow_or_task_or_decl = $task",
        "$workflow_or_task_or_decl = $declaration",
    ],
    84: [
        "$setter = :equal $e -> $1",
    ],
    85: [
        "$_gen14 = list($mapping, :comma)",
    ],
    86: [
        "$_gen11 = $alias",
        "$_gen11 = :_empty",
    ],
    87: [
        "$_gen0 = list($import)",
    ],
    88: [
        "$_gen4 = list($sections)",
    ],
    89: [
        "$command = :raw_command :raw_cmd_start $_gen5 :raw_cmd_end -> RawCommand( parts=$2 )",
    ],
    90: [
        "$_gen5 = list($command_part)",
    ],
    91: [
        "$runtime = :runtime $map -> Runtime( map=$1 )",
    ],
    92: [
        "$output_kv = $type_e :identifier :equal $e -> Output( type=$0, name=$1, expression=$3 )",
    ],
    93: [
        "$_gen7 = list($output_kv)",
    ],
    94: [
        "$cmd_param_kv = :cmd_attr_hint :identifier :equal $e -> CommandParameterAttr( key=$1, value=$3 )",
    ],
    95: [
        "$object_kv = :identifier :colon $e -> ObjectKV( key=$0, value=$2 )",
    ],
    96: [
        "$call = :call :fqn $_gen11 $_gen12 -> Call( task=$1, alias=$2, body=$3 )",
    ],
    97: [
        "$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 $_gen18 :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 $_gen19 :rbrace -> ObjectLiteral( map=$2 )",
        "$e = :lsquare $_gen18 :rsquare -> ArrayLiteral( values=$1 )",
        "$e = :lbrace $_gen20 :rbrace -> MapLiteral( map=$1 )",
        "$e = :lparen $_gen18 :rparen -> TupleLiteral( values=$1 )",
        "$e = :if $e :then $e :else $e -> TernaryIf( cond=$1, iftrue=$3, iffalse=$5 )",
        "$e = :string",
        "$e = :identifier",
        "$e = :boolean",
        "$e = :integer",
        "$e = :float",
    ],
    98: [
        "$_gen13 = list($call_input)",
    ],
    99: [
        "$kv = :identifier :colon $e -> RuntimeAttribute( key=$0, value=$2 )",
    ],
    100: [
        "$document = $_gen0 $_gen1 -> Namespace( imports=$0, body=$1 )",
    ],
    101: [
        "$parameter_meta = :parameter_meta $map -> ParameterMeta( map=$1 )",
    ],
    102: [
        "$_gen8 = list($kv)",
    ],
    103: [
        "$outputs = :output :lbrace $_gen7 :rbrace -> Outputs( attributes=$2 )",
    ],
    104: [
        "$while_loop = :while :lparen $e :rparen :lbrace $_gen10 :rbrace -> WhileLoop( expression=$2, body=$5 )",
    ],
    105: [
        "$mapping = :identifier :equal $e -> IOMapping( key=$0, value=$2 )",
    ],
    106: [
        "$if_stmt = :if :lparen $e :rparen :lbrace $_gen10 :rbrace -> If( expression=$2, body=$5 )",
    ],
    107: [
        "$workflow = :workflow :identifier :lbrace $_gen10 :rbrace -> Workflow( name=$1, body=$3 )",
    ],
    108: [
        "$declaration = $type_e :identifier $_gen9 -> Declaration( type=$0, name=$1, expression=$2 )",
    ],
    109: [
        "$scatter = :scatter :lparen :identifier :in $e :rparen :lbrace $_gen10 :rbrace -> Scatter( item=$2, collection=$4, body=$7 )",
    ],
    110: [
        "$meta = :meta $map -> Meta( map=$1 )",
    ],
    111: [
        "$_gen17 = list($type_e, :comma)",
    ],
    112: [
        "$_gen20 = list($map_kv, :comma)",
    ],
    113: [
        "$cmd_param = :cmd_param_start $_gen6 $e :cmd_param_end -> CommandParameter( attributes=$1, expr=$2 )",
    ],
    114: [
        "$wf_parameter_meta = :parameter_meta $map -> ParameterMeta( map=$1 )",
    ],
    115: [
        "$call_input = :input :colon $_gen14 -> Inputs( map=$2 )",
    ],
    116: [
        "$wf_output = $wf_output_declaration_syntax",
        "$wf_output = $wf_output_wildcard_syntax",
    ],
    117: [
        "$wf_output_wildcard = :dot :asterisk -> $1",
    ],
    118: [
        "$_gen10 = list($wf_body_element)",
    ],
}
rules = {
    0: "$_gen0 = list($import)",
    1: "$_gen1 = list($workflow_or_task_or_decl)",
    2: "$document = $_gen0 $_gen1 -> Namespace( imports=$0, body=$1 )",
    3: "$workflow_or_task_or_decl = $workflow",
    4: "$workflow_or_task_or_decl = $task",
    5: "$workflow_or_task_or_decl = $declaration",
    6: "$_gen2 = $import_namespace",
    7: "$_gen2 = :_empty",
    8: "$import = :import :string $_gen2 -> Import( uri=$1, namespace=$2 )",
    9: "$import_namespace = :as :identifier -> $1",
    10: "$_gen3 = list($declaration)",
    11: "$_gen4 = list($sections)",
    12: "$task = :task :identifier :lbrace $_gen3 $_gen4 :rbrace -> Task( name=$1, declarations=$3, sections=$4 )",
    13: "$sections = $command",
    14: "$sections = $outputs",
    15: "$sections = $runtime",
    16: "$sections = $parameter_meta",
    17: "$sections = $meta",
    18: "$_gen5 = list($command_part)",
    19: "$command = :raw_command :raw_cmd_start $_gen5 :raw_cmd_end -> RawCommand( parts=$2 )",
    20: "$command_part = :cmd_part",
    21: "$command_part = $cmd_param",
    22: "$_gen6 = list($cmd_param_kv)",
    23: "$cmd_param = :cmd_param_start $_gen6 $e :cmd_param_end -> CommandParameter( attributes=$1, expr=$2 )",
    24: "$cmd_param_kv = :cmd_attr_hint :identifier :equal $e -> CommandParameterAttr( key=$1, value=$3 )",
    25: "$_gen7 = list($output_kv)",
    26: "$outputs = :output :lbrace $_gen7 :rbrace -> Outputs( attributes=$2 )",
    27: "$output_kv = $type_e :identifier :equal $e -> Output( type=$0, name=$1, expression=$3 )",
    28: "$runtime = :runtime $map -> Runtime( map=$1 )",
    29: "$parameter_meta = :parameter_meta $map -> ParameterMeta( map=$1 )",
    30: "$meta = :meta $map -> Meta( map=$1 )",
    31: "$_gen8 = list($kv)",
    32: "$map = :lbrace $_gen8 :rbrace -> $1",
    33: "$kv = :identifier :colon $e -> RuntimeAttribute( key=$0, value=$2 )",
    34: "$_gen9 = $setter",
    35: "$_gen9 = :_empty",
    36: "$declaration = $type_e :identifier $_gen9 -> Declaration( type=$0, name=$1, expression=$2 )",
    37: "$setter = :equal $e -> $1",
    38: "$map_kv = $e :colon $e -> MapLiteralKv( key=$0, value=$2 )",
    39: "$_gen10 = list($wf_body_element)",
    40: "$workflow = :workflow :identifier :lbrace $_gen10 :rbrace -> Workflow( name=$1, body=$3 )",
    41: "$wf_body_element = $call",
    42: "$wf_body_element = $declaration",
    43: "$wf_body_element = $while_loop",
    44: "$wf_body_element = $if_stmt",
    45: "$wf_body_element = $scatter",
    46: "$wf_body_element = $wf_outputs",
    47: "$wf_body_element = $wf_parameter_meta",
    48: "$wf_body_element = $wf_meta",
    49: "$_gen11 = $alias",
    50: "$_gen11 = :_empty",
    51: "$_gen12 = $call_body",
    52: "$_gen12 = :_empty",
    53: "$call = :call :fqn $_gen11 $_gen12 -> Call( task=$1, alias=$2, body=$3 )",
    54: "$_gen13 = list($call_input)",
    55: "$call_body = :lbrace $_gen3 $_gen13 :rbrace -> CallBody( declarations=$1, io=$2 )",
    56: "$_gen14 = list($mapping, :comma)",
    57: "$call_input = :input :colon $_gen14 -> Inputs( map=$2 )",
    58: "$mapping = :identifier :equal $e -> IOMapping( key=$0, value=$2 )",
    59: "$alias = :as :identifier -> $1",
    60: "$_gen15 = list($wf_output)",
    61: "$wf_outputs = :output :lbrace $_gen15 :rbrace -> WorkflowOutputs( outputs=$2 )",
    62: "$wf_output = $wf_output_declaration_syntax",
    63: "$wf_output = $wf_output_wildcard_syntax",
    64: "$wf_output_declaration_syntax = $type_e :identifier :equal $e -> WorkflowOutputDeclaration( type=$0, name=$1, expression=$3 )",
    65: "$_gen16 = $wf_output_wildcard",
    66: "$_gen16 = :_empty",
    67: "$wf_output_wildcard_syntax = :fqn $_gen16 -> WorkflowOutputWildcard( fqn=$0, wildcard=$1 )",
    68: "$wf_output_wildcard = :dot :asterisk -> $1",
    69: "$wf_parameter_meta = :parameter_meta $map -> ParameterMeta( map=$1 )",
    70: "$wf_meta = :meta $map -> Meta( map=$1 )",
    71: "$while_loop = :while :lparen $e :rparen :lbrace $_gen10 :rbrace -> WhileLoop( expression=$2, body=$5 )",
    72: "$if_stmt = :if :lparen $e :rparen :lbrace $_gen10 :rbrace -> If( expression=$2, body=$5 )",
    73: "$scatter = :scatter :lparen :identifier :in $e :rparen :lbrace $_gen10 :rbrace -> Scatter( item=$2, collection=$4, body=$7 )",
    74: "$object_kv = :identifier :colon $e -> ObjectKV( key=$0, value=$2 )",
    75: "$_gen17 = list($type_e, :comma)",
    76: "$type_e = :type <=> :lsquare $_gen17 :rsquare -> Type( name=$0, subtype=$2 )",
    77: "$type_e = :type <=> :qmark -> OptionalType( innerType=$0 )",
    78: "$type_e = :type <=> :plus -> NonEmptyType( innerType=$0 )",
    79: "$type_e = :type",
    80: "$e = $e :double_pipe $e -> LogicalOr( lhs=$0, rhs=$2 )",
    81: "$e = $e :double_ampersand $e -> LogicalAnd( lhs=$0, rhs=$2 )",
    82: "$e = $e :double_equal $e -> Equals( lhs=$0, rhs=$2 )",
    83: "$e = $e :not_equal $e -> NotEquals( lhs=$0, rhs=$2 )",
    84: "$e = $e :lt $e -> LessThan( lhs=$0, rhs=$2 )",
    85: "$e = $e :lteq $e -> LessThanOrEqual( lhs=$0, rhs=$2 )",
    86: "$e = $e :gt $e -> GreaterThan( lhs=$0, rhs=$2 )",
    87: "$e = $e :gteq $e -> GreaterThanOrEqual( lhs=$0, rhs=$2 )",
    88: "$e = $e :plus $e -> Add( lhs=$0, rhs=$2 )",
    89: "$e = $e :dash $e -> Subtract( lhs=$0, rhs=$2 )",
    90: "$e = $e :asterisk $e -> Multiply( lhs=$0, rhs=$2 )",
    91: "$e = $e :slash $e -> Divide( lhs=$0, rhs=$2 )",
    92: "$e = $e :percent $e -> Remainder( lhs=$0, rhs=$2 )",
    93: "$e = :not $e -> LogicalNot( expression=$1 )",
    94: "$e = :plus $e -> UnaryPlus( expression=$1 )",
    95: "$e = :dash $e -> UnaryNegation( expression=$1 )",
    96: "$_gen18 = list($e, :comma)",
    97: "$e = :identifier <=> :lparen $_gen18 :rparen -> FunctionCall( name=$0, params=$2 )",
    98: "$e = :identifier <=> :lsquare $e :rsquare -> ArrayOrMapLookup( lhs=$0, rhs=$2 )",
    99: "$e = :identifier <=> :dot :identifier -> MemberAccess( lhs=$0, rhs=$2 )",
    100: "$_gen19 = list($object_kv, :comma)",
    101: "$e = :object :lbrace $_gen19 :rbrace -> ObjectLiteral( map=$2 )",
    102: "$e = :lsquare $_gen18 :rsquare -> ArrayLiteral( values=$1 )",
    103: "$_gen20 = list($map_kv, :comma)",
    104: "$e = :lbrace $_gen20 :rbrace -> MapLiteral( map=$1 )",
    105: "$e = :lparen $_gen18 :rparen -> TupleLiteral( values=$1 )",
    106: "$e = :if $e :then $e :else $e -> TernaryIf( cond=$1, iftrue=$3, iffalse=$5 )",
    107: "$e = :string",
    108: "$e = :identifier",
    109: "$e = :boolean",
    110: "$e = :integer",
    111: "$e = :float",
}
def is_terminal(id): return isinstance(id, int) and 0 <= id <= 57
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 = {
    6: 4000, # $e = $e :double_pipe $e -> LogicalOr( lhs=$0, rhs=$2 )
    20: 5000, # $e = $e :double_ampersand $e -> LogicalAnd( lhs=$0, rhs=$2 )
    27: 6000, # $e = $e :double_equal $e -> Equals( lhs=$0, rhs=$2 )
    48: 6000, # $e = $e :not_equal $e -> NotEquals( lhs=$0, rhs=$2 )
    28: 7000, # $e = $e :lt $e -> LessThan( lhs=$0, rhs=$2 )
    3: 7000, # $e = $e :lteq $e -> LessThanOrEqual( lhs=$0, rhs=$2 )
    31: 7000, # $e = $e :gt $e -> GreaterThan( lhs=$0, rhs=$2 )
    30: 7000, # $e = $e :gteq $e -> GreaterThanOrEqual( lhs=$0, rhs=$2 )
    11: 8000, # $e = $e :plus $e -> Add( lhs=$0, rhs=$2 )
    51: 8000, # $e = $e :dash $e -> Subtract( lhs=$0, rhs=$2 )
    9: 9000, # $e = $e :asterisk $e -> Multiply( lhs=$0, rhs=$2 )
    36: 9000, # $e = $e :slash $e -> Divide( lhs=$0, rhs=$2 )
    52: 9000, # $e = $e :percent $e -> Remainder( lhs=$0, rhs=$2 )
    15: 11000, # $e = :identifier <=> :lparen list($e, :comma) :rparen -> FunctionCall( name=$0, params=$2 )
    10: 12000, # $e = :identifier <=> :lsquare $e :rsquare -> ArrayOrMapLookup( lhs=$0, rhs=$2 )
    0: 13000, # $e = :identifier <=> :dot :identifier -> MemberAccess( lhs=$0, rhs=$2 )
}
prefix_binding_power_e = {
    29: 10000, # $e = :not $e -> LogicalNot( expression=$1 )
    11: 10000, # $e = :plus $e -> UnaryPlus( expression=$1 )
    51: 10000, # $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(97, 'e'))
    current = ctx.tokens.current()
    ctx.nonterminal = "e"
    if not current:
        return tree
    elif current.id in rule_first[93]:
        # rule first == not
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :not $e -> LogicalNot( expression=$1 )
        ctx.rule = rules[93]
        ast_parameters = OrderedDict([
            ('expression', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('LogicalNot', ast_parameters)
        tree.nudMorphemeCount = 2
        tree.add(expect(ctx, 29))
        tree.add(parse_e_internal(ctx, get_prefix_binding_power_e(29)))
        tree.isPrefix = True
    elif current.id in rule_first[94]:
        # rule first == plus
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :plus $e -> UnaryPlus( expression=$1 )
        ctx.rule = rules[94]
        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[95]:
        # rule first == dash
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :dash $e -> UnaryNegation( expression=$1 )
        ctx.rule = rules[95]
        ast_parameters = OrderedDict([
            ('expression', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('UnaryNegation', ast_parameters)
        tree.nudMorphemeCount = 2
        tree.add(expect(ctx, 51))
        tree.add(parse_e_internal(ctx, get_prefix_binding_power_e(51)))
        tree.isPrefix = True
    elif current.id in rule_first[97]:
        # rule first == identifier
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :identifier <=> :lparen $_gen18 :rparen -> FunctionCall( name=$0, params=$2 )
        ctx.rule = rules[97]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 33))
    elif current.id in rule_first[98]:
        # rule first == identifier
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :identifier <=> :lsquare $e :rsquare -> ArrayOrMapLookup( lhs=$0, rhs=$2 )
        ctx.rule = rules[98]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 33))
    elif current.id in rule_first[99]:
        # rule first == identifier
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :identifier <=> :dot :identifier -> MemberAccess( lhs=$0, rhs=$2 )
        ctx.rule = rules[99]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 33))
    elif current.id in rule_first[101]:
        # rule first == object
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :object :lbrace $_gen19 :rbrace -> ObjectLiteral( map=$2 )
        ctx.rule = rules[101]
        ast_parameters = OrderedDict([
            ('map', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('ObjectLiteral', ast_parameters)
        tree.nudMorphemeCount = 4
        tree.add(expect(ctx, 41))
        tree.add(expect(ctx, 8))
        tree.add(parse__gen19(ctx))
        tree.add(expect(ctx, 17))
    elif current.id in rule_first[102]:
        # rule first == lsquare
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :lsquare $_gen18 :rsquare -> ArrayLiteral( values=$1 )
        ctx.rule = rules[102]
        ast_parameters = OrderedDict([
            ('values', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('ArrayLiteral', ast_parameters)
        tree.nudMorphemeCount = 3
        tree.add(expect(ctx, 10))
        tree.add(parse__gen18(ctx))
        tree.add(expect(ctx, 46))
    elif current.id in rule_first[104]:
        # rule first == lbrace
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :lbrace $_gen20 :rbrace -> MapLiteral( map=$1 )
        ctx.rule = rules[104]
        ast_parameters = OrderedDict([
            ('map', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('MapLiteral', ast_parameters)
        tree.nudMorphemeCount = 3
        tree.add(expect(ctx, 8))
        tree.add(parse__gen20(ctx))
        tree.add(expect(ctx, 17))
    elif current.id in rule_first[105]:
        # rule first == lparen
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :lparen $_gen18 :rparen -> TupleLiteral( values=$1 )
        ctx.rule = rules[105]
        ast_parameters = OrderedDict([
            ('values', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('TupleLiteral', ast_parameters)
        tree.nudMorphemeCount = 3
        tree.add(expect(ctx, 15))
        tree.add(parse__gen18(ctx))
        tree.add(expect(ctx, 22))
    elif current.id in rule_first[106]:
        # rule first == if
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :if $e :then $e :else $e -> TernaryIf( cond=$1, iftrue=$3, iffalse=$5 )
        ctx.rule = rules[106]
        ast_parameters = OrderedDict([
            ('cond', 1),
            ('iftrue', 3),
            ('iffalse', 5),
        ])
        tree.astTransform = AstTransformNodeCreator('TernaryIf', ast_parameters)
        tree.nudMorphemeCount = 6
        tree.add(expect(ctx, 13))
        tree.add(parse_e(ctx))
        tree.add(expect(ctx, 34))
        tree.add(parse_e(ctx))
        tree.add(expect(ctx, 35))
        tree.add(parse_e(ctx))
    elif current.id in rule_first[107]:
        # rule first == string
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :string
        ctx.rule = rules[107]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 55))
    elif current.id in rule_first[108]:
        # rule first == identifier
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :identifier
        ctx.rule = rules[108]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 33))
    elif current.id in rule_first[109]:
        # rule first == boolean
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :boolean
        ctx.rule = rules[109]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 39))
    elif current.id in rule_first[110]:
        # rule first == integer
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :integer
        ctx.rule = rules[110]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 21))
    elif current.id in rule_first[111]:
        # rule first == float
        # e first == if, identifier, lparen, float, string, integer, dash, e, not, boolean, lbrace, lsquare, plus, object
        # $e = :float
        ctx.rule = rules[111]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 14))
    return tree
def led_e(left, ctx):
    tree = ParseTree(NonTerminal(97, 'e'))
    current = ctx.tokens.current()
    ctx.nonterminal = "e"
    if current.id == 6: # :double_pipe
        # $e = $e :double_pipe $e -> LogicalOr( lhs=$0, rhs=$2 )
        ctx.rule = rules[80]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('LogicalOr', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 6)) # :double_pipe
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(6) - modifier))
    if current.id == 20: # :double_ampersand
        # $e = $e :double_ampersand $e -> LogicalAnd( lhs=$0, rhs=$2 )
        ctx.rule = rules[81]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('LogicalAnd', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 20)) # :double_ampersand
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(20) - modifier))
    if current.id == 27: # :double_equal
        # $e = $e :double_equal $e -> Equals( lhs=$0, rhs=$2 )
        ctx.rule = rules[82]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Equals', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 27)) # :double_equal
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(27) - modifier))
    if current.id == 48: # :not_equal
        # $e = $e :not_equal $e -> NotEquals( lhs=$0, rhs=$2 )
        ctx.rule = rules[83]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('NotEquals', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 48)) # :not_equal
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(48) - modifier))
    if current.id == 28: # :lt
        # $e = $e :lt $e -> LessThan( lhs=$0, rhs=$2 )
        ctx.rule = rules[84]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('LessThan', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 28)) # :lt
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(28) - modifier))
    if current.id == 3: # :lteq
        # $e = $e :lteq $e -> LessThanOrEqual( lhs=$0, rhs=$2 )
        ctx.rule = rules[85]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('LessThanOrEqual', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 3)) # :lteq
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(3) - modifier))
    if current.id == 31: # :gt
        # $e = $e :gt $e -> GreaterThan( lhs=$0, rhs=$2 )
        ctx.rule = rules[86]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('GreaterThan', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 31)) # :gt
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(31) - modifier))
    if current.id == 30: # :gteq
        # $e = $e :gteq $e -> GreaterThanOrEqual( lhs=$0, rhs=$2 )
        ctx.rule = rules[87]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('GreaterThanOrEqual', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 30)) # :gteq
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(30) - modifier))
    if current.id == 11: # :plus
        # $e = $e :plus $e -> Add( lhs=$0, rhs=$2 )
        ctx.rule = rules[88]
        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 == 51: # :dash
        # $e = $e :dash $e -> Subtract( lhs=$0, rhs=$2 )
        ctx.rule = rules[89]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Subtract', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 51)) # :dash
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(51) - modifier))
    if current.id == 9: # :asterisk
        # $e = $e :asterisk $e -> Multiply( lhs=$0, rhs=$2 )
        ctx.rule = rules[90]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Multiply', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 9)) # :asterisk
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(9) - modifier))
    if current.id == 36: # :slash
        # $e = $e :slash $e -> Divide( lhs=$0, rhs=$2 )
        ctx.rule = rules[91]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Divide', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 36)) # :slash
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(36) - modifier))
    if current.id == 52: # :percent
        # $e = $e :percent $e -> Remainder( lhs=$0, rhs=$2 )
        ctx.rule = rules[92]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Remainder', ast_parameters)
        tree.isExprNud = True
        tree.add(left)
        tree.add(expect(ctx, 52)) # :percent
        modifier = 0
        tree.isInfix = True
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(52) - modifier))
    if current.id == 15: # :lparen
        # $e = :identifier <=> :lparen $_gen18 :rparen -> FunctionCall( name=$0, params=$2 )
        ctx.rule = rules[97]
        ast_parameters = OrderedDict([
            ('name', 0),
            ('params', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('FunctionCall', ast_parameters)
        tree.add(left)
        tree.add(expect(ctx, 15)) # :lparen
        tree.add(parse__gen18(ctx))
        tree.add(expect(ctx, 22)) # :rparen
    if current.id == 10: # :lsquare
        # $e = :identifier <=> :lsquare $e :rsquare -> ArrayOrMapLookup( lhs=$0, rhs=$2 )
        ctx.rule = rules[98]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('ArrayOrMapLookup', ast_parameters)
        tree.add(left)
        tree.add(expect(ctx, 10)) # :lsquare
        modifier = 0
        tree.add(parse_e_internal(ctx, get_infix_binding_power_e(10) - modifier))
        tree.add(expect(ctx, 46)) # :rsquare
    if current.id == 0: # :dot
        # $e = :identifier <=> :dot :identifier -> MemberAccess( lhs=$0, rhs=$2 )
        ctx.rule = rules[99]
        ast_parameters = OrderedDict([
            ('lhs', 0),
            ('rhs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('MemberAccess', ast_parameters)
        tree.add(left)
        tree.add(expect(ctx, 0)) # :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 = {
    10: 1000, # $type_e = :type <=> :lsquare list($type_e, :comma) :rsquare -> Type( name=$0, subtype=$2 )
    50: 2000, # $type_e = :type <=> :qmark -> OptionalType( innerType=$0 )
    11: 3000, # $type_e = :type <=> :plus -> NonEmptyType( innerType=$0 )
}
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(72, 'type_e'))
    current = ctx.tokens.current()
    ctx.nonterminal = "type_e"
    if not current:
        return tree
    if current.id in rule_first[76]:
        # rule first == type
        # e first == type_e, type
        # $type_e = :type <=> :lsquare $_gen17 :rsquare -> Type( name=$0, subtype=$2 )
        ctx.rule = rules[76]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 54))
    elif current.id in rule_first[77]:
        # rule first == type
        # e first == type_e, type
        # $type_e = :type <=> :qmark -> OptionalType( innerType=$0 )
        ctx.rule = rules[77]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 54))
    elif current.id in rule_first[78]:
        # rule first == type
        # e first == type_e, type
        # $type_e = :type <=> :plus -> NonEmptyType( innerType=$0 )
        ctx.rule = rules[78]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 54))
    elif current.id in rule_first[79]:
        # rule first == type
        # e first == type_e, type
        # $type_e = :type
        ctx.rule = rules[79]
        tree.astTransform = AstTransformSubstitution(0)
        tree.nudMorphemeCount = 1
        tree.add(expect(ctx, 54))
    return tree
def led_type_e(left, ctx):
    tree = ParseTree(NonTerminal(72, 'type_e'))
    current = ctx.tokens.current()
    ctx.nonterminal = "type_e"
    if current.id == 10: # :lsquare
        # $type_e = :type <=> :lsquare $_gen17 :rsquare -> Type( name=$0, subtype=$2 )
        ctx.rule = rules[76]
        ast_parameters = OrderedDict([
            ('name', 0),
            ('subtype', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Type', ast_parameters)
        tree.add(left)
        tree.add(expect(ctx, 10)) # :lsquare
        tree.add(parse__gen17(ctx))
        tree.add(expect(ctx, 46)) # :rsquare
    if current.id == 50: # :qmark
        # $type_e = :type <=> :qmark -> OptionalType( innerType=$0 )
        ctx.rule = rules[77]
        ast_parameters = OrderedDict([
            ('innerType', 0),
        ])
        tree.astTransform = AstTransformNodeCreator('OptionalType', ast_parameters)
        tree.add(left)
        tree.add(expect(ctx, 50)) # :qmark
    if current.id == 11: # :plus
        # $type_e = :type <=> :plus -> NonEmptyType( innerType=$0 )
        ctx.rule = rules[78]
        ast_parameters = OrderedDict([
            ('innerType', 0),
        ])
        tree.astTransform = AstTransformNodeCreator('NonEmptyType', ast_parameters)
        tree.add(left)
        tree.add(expect(ctx, 11)) # :plus
    return tree
# END definitions for expression parser: type_e
def parse__gen0(ctx):
    tree = ParseTree(NonTerminal(87, '_gen0'))
    tree.list = True
    ctx.nonterminal = "_gen0"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[87] and \
       ctx.tokens.current().id in nonterminal_follow[87]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(87)):
        tree.add(parse_import(ctx))
        ctx.nonterminal = "_gen0" # Horrible -- because parse_* can reset this
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen1(ctx):
    tree = ParseTree(NonTerminal(73, '_gen1'))
    tree.list = True
    ctx.nonterminal = "_gen1"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[73] and \
       ctx.tokens.current().id in nonterminal_follow[73]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(73)):
        tree.add(parse_workflow_or_task_or_decl(ctx))
        ctx.nonterminal = "_gen1" # Horrible -- because parse_* can reset this
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen10(ctx):
    tree = ParseTree(NonTerminal(118, '_gen10'))
    tree.list = True
    ctx.nonterminal = "_gen10"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[118] and \
       ctx.tokens.current().id in nonterminal_follow[118]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(118)):
        tree.add(parse_wf_body_element(ctx))
        ctx.nonterminal = "_gen10" # Horrible -- because parse_* can reset this
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen13(ctx):
    tree = ParseTree(NonTerminal(98, '_gen13'))
    tree.list = True
    ctx.nonterminal = "_gen13"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[98] and \
       ctx.tokens.current().id in nonterminal_follow[98]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(98)):
        tree.add(parse_call_input(ctx))
        ctx.nonterminal = "_gen13" # Horrible -- because parse_* can reset this
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen14(ctx):
    tree = ParseTree(NonTerminal(85, '_gen14'))
    tree.list = True
    tree.list_separator_id = 57
    ctx.nonterminal = "_gen14"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[85] and \
       ctx.tokens.current().id in nonterminal_follow[85]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(85)):
        tree.add(parse_mapping(ctx))
        ctx.nonterminal = "_gen14" # Horrible -- because parse_* can reset this
        if ctx.tokens.current() is not None and ctx.tokens.current().id == 57:
            tree.add(expect(ctx, 57));
        else:
          break
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen15(ctx):
    tree = ParseTree(NonTerminal(81, '_gen15'))
    tree.list = True
    ctx.nonterminal = "_gen15"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[81] and \
       ctx.tokens.current().id in nonterminal_follow[81]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(81)):
        tree.add(parse_wf_output(ctx))
        ctx.nonterminal = "_gen15" # Horrible -- because parse_* can reset this
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen17(ctx):
    tree = ParseTree(NonTerminal(111, '_gen17'))
    tree.list = True
    tree.list_separator_id = 57
    ctx.nonterminal = "_gen17"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[111] and \
       ctx.tokens.current().id in nonterminal_follow[111]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(111)):
        tree.add(parse_type_e(ctx))
        ctx.nonterminal = "_gen17" # Horrible -- because parse_* can reset this
        if ctx.tokens.current() is not None and ctx.tokens.current().id == 57:
            tree.add(expect(ctx, 57));
        else:
          break
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen18(ctx):
    tree = ParseTree(NonTerminal(74, '_gen18'))
    tree.list = True
    tree.list_separator_id = 57
    ctx.nonterminal = "_gen18"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[74] and \
       ctx.tokens.current().id in nonterminal_follow[74]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(74)):
        tree.add(parse_e(ctx))
        ctx.nonterminal = "_gen18" # Horrible -- because parse_* can reset this
        if ctx.tokens.current() is not None and ctx.tokens.current().id == 57:
            tree.add(expect(ctx, 57));
        else:
          break
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen19(ctx):
    tree = ParseTree(NonTerminal(70, '_gen19'))
    tree.list = True
    tree.list_separator_id = 57
    ctx.nonterminal = "_gen19"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[70] and \
       ctx.tokens.current().id in nonterminal_follow[70]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(70)):
        tree.add(parse_object_kv(ctx))
        ctx.nonterminal = "_gen19" # Horrible -- because parse_* can reset this
        if ctx.tokens.current() is not None and ctx.tokens.current().id == 57:
            tree.add(expect(ctx, 57));
        else:
          break
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen20(ctx):
    tree = ParseTree(NonTerminal(112, '_gen20'))
    tree.list = True
    tree.list_separator_id = 57
    ctx.nonterminal = "_gen20"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[112] and \
       ctx.tokens.current().id in nonterminal_follow[112]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(112)):
        tree.add(parse_map_kv(ctx))
        ctx.nonterminal = "_gen20" # Horrible -- because parse_* can reset this
        if ctx.tokens.current() is not None and ctx.tokens.current().id == 57:
            tree.add(expect(ctx, 57));
        else:
          break
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen3(ctx):
    tree = ParseTree(NonTerminal(78, '_gen3'))
    tree.list = True
    ctx.nonterminal = "_gen3"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[78] and \
       ctx.tokens.current().id in nonterminal_follow[78]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(78)):
        tree.add(parse_declaration(ctx))
        ctx.nonterminal = "_gen3" # Horrible -- because parse_* can reset this
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen4(ctx):
    tree = ParseTree(NonTerminal(88, '_gen4'))
    tree.list = True
    ctx.nonterminal = "_gen4"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[88] and \
       ctx.tokens.current().id in nonterminal_follow[88]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(88)):
        tree.add(parse_sections(ctx))
        ctx.nonterminal = "_gen4" # Horrible -- because parse_* can reset this
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen5(ctx):
    tree = ParseTree(NonTerminal(90, '_gen5'))
    tree.list = True
    ctx.nonterminal = "_gen5"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[90] and \
       ctx.tokens.current().id in nonterminal_follow[90]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(90)):
        tree.add(parse_command_part(ctx))
        ctx.nonterminal = "_gen5" # Horrible -- because parse_* can reset this
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen6(ctx):
    tree = ParseTree(NonTerminal(71, '_gen6'))
    tree.list = True
    ctx.nonterminal = "_gen6"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[71] and \
       ctx.tokens.current().id in nonterminal_follow[71]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(71)):
        tree.add(parse_cmd_param_kv(ctx))
        ctx.nonterminal = "_gen6" # Horrible -- because parse_* can reset this
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen7(ctx):
    tree = ParseTree(NonTerminal(93, '_gen7'))
    tree.list = True
    ctx.nonterminal = "_gen7"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[93] and \
       ctx.tokens.current().id in nonterminal_follow[93]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(93)):
        tree.add(parse_output_kv(ctx))
        ctx.nonterminal = "_gen7" # Horrible -- because parse_* can reset this
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen8(ctx):
    tree = ParseTree(NonTerminal(102, '_gen8'))
    tree.list = True
    ctx.nonterminal = "_gen8"
    if ctx.tokens.current() is not None and \
       ctx.tokens.current().id not in nonterminal_first[102] and \
       ctx.tokens.current().id in nonterminal_follow[102]:
        return tree
    if ctx.tokens.current() is None:
        return tree
    minimum = 0
    while minimum > 0 or \
           (ctx.tokens.current() is not None and \
            ctx.tokens.current().id in nonterminal_first.get(102)):
        tree.add(parse_kv(ctx))
        ctx.nonterminal = "_gen8" # Horrible -- because parse_* can reset this
        minimum = max(minimum - 1, 0)
    return tree
def parse__gen11(ctx):
    current = ctx.tokens.current()
    rule = table[28][current.id] if current else -1
    tree = ParseTree(NonTerminal(86, '_gen11'))
    ctx.nonterminal = "_gen11"
    if current != None and current.id in nonterminal_follow[86] and current.id not in nonterminal_first[86]:
        return tree
    if current == None:
        return tree
    if rule == 49: # $_gen11 = $alias
        ctx.rule = rules[49]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_alias(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen12(ctx):
    current = ctx.tokens.current()
    rule = table[9][current.id] if current else -1
    tree = ParseTree(NonTerminal(67, '_gen12'))
    ctx.nonterminal = "_gen12"
    if current != None and current.id in nonterminal_follow[67] and current.id not in nonterminal_first[67]:
        return tree
    if current == None:
        return tree
    if rule == 51: # $_gen12 = $call_body
        ctx.rule = rules[51]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_call_body(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen16(ctx):
    current = ctx.tokens.current()
    rule = table[22][current.id] if current else -1
    tree = ParseTree(NonTerminal(80, '_gen16'))
    ctx.nonterminal = "_gen16"
    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 == 65: # $_gen16 = $wf_output_wildcard
        ctx.rule = rules[65]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_wf_output_wildcard(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen2(ctx):
    current = ctx.tokens.current()
    rule = table[18][current.id] if current else -1
    tree = ParseTree(NonTerminal(76, '_gen2'))
    ctx.nonterminal = "_gen2"
    if current != None and current.id in nonterminal_follow[76] and current.id not in nonterminal_first[76]:
        return tree
    if current == None:
        return tree
    if rule == 6: # $_gen2 = $import_namespace
        ctx.rule = rules[6]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_import_namespace(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse__gen9(ctx):
    current = ctx.tokens.current()
    rule = table[0][current.id] if current else -1
    tree = ParseTree(NonTerminal(58, '_gen9'))
    ctx.nonterminal = "_gen9"
    if current != None and current.id in nonterminal_follow[58] and current.id not in nonterminal_first[58]:
        return tree
    if current == None:
        return tree
    if rule == 34: # $_gen9 = $setter
        ctx.rule = rules[34]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_setter(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_alias(ctx):
    current = ctx.tokens.current()
    rule = table[4][current.id] if current else -1
    tree = ParseTree(NonTerminal(62, 'alias'))
    ctx.nonterminal = "alias"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 59: # $alias = :as :identifier -> $1
        ctx.rule = rules[59]
        tree.astTransform = AstTransformSubstitution(1)
        t = expect(ctx, 47) # :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[62] if x >=0],
      rules[59]
    )
def parse_call(ctx):
    current = ctx.tokens.current()
    rule = table[38][current.id] if current else -1
    tree = ParseTree(NonTerminal(96, 'call'))
    ctx.nonterminal = "call"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 53: # $call = :call :fqn $_gen11 $_gen12 -> Call( task=$1, alias=$2, body=$3 )
        ctx.rule = rules[53]
        ast_parameters = OrderedDict([
            ('task', 1),
            ('alias', 2),
            ('body', 3),
        ])
        tree.astTransform = AstTransformNodeCreator('Call', ast_parameters)
        t = expect(ctx, 24) # :call
        tree.add(t)
        t = expect(ctx, 7) # :fqn
        tree.add(t)
        subtree = parse__gen11(ctx)
        tree.add(subtree)
        subtree = parse__gen12(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[53]
    )
def parse_call_body(ctx):
    current = ctx.tokens.current()
    rule = table[2][current.id] if current else -1
    tree = ParseTree(NonTerminal(60, 'call_body'))
    ctx.nonterminal = "call_body"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 55: # $call_body = :lbrace $_gen3 $_gen13 :rbrace -> CallBody( declarations=$1, io=$2 )
        ctx.rule = rules[55]
        ast_parameters = OrderedDict([
            ('declarations', 1),
            ('io', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('CallBody', ast_parameters)
        t = expect(ctx, 8) # :lbrace
        tree.add(t)
        subtree = parse__gen3(ctx)
        tree.add(subtree)
        subtree = parse__gen13(ctx)
        tree.add(subtree)
        t = expect(ctx, 17) # :rbrace
        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[55]
    )
def parse_call_input(ctx):
    current = ctx.tokens.current()
    rule = table[57][current.id] if current else -1
    tree = ParseTree(NonTerminal(115, 'call_input'))
    ctx.nonterminal = "call_input"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 57: # $call_input = :input :colon $_gen14 -> Inputs( map=$2 )
        ctx.rule = rules[57]
        ast_parameters = OrderedDict([
            ('map', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Inputs', ast_parameters)
        t = expect(ctx, 25) # :input
        tree.add(t)
        t = expect(ctx, 56) # :colon
        tree.add(t)
        subtree = parse__gen14(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[115] if x >=0],
      rules[57]
    )
def parse_cmd_param(ctx):
    current = ctx.tokens.current()
    rule = table[55][current.id] if current else -1
    tree = ParseTree(NonTerminal(113, 'cmd_param'))
    ctx.nonterminal = "cmd_param"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 23: # $cmd_param = :cmd_param_start $_gen6 $e :cmd_param_end -> CommandParameter( attributes=$1, expr=$2 )
        ctx.rule = rules[23]
        ast_parameters = OrderedDict([
            ('attributes', 1),
            ('expr', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('CommandParameter', ast_parameters)
        t = expect(ctx, 19) # :cmd_param_start
        tree.add(t)
        subtree = parse__gen6(ctx)
        tree.add(subtree)
        subtree = parse_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 5) # :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[113] if x >=0],
      rules[23]
    )
def parse_cmd_param_kv(ctx):
    current = ctx.tokens.current()
    rule = table[36][current.id] if current else -1
    tree = ParseTree(NonTerminal(94, 'cmd_param_kv'))
    ctx.nonterminal = "cmd_param_kv"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 24: # $cmd_param_kv = :cmd_attr_hint :identifier :equal $e -> CommandParameterAttr( key=$1, value=$3 )
        ctx.rule = rules[24]
        ast_parameters = OrderedDict([
            ('key', 1),
            ('value', 3),
        ])
        tree.astTransform = AstTransformNodeCreator('CommandParameterAttr', ast_parameters)
        t = expect(ctx, 37) # :cmd_attr_hint
        tree.add(t)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 40) # :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[94] if x >=0],
      rules[24]
    )
def parse_command(ctx):
    current = ctx.tokens.current()
    rule = table[31][current.id] if current else -1
    tree = ParseTree(NonTerminal(89, 'command'))
    ctx.nonterminal = "command"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 19: # $command = :raw_command :raw_cmd_start $_gen5 :raw_cmd_end -> RawCommand( parts=$2 )
        ctx.rule = rules[19]
        ast_parameters = OrderedDict([
            ('parts', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('RawCommand', ast_parameters)
        t = expect(ctx, 43) # :raw_command
        tree.add(t)
        t = expect(ctx, 44) # :raw_cmd_start
        tree.add(t)
        subtree = parse__gen5(ctx)
        tree.add(subtree)
        t = expect(ctx, 23) # :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[89] if x >=0],
      rules[19]
    )
def parse_command_part(ctx):
    current = ctx.tokens.current()
    rule = table[8][current.id] if current else -1
    tree = ParseTree(NonTerminal(66, 'command_part'))
    ctx.nonterminal = "command_part"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 20: # $command_part = :cmd_part
        ctx.rule = rules[20]
        tree.astTransform = AstTransformSubstitution(0)
        t = expect(ctx, 45) # :cmd_part
        tree.add(t)
        return tree
    elif rule == 21: # $command_part = $cmd_param
        ctx.rule = rules[21]
        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[66] if x >=0],
      rules[21]
    )
def parse_declaration(ctx):
    current = ctx.tokens.current()
    rule = table[50][current.id] if current else -1
    tree = ParseTree(NonTerminal(108, 'declaration'))
    ctx.nonterminal = "declaration"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 36: # $declaration = $type_e :identifier $_gen9 -> Declaration( type=$0, name=$1, expression=$2 )
        ctx.rule = rules[36]
        ast_parameters = OrderedDict([
            ('type', 0),
            ('name', 1),
            ('expression', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Declaration', ast_parameters)
        subtree = parse_type_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        subtree = parse__gen9(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[108] if x >=0],
      rules[36]
    )
def parse_document(ctx):
    current = ctx.tokens.current()
    rule = table[42][current.id] if current else -1
    tree = ParseTree(NonTerminal(100, 'document'))
    ctx.nonterminal = "document"
    if current != None and current.id in nonterminal_follow[100] and current.id not in nonterminal_first[100]:
        return tree
    if current == None:
        return tree
    if rule == 2: # $document = $_gen0 $_gen1 -> Namespace( imports=$0, body=$1 )
        ctx.rule = rules[2]
        ast_parameters = OrderedDict([
            ('imports', 0),
            ('body', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('Namespace', ast_parameters)
        subtree = parse__gen0(ctx)
        tree.add(subtree)
        subtree = parse__gen1(ctx)
        tree.add(subtree)
        return tree
    return tree
def parse_if_stmt(ctx):
    current = ctx.tokens.current()
    rule = table[48][current.id] if current else -1
    tree = ParseTree(NonTerminal(106, 'if_stmt'))
    ctx.nonterminal = "if_stmt"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 72: # $if_stmt = :if :lparen $e :rparen :lbrace $_gen10 :rbrace -> If( expression=$2, body=$5 )
        ctx.rule = rules[72]
        ast_parameters = OrderedDict([
            ('expression', 2),
            ('body', 5),
        ])
        tree.astTransform = AstTransformNodeCreator('If', ast_parameters)
        t = expect(ctx, 13) # :if
        tree.add(t)
        t = expect(ctx, 15) # :lparen
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 22) # :rparen
        tree.add(t)
        t = expect(ctx, 8) # :lbrace
        tree.add(t)
        subtree = parse__gen10(ctx)
        tree.add(subtree)
        t = expect(ctx, 17) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[106] if x >=0],
      rules[72]
    )
def parse_import(ctx):
    current = ctx.tokens.current()
    rule = table[5][current.id] if current else -1
    tree = ParseTree(NonTerminal(63, 'import'))
    ctx.nonterminal = "import"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 8: # $import = :import :string $_gen2 -> Import( uri=$1, namespace=$2 )
        ctx.rule = rules[8]
        ast_parameters = OrderedDict([
            ('uri', 1),
            ('namespace', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Import', ast_parameters)
        t = expect(ctx, 2) # :import
        tree.add(t)
        t = expect(ctx, 55) # :string
        tree.add(t)
        subtree = parse__gen2(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[63] if x >=0],
      rules[8]
    )
def parse_import_namespace(ctx):
    current = ctx.tokens.current()
    rule = table[24][current.id] if current else -1
    tree = ParseTree(NonTerminal(82, 'import_namespace'))
    ctx.nonterminal = "import_namespace"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 9: # $import_namespace = :as :identifier -> $1
        ctx.rule = rules[9]
        tree.astTransform = AstTransformSubstitution(1)
        t = expect(ctx, 47) # :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[82] if x >=0],
      rules[9]
    )
def parse_kv(ctx):
    current = ctx.tokens.current()
    rule = table[41][current.id] if current else -1
    tree = ParseTree(NonTerminal(99, 'kv'))
    ctx.nonterminal = "kv"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 33: # $kv = :identifier :colon $e -> RuntimeAttribute( key=$0, value=$2 )
        ctx.rule = rules[33]
        ast_parameters = OrderedDict([
            ('key', 0),
            ('value', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('RuntimeAttribute', ast_parameters)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 56) # :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[33]
    )
def parse_map(ctx):
    current = ctx.tokens.current()
    rule = table[21][current.id] if current else -1
    tree = ParseTree(NonTerminal(79, 'map'))
    ctx.nonterminal = "map"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 32: # $map = :lbrace $_gen8 :rbrace -> $1
        ctx.rule = rules[32]
        tree.astTransform = AstTransformSubstitution(1)
        t = expect(ctx, 8) # :lbrace
        tree.add(t)
        subtree = parse__gen8(ctx)
        tree.add(subtree)
        t = expect(ctx, 17) # :rbrace
        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[32]
    )
def parse_map_kv(ctx):
    current = ctx.tokens.current()
    rule = table[11][current.id] if current else -1
    tree = ParseTree(NonTerminal(69, 'map_kv'))
    ctx.nonterminal = "map_kv"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 38: # $map_kv = $e :colon $e -> MapLiteralKv( key=$0, value=$2 )
        ctx.rule = rules[38]
        ast_parameters = OrderedDict([
            ('key', 0),
            ('value', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('MapLiteralKv', ast_parameters)
        subtree = parse_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 56) # :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[69] if x >=0],
      rules[38]
    )
def parse_mapping(ctx):
    current = ctx.tokens.current()
    rule = table[47][current.id] if current else -1
    tree = ParseTree(NonTerminal(105, 'mapping'))
    ctx.nonterminal = "mapping"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 58: # $mapping = :identifier :equal $e -> IOMapping( key=$0, value=$2 )
        ctx.rule = rules[58]
        ast_parameters = OrderedDict([
            ('key', 0),
            ('value', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('IOMapping', ast_parameters)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 40) # :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[105] if x >=0],
      rules[58]
    )
def parse_meta(ctx):
    current = ctx.tokens.current()
    rule = table[52][current.id] if current else -1
    tree = ParseTree(NonTerminal(110, 'meta'))
    ctx.nonterminal = "meta"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 30: # $meta = :meta $map -> Meta( map=$1 )
        ctx.rule = rules[30]
        ast_parameters = OrderedDict([
            ('map', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('Meta', ast_parameters)
        t = expect(ctx, 42) # :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[110] if x >=0],
      rules[30]
    )
def parse_object_kv(ctx):
    current = ctx.tokens.current()
    rule = table[37][current.id] if current else -1
    tree = ParseTree(NonTerminal(95, 'object_kv'))
    ctx.nonterminal = "object_kv"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 74: # $object_kv = :identifier :colon $e -> ObjectKV( key=$0, value=$2 )
        ctx.rule = rules[74]
        ast_parameters = OrderedDict([
            ('key', 0),
            ('value', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('ObjectKV', ast_parameters)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 56) # :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[95] if x >=0],
      rules[74]
    )
def parse_output_kv(ctx):
    current = ctx.tokens.current()
    rule = table[34][current.id] if current else -1
    tree = ParseTree(NonTerminal(92, 'output_kv'))
    ctx.nonterminal = "output_kv"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 27: # $output_kv = $type_e :identifier :equal $e -> Output( type=$0, name=$1, expression=$3 )
        ctx.rule = rules[27]
        ast_parameters = OrderedDict([
            ('type', 0),
            ('name', 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, 40) # :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[92] if x >=0],
      rules[27]
    )
def parse_outputs(ctx):
    current = ctx.tokens.current()
    rule = table[45][current.id] if current else -1
    tree = ParseTree(NonTerminal(103, 'outputs'))
    ctx.nonterminal = "outputs"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 26: # $outputs = :output :lbrace $_gen7 :rbrace -> Outputs( attributes=$2 )
        ctx.rule = rules[26]
        ast_parameters = OrderedDict([
            ('attributes', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('Outputs', ast_parameters)
        t = expect(ctx, 32) # :output
        tree.add(t)
        t = expect(ctx, 8) # :lbrace
        tree.add(t)
        subtree = parse__gen7(ctx)
        tree.add(subtree)
        t = expect(ctx, 17) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[103] if x >=0],
      rules[26]
    )
def parse_parameter_meta(ctx):
    current = ctx.tokens.current()
    rule = table[43][current.id] if current else -1
    tree = ParseTree(NonTerminal(101, 'parameter_meta'))
    ctx.nonterminal = "parameter_meta"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 29: # $parameter_meta = :parameter_meta $map -> ParameterMeta( map=$1 )
        ctx.rule = rules[29]
        ast_parameters = OrderedDict([
            ('map', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('ParameterMeta', ast_parameters)
        t = expect(ctx, 49) # :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[101] if x >=0],
      rules[29]
    )
def parse_runtime(ctx):
    current = ctx.tokens.current()
    rule = table[33][current.id] if current else -1
    tree = ParseTree(NonTerminal(91, 'runtime'))
    ctx.nonterminal = "runtime"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 28: # $runtime = :runtime $map -> Runtime( map=$1 )
        ctx.rule = rules[28]
        ast_parameters = OrderedDict([
            ('map', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('Runtime', ast_parameters)
        t = expect(ctx, 18) # :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[91] if x >=0],
      rules[28]
    )
def parse_scatter(ctx):
    current = ctx.tokens.current()
    rule = table[51][current.id] if current else -1
    tree = ParseTree(NonTerminal(109, 'scatter'))
    ctx.nonterminal = "scatter"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 73: # $scatter = :scatter :lparen :identifier :in $e :rparen :lbrace $_gen10 :rbrace -> Scatter( item=$2, collection=$4, body=$7 )
        ctx.rule = rules[73]
        ast_parameters = OrderedDict([
            ('item', 2),
            ('collection', 4),
            ('body', 7),
        ])
        tree.astTransform = AstTransformNodeCreator('Scatter', ast_parameters)
        t = expect(ctx, 1) # :scatter
        tree.add(t)
        t = expect(ctx, 15) # :lparen
        tree.add(t)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 4) # :in
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 22) # :rparen
        tree.add(t)
        t = expect(ctx, 8) # :lbrace
        tree.add(t)
        subtree = parse__gen10(ctx)
        tree.add(subtree)
        t = expect(ctx, 17) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[109] if x >=0],
      rules[73]
    )
def parse_sections(ctx):
    current = ctx.tokens.current()
    rule = table[1][current.id] if current else -1
    tree = ParseTree(NonTerminal(59, 'sections'))
    ctx.nonterminal = "sections"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 13: # $sections = $command
        ctx.rule = rules[13]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_command(ctx)
        tree.add(subtree)
        return tree
    elif rule == 14: # $sections = $outputs
        ctx.rule = rules[14]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_outputs(ctx)
        tree.add(subtree)
        return tree
    elif rule == 15: # $sections = $runtime
        ctx.rule = rules[15]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_runtime(ctx)
        tree.add(subtree)
        return tree
    elif rule == 16: # $sections = $parameter_meta
        ctx.rule = rules[16]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_parameter_meta(ctx)
        tree.add(subtree)
        return tree
    elif rule == 17: # $sections = $meta
        ctx.rule = rules[17]
        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[59] if x >=0],
      rules[17]
    )
def parse_setter(ctx):
    current = ctx.tokens.current()
    rule = table[26][current.id] if current else -1
    tree = ParseTree(NonTerminal(84, 'setter'))
    ctx.nonterminal = "setter"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 37: # $setter = :equal $e -> $1
        ctx.rule = rules[37]
        tree.astTransform = AstTransformSubstitution(1)
        t = expect(ctx, 40) # :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[84] if x >=0],
      rules[37]
    )
def parse_task(ctx):
    current = ctx.tokens.current()
    rule = table[7][current.id] if current else -1
    tree = ParseTree(NonTerminal(65, 'task'))
    ctx.nonterminal = "task"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 12: # $task = :task :identifier :lbrace $_gen3 $_gen4 :rbrace -> Task( name=$1, declarations=$3, sections=$4 )
        ctx.rule = rules[12]
        ast_parameters = OrderedDict([
            ('name', 1),
            ('declarations', 3),
            ('sections', 4),
        ])
        tree.astTransform = AstTransformNodeCreator('Task', ast_parameters)
        t = expect(ctx, 12) # :task
        tree.add(t)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 8) # :lbrace
        tree.add(t)
        subtree = parse__gen3(ctx)
        tree.add(subtree)
        subtree = parse__gen4(ctx)
        tree.add(subtree)
        t = expect(ctx, 17) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[65] if x >=0],
      rules[12]
    )
def parse_wf_body_element(ctx):
    current = ctx.tokens.current()
    rule = table[19][current.id] if current else -1
    tree = ParseTree(NonTerminal(77, 'wf_body_element'))
    ctx.nonterminal = "wf_body_element"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 41: # $wf_body_element = $call
        ctx.rule = rules[41]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_call(ctx)
        tree.add(subtree)
        return tree
    elif rule == 42: # $wf_body_element = $declaration
        ctx.rule = rules[42]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_declaration(ctx)
        tree.add(subtree)
        return tree
    elif rule == 43: # $wf_body_element = $while_loop
        ctx.rule = rules[43]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_while_loop(ctx)
        tree.add(subtree)
        return tree
    elif rule == 44: # $wf_body_element = $if_stmt
        ctx.rule = rules[44]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_if_stmt(ctx)
        tree.add(subtree)
        return tree
    elif rule == 45: # $wf_body_element = $scatter
        ctx.rule = rules[45]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_scatter(ctx)
        tree.add(subtree)
        return tree
    elif rule == 46: # $wf_body_element = $wf_outputs
        ctx.rule = rules[46]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_wf_outputs(ctx)
        tree.add(subtree)
        return tree
    elif rule == 47: # $wf_body_element = $wf_parameter_meta
        ctx.rule = rules[47]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_wf_parameter_meta(ctx)
        tree.add(subtree)
        return tree
    elif rule == 48: # $wf_body_element = $wf_meta
        ctx.rule = rules[48]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_wf_meta(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[77] if x >=0],
      rules[48]
    )
def parse_wf_meta(ctx):
    current = ctx.tokens.current()
    rule = table[17][current.id] if current else -1
    tree = ParseTree(NonTerminal(75, 'wf_meta'))
    ctx.nonterminal = "wf_meta"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 70: # $wf_meta = :meta $map -> Meta( map=$1 )
        ctx.rule = rules[70]
        ast_parameters = OrderedDict([
            ('map', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('Meta', ast_parameters)
        t = expect(ctx, 42) # :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[75] if x >=0],
      rules[70]
    )
def parse_wf_output(ctx):
    current = ctx.tokens.current()
    rule = table[58][current.id] if current else -1
    tree = ParseTree(NonTerminal(116, 'wf_output'))
    ctx.nonterminal = "wf_output"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 62: # $wf_output = $wf_output_declaration_syntax
        ctx.rule = rules[62]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_wf_output_declaration_syntax(ctx)
        tree.add(subtree)
        return tree
    elif rule == 63: # $wf_output = $wf_output_wildcard_syntax
        ctx.rule = rules[63]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_wf_output_wildcard_syntax(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[63]
    )
def parse_wf_output_declaration_syntax(ctx):
    current = ctx.tokens.current()
    rule = table[10][current.id] if current else -1
    tree = ParseTree(NonTerminal(68, 'wf_output_declaration_syntax'))
    ctx.nonterminal = "wf_output_declaration_syntax"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 64: # $wf_output_declaration_syntax = $type_e :identifier :equal $e -> WorkflowOutputDeclaration( type=$0, name=$1, expression=$3 )
        ctx.rule = rules[64]
        ast_parameters = OrderedDict([
            ('type', 0),
            ('name', 1),
            ('expression', 3),
        ])
        tree.astTransform = AstTransformNodeCreator('WorkflowOutputDeclaration', ast_parameters)
        subtree = parse_type_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 33) # :identifier
        tree.add(t)
        t = expect(ctx, 40) # :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[68] if x >=0],
      rules[64]
    )
def parse_wf_output_wildcard(ctx):
    current = ctx.tokens.current()
    rule = table[59][current.id] if current else -1
    tree = ParseTree(NonTerminal(117, 'wf_output_wildcard'))
    ctx.nonterminal = "wf_output_wildcard"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 68: # $wf_output_wildcard = :dot :asterisk -> $1
        ctx.rule = rules[68]
        tree.astTransform = AstTransformSubstitution(1)
        t = expect(ctx, 0) # :dot
        tree.add(t)
        t = expect(ctx, 9) # :asterisk
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[117] if x >=0],
      rules[68]
    )
def parse_wf_output_wildcard_syntax(ctx):
    current = ctx.tokens.current()
    rule = table[3][current.id] if current else -1
    tree = ParseTree(NonTerminal(61, 'wf_output_wildcard_syntax'))
    ctx.nonterminal = "wf_output_wildcard_syntax"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 67: # $wf_output_wildcard_syntax = :fqn $_gen16 -> WorkflowOutputWildcard( fqn=$0, wildcard=$1 )
        ctx.rule = rules[67]
        ast_parameters = OrderedDict([
            ('fqn', 0),
            ('wildcard', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('WorkflowOutputWildcard', ast_parameters)
        t = expect(ctx, 7) # :fqn
        tree.add(t)
        subtree = parse__gen16(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[61] if x >=0],
      rules[67]
    )
def parse_wf_outputs(ctx):
    current = ctx.tokens.current()
    rule = table[6][current.id] if current else -1
    tree = ParseTree(NonTerminal(64, 'wf_outputs'))
    ctx.nonterminal = "wf_outputs"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 61: # $wf_outputs = :output :lbrace $_gen15 :rbrace -> WorkflowOutputs( outputs=$2 )
        ctx.rule = rules[61]
        ast_parameters = OrderedDict([
            ('outputs', 2),
        ])
        tree.astTransform = AstTransformNodeCreator('WorkflowOutputs', ast_parameters)
        t = expect(ctx, 32) # :output
        tree.add(t)
        t = expect(ctx, 8) # :lbrace
        tree.add(t)
        subtree = parse__gen15(ctx)
        tree.add(subtree)
        t = expect(ctx, 17) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[64] if x >=0],
      rules[61]
    )
def parse_wf_parameter_meta(ctx):
    current = ctx.tokens.current()
    rule = table[56][current.id] if current else -1
    tree = ParseTree(NonTerminal(114, 'wf_parameter_meta'))
    ctx.nonterminal = "wf_parameter_meta"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 69: # $wf_parameter_meta = :parameter_meta $map -> ParameterMeta( map=$1 )
        ctx.rule = rules[69]
        ast_parameters = OrderedDict([
            ('map', 1),
        ])
        tree.astTransform = AstTransformNodeCreator('ParameterMeta', ast_parameters)
        t = expect(ctx, 49) # :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[114] if x >=0],
      rules[69]
    )
def parse_while_loop(ctx):
    current = ctx.tokens.current()
    rule = table[46][current.id] if current else -1
    tree = ParseTree(NonTerminal(104, 'while_loop'))
    ctx.nonterminal = "while_loop"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 71: # $while_loop = :while :lparen $e :rparen :lbrace $_gen10 :rbrace -> WhileLoop( expression=$2, body=$5 )
        ctx.rule = rules[71]
        ast_parameters = OrderedDict([
            ('expression', 2),
            ('body', 5),
        ])
        tree.astTransform = AstTransformNodeCreator('WhileLoop', ast_parameters)
        t = expect(ctx, 16) # :while
        tree.add(t)
        t = expect(ctx, 15) # :lparen
        tree.add(t)
        subtree = parse_e(ctx)
        tree.add(subtree)
        t = expect(ctx, 22) # :rparen
        tree.add(t)
        t = expect(ctx, 8) # :lbrace
        tree.add(t)
        subtree = parse__gen10(ctx)
        tree.add(subtree)
        t = expect(ctx, 17) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[104] if x >=0],
      rules[71]
    )
def parse_workflow(ctx):
    current = ctx.tokens.current()
    rule = table[49][current.id] if current else -1
    tree = ParseTree(NonTerminal(107, 'workflow'))
    ctx.nonterminal = "workflow"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 40: # $workflow = :workflow :identifier :lbrace $_gen10 :rbrace -> Workflow( name=$1, body=$3 )
        ctx.rule = rules[40]
        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, 8) # :lbrace
        tree.add(t)
        subtree = parse__gen10(ctx)
        tree.add(subtree)
        t = expect(ctx, 17) # :rbrace
        tree.add(t)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[107] if x >=0],
      rules[40]
    )
def parse_workflow_or_task_or_decl(ctx):
    current = ctx.tokens.current()
    rule = table[25][current.id] if current else -1
    tree = ParseTree(NonTerminal(83, 'workflow_or_task_or_decl'))
    ctx.nonterminal = "workflow_or_task_or_decl"
    if current == None:
        raise ctx.errors.unexpected_eof()
    if rule == 3: # $workflow_or_task_or_decl = $workflow
        ctx.rule = rules[3]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_workflow(ctx)
        tree.add(subtree)
        return tree
    elif rule == 4: # $workflow_or_task_or_decl = $task
        ctx.rule = rules[4]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_task(ctx)
        tree.add(subtree)
        return tree
    elif rule == 5: # $workflow_or_task_or_decl = $declaration
        ctx.rule = rules[5]
        tree.astTransform = AstTransformSubstitution(0)
        subtree = parse_declaration(ctx)
        tree.add(subtree)
        return tree
    raise ctx.errors.unexpected_symbol(
      ctx.nonterminal,
      ctx.tokens.current(),
      [terminals[x] for x in nonterminal_first[83] if x >=0],
      rules[5]
    )
# 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 wdl_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("\u005C\u005C", "\u005C")
    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, chr(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 post_filter(tokens):
    return tokens
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'then(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('then', 0, None),
          ]),
          (re.compile(r'else(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('else', 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|Pair|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, wdl_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, wdl_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)
          ]),
          (re.compile(r'(Array|Map|Object|Pair|Boolean|Int|Float|Uri|File|String)(?![a-zA-Z0-9_])(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('type', 0, None),
              LexerAction('pop'),
              LexerStackPush('wf_output_declaration'),
          ]),
          (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),
          ]),
        ]),
        'wf_output_declaration': OrderedDict([
          (re.compile(r'\s+'), [
              # (terminal, group, function)
          ]),
          (re.compile(r'#.*'), [
              # (terminal, group, function)
          ]),
          (re.compile(r'\}'), [
              # (terminal, group, function)
              ('rbrace', 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)
              ('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'if'), [
              # (terminal, group, function)
              ('if', 0, None),
          ]),
          (re.compile(r'else'), [
              # (terminal, group, function)
              ('else', 0, None),
          ]),
          (re.compile(r'then'), [
              # (terminal, group, function)
              ('then', 0, None),
          ]),
          (re.compile(r'(Array|Map|Object|Pair|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':'), [
              # (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)
              ('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'\?'), [
              # (terminal, group, function)
              ('qmark', 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, wdl_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, wdl_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),
          ]),
        ]),
        '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)
              ('lparen', 0, None),
          ]),
          (re.compile(r'in(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('in', 0, None),
              LexerAction('pop'),
          ]),
          (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'if'), [
              # (terminal, group, function)
              ('if', 0, None),
          ]),
          (re.compile(r'else'), [
              # (terminal, group, function)
              ('else', 0, None),
          ]),
          (re.compile(r'then'), [
              # (terminal, group, function)
              ('then', 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'(true|false)(?![a-zA-Z0-9_])'), [
              # (terminal, group, function)
              ('boolean', 0, None),
          ]),
          (re.compile(r'(Array|Map|Object|Pair|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':'), [
              # (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, wdl_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, wdl_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)
        filtered = post_filter(ctx.tokens)
        return filtered
def lex(source, resource, errors=None, debug=False):
    return TokenStream(HermesLexer().lex(source, resource, errors, debug))
