[3027] | 1 | # |
---|

| 2 | # Recursive Parenthesis Matching |
---|

| 3 | # |
---|

| 4 | # |
---|

| 5 | # Robert D. Cameron |
---|

| 6 | # October 14, 2012 |
---|

| 7 | # |
---|

| 8 | |
---|

| 9 | class Basis_bits(): |
---|

| 10 | bit_0 = 0 |
---|

| 11 | bit_1 = 0 |
---|

| 12 | bit_2 = 0 |
---|

| 13 | bit_3 = 0 |
---|

| 14 | bit_4 = 0 |
---|

| 15 | bit_5 = 0 |
---|

| 16 | bit_6 = 0 |
---|

| 17 | bit_7 = 0 |
---|

| 18 | |
---|

| 19 | class Lex (): |
---|

| 20 | LParen = 0 |
---|

| 21 | RParen = 0 |
---|

| 22 | |
---|

| 23 | class Matches() : |
---|

| 24 | closed = 0 |
---|

| 25 | instring = 0 |
---|

| 26 | error = 0 |
---|

| 27 | |
---|

| 28 | |
---|

| 29 | def Classify_bytes(basis_bits, lex): |
---|

| 30 | temp1 = (basis_bits.bit_0 | basis_bits.bit_1) |
---|

| 31 | temp2 = (basis_bits.bit_2 &~ basis_bits.bit_3) |
---|

| 32 | temp3 = (temp2 &~ temp1) |
---|

| 33 | temp4 = (basis_bits.bit_4 &~ basis_bits.bit_5) |
---|

| 34 | temp5 = (basis_bits.bit_6 | basis_bits.bit_7) |
---|

| 35 | temp6 = (temp4 &~ temp5) |
---|

| 36 | lex.LParen = (temp3 & temp6) |
---|

| 37 | temp7 = (basis_bits.bit_7 &~ basis_bits.bit_6) |
---|

| 38 | temp8 = (temp4 & temp7) |
---|

| 39 | lex.RParen = (temp3 & temp8) |
---|

| 40 | |
---|

| 41 | def Match_Parens(lex, matches): |
---|

| 42 | unmatched = lex.RParen |
---|

| 43 | pscan = 0 |
---|

| 44 | qscan = 0 |
---|

| 45 | pscan = pablo.ScanTo(pablo.Advance(lex.LParen), lex.LParen | lex.RParen) |
---|

| 46 | qscan = pablo.ScanTo(pablo.Advance(lex.RParen), lex.LParen | lex.RParen) |
---|

| 47 | matches.instring = pablo.ExclusiveSpan(lex.LParen, pscan) |
---|

| 48 | matches.closed = pscan & lex.RParen |
---|

| 49 | unclosed = pscan & lex.LParen | qscan & lex.RParen |
---|

| 50 | matches.error = pablo.atEOF(pscan) |
---|

| 51 | all_closed = matches.closed |
---|

| 52 | while unclosed: |
---|

| 53 | pscan = pablo.ScanTo(pablo.Advance(unclosed & lex.LParen), unclosed) |
---|

| 54 | qscan = pablo.ScanTo(pablo.Advance(unclosed & lex.RParen), unclosed) |
---|

| 55 | matches.instring = matches.instring | pablo.SpanUpTo(unclosed & lex.LParen, pscan) |
---|

| 56 | matches.closed = pscan & lex.RParen |
---|

| 57 | unclosed = pscan & lex.LParen | qscan & lex.RParen |
---|

| 58 | all_closed |= matches.closed |
---|

| 59 | matches.error |= pablo.atEOF(pscan) |
---|

| 60 | # |
---|

| 61 | # Any closing paren that was not actually used to close |
---|

| 62 | # an opener is in error. |
---|

| 63 | matches.error = matches.error | (lex.RParen &~ all_closed) |
---|

| 64 | |
---|

| 65 | |
---|

| 66 | def Main(basis_bits, lex, matches): |
---|

| 67 | Classify_bytes(basis_bits, lex) |
---|

| 68 | Match_Parens(lex, matches) |
---|

| 69 | |
---|

| 70 | |
---|