def Parse(gp):
    startline = 0

    ps = pstate(
        gp = gp,
        filename = gp.filename,
        errorcnt = 0,
        state = INITIALIZE,
        tokenlineno = 0,
        tokenstart = None,
        fallback = None,
        lhs = None,
        lhsalias = None,
        nrhs = 0,
        rhs = [None] * MAXRHS,
        alias = [None] * MAXRHS,
        prevrule = None,
        declkeyword = None,
        declargslot = None,
        insertLineMacro = False,
        declassoc = 0,
        preccounter = 0,
        firstrule = None,
        lastrule = None,
        )

    # Begin by reading the input file
    try:
        fp = open(ps.filename, "rb")
    except IOError:
        ErrorMsg(ps.filename, 0, "Can't open this file for reading.")
        gp.errorcnt += 1
        return
    filebuf = fp.read()
    fp.close()

    lineno = 1


    # Now scan the text of the input file

    cp = 0
    while cp < len(filebuf):
        c = filebuf[cp]

        # Keep track of the line number
        if c == '\n':
            lineno += 1

        # Skip all white space
        if c.isspace():
            cp += 1
            continue

        # Skip C++ style comments
        if filebuf[cp:cp+2] == "//":
            cp += 2
            while cp < len(filebuf):
                if filebuf[cp] == '\n':
                    break
                cp += 1
            continue

        # Skip C style comments
        if filebuf[cp:cp+2] == "/*":
            cp += 2
            while cp < len(filebuf):
                if filebuf[cp] == '\n':
                    lineno += 1
                if filebuf[cp-1:cp+1] == '*/':
                    cp += 1
                    break
                cp += 1
            continue

        ps.tokenstart = cp         # Mark the beginning of the token
        ps.tokenlineno = lineno    # Linenumber on which token begins

        if c == '"':
            # String literals
            cp += 1
            while cp < len(filebuf):
                c = filebuf[cp]
                if c == '"':
                    nextcp = cp + 1
                    break
                if c == '\n':
                    lineno += 1
                cp += 1
            else:
                ErrorMsg(ps.filename, startline,
                         "String starting on this line is not terminated "
                         "before the end of the file.")
                ps.errorcnt += 1
                nextcp = cp

        elif c == '{':
            # A block of C code
            cp += 1
            level = 1
            while cp < len(filebuf) and (level > 1 or filebuf[cp] != '}'):
                c = filebuf[cp]
                if c == '\n':
                    lineno += 1
                elif c == '{':
                    level += 1
                elif c == '}':
                    level -= 1

                elif filebuf[cp:cp+2] == "/*":
                    # Skip comments
                    cp += 2
                    while cp < len(filebuf):
                        c = filebuf[cp]
                        if filebuf[cp] == '\n':
                            lineno += 1
                        if filebuf[cp-1:cp+1] == '*/':
                            cp += 1
                            break
                        cp += 1

                elif filebuf[cp:cp+2] == "//":
                    # Skip C++ style comments too
                    cp += 2
                    while cp < len(filebuf):
                        if filebuf[cp] == '\n':
                            lineno += 1
                            break
                        cp += 1

                elif c == "'" or c == '"':
                    # String and character literals
                    startchar = c
                    prevc = 0
                    cp += 1
                    while (cp < len(filebuf) and
                           (filebuf[cp] != startchar or prevc == '\\')
                           ):
                        c = filebuf[cp]
                        if c == '\n':
                            lineno += 1
                        if prevc == '\\':
                            prevc = 0
                        else:
                            prevc = c
                        cp += 1

                cp += 1

            if cp == len(filebuf):
                ErrorMsg(ps.filename, ps.tokenlineno,
                         "C code starting on this line is not terminated "
                         "before the end of the file.")
                ps.errorcnt += 1
                nextcp = cp
            else:
                nextcp = cp + 1

        elif c.isalnum():
            # Identifiers
            while c.isalnum() or c == '_':
                cp += 1
                if cp > len(filebuf):
                    break
                c = filebuf[cp]
            nextcp = cp

        elif filebuf[cp:cp+3] == "::=":
            # The operator "::="
            cp += 3
            nextcp = cp

        elif (c in ('/', '|')) and cp+1 < len(filebuf) and filebuf[cp+1].isalpha():
            cp += 2
            while cp < len(filebuf):
                c = filebuf[cp]
                if not (c.isalnum() or c == '_'):
                    break
                cp += 1
            nextcp = cp

        else:
            # All other (one character) operators
            cp += 1
            nextcp = cp

        # Parse the token
        token = filebuf[ps.tokenstart:cp]
        parseonetoken(ps, token)

        cp = nextcp

    gp.rule = ps.firstrule
    gp.errorcnt = ps.errorcnt

    return
dataset/ETHPy150Open probcomp/bayeslite/external/lemonade/dist/lemonade/parse.py/Parse/original