def t_string(self, s, m, parent):
     r"[^ \t\n()\\;{}&]+(\\(.|\n)[^ \t\n()\\;{}&]*)*"
     # What other characters are forbidden in unquoted strings?
     # Allowing escaped newlines, blanks, quotes, etc.
     # Increment line count for embedded newlines (after adding token)
     parent.addToken(type=parent.argsep)
     parent.argsep = ","
     nline = _countNewlines(s)
     s = irafutils.removeEscapes(s)
     parent.addToken(type="STRING", attr=s)
     parent.lineno = parent.lineno + nline
    def t_doublequote(self, s, m, parent):
        r'" [^"\\\n]* ( ( ((\\(.|\n)|\n)[\s?]*) | "" ) [^"\\\n]* )* "'
        if parent.current[-1] == _COMMAND_MODE:
            parent.addToken(type=parent.argsep)
            parent.argsep = ","

        nline = _countNewlines(s)

        # Recognize and remove any embedded comments
        s = comment_pat.sub("", s)

        s = irafutils.removeEscapes(irafutils.stripQuotes(s), quoted=1)
        parent.addToken(type="QSTRING", attr=s)
        parent.lineno = parent.lineno + nline
    def t_singlequote(self, s, m, parent):
        r"' [^'\\\n]* ( ( ((\\(.|\n)|\n)[\s?]*) | '' ) [^'\\\n]* )*'"
        # this pattern allows both escaped embedded quotes and
        # embedded double quotes ('embedded''quotes')
        # it also allows escaped newlines
        if parent.current[-1] == _COMMAND_MODE:
            parent.addToken(type=parent.argsep)
            parent.argsep = ","

        nline = _countNewlines(s)
        # Recognize and remove any embedded comments
        s = comment_pat.sub("", s)

        s = irafutils.removeEscapes(irafutils.stripQuotes(s), quoted=1)
        # We use a different type for quoted strings to protect them
        # against conversion to other token types by enterComputeEqnMode
        parent.addToken(type="QSTRING", attr=s)
        parent.lineno = parent.lineno + nline