text: #
  # Contain syntax and grammar specifications
  #
  
  import sys
  import variable, tool.ply.lex, tool.ply.yacc
  from orio.main.util.globals import *
  
  #------------------------------------------------
  
  __start_line_no = 1
  
  #------------------------------------------------
  
  # reserved words
  reserved = []
  
  tokens = reserved + [
      # literals (identifier, integer constant)
      'ID', 'ICONST',
  
      # delimeters [ ] , 
      'LBRACKET', 'RBRACKET',
      'COMMA'
      ]
  
  # tokens
  t_LBRACKET         = r'\['
  t_RBRACKET         = r'\]'
  t_COMMA            = r','
  
  # ignored characters
  t_ignore = ' \t'
  
  # newlines
  def t_NEWLINE(t):
      r'\n+'
      t.lineno += t.value.count('\n')
  
  # identifiers and reserved words
  reserved_map = {}
  for r in reserved:
      reserved_map[r.lower()] = r
  
  def t_ID(t):
      r'[A-Za-z_]\w*'
      t.type = reserved_map.get(t.value,'ID')
      return t
  
  # integer literal
  t_ICONST = r'\d+'
  
  # syntactical error
  def t_error(t):
      err('orio.module.align.parser:%s: syntactical error: "%s"' % ((t.lineno + __start_line_no - 1),
                                                   t.value[0]))
      
  #------------------------------------------------
  
  # grammar
  def p_annote(p):
      'annote : var_list_opt'
      p[0] = p[1]
  
  def p_var_list_opt_1(p):
      'var_list_opt :'
      p[0] = []
  
  def p_var_list_opt_2(p):
      'var_list_opt : var_list'
      p[0] = p[1]
  
  def p_var_list_1(p):
      'var_list : var'
      p[0] = [p[1]]
  
  def p_var_list_2(p):
      'var_list : var_list COMMA var'
      p[1].append(p[3])
      p[0] = p[1]
  
  def p_var(p):
      'var : ID dimensions'
      p[0] = variable.Variable(p[1], p[2], p.lineno(1) + __start_line_no - 1)
  
  def p_dimensions_1(p):
      'dimensions : LBRACKET RBRACKET'
      p[0] = [None]
  
  def p_dimensions_2(p):
      'dimensions : LBRACKET index RBRACKET'
      p[0] = [p[2]]
  
  def p_dimensions_3(p):
      'dimensions : dimensions LBRACKET RBRACKET'
      p[1].append(None)
      p[0] = p[1]
  
  def p_dimensions_4(p):
      'dimensions : dimensions LBRACKET index RBRACKET'
      p[1].append(p[3])
      p[0] = p[1]
  
  def p_index_1(p):
      'index : ID'
      p[0] = p[1]
  
  def p_index_2(p):
      'index : ICONST'
      p[0] = p[1]
  
  # grammatical error
  def p_error(p):
      err('orio.module.align.parser: %s: grammatical error: "%s"' % ((p.lineno + __start_line_no - 1), p.value))
  
  #------------------------------------------------
  
  def getParser(start_line_no):
      '''Create the parser'''
  
      # set the starting line number
      global __start_line_no 
      __start_line_no = start_line_no
  
      # create the lexer and parser
      lexer = tool.ply.lex.lex()
      parser = tool.ply.yacc.yacc(method='LALR', debug=0, optimize=1, write_tables=0)
  
      # return the parser
      return parser
  
  