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 | parens = lex.LParen | lex.RParen |
---|

43 | Lscan = pablo.AdvanceThenScanTo(lex.LParen, parens) |
---|

44 | Rscan = pablo.AdvanceThenScanTo(lex.RParen, parens) |
---|

45 | matches.instring = pablo.ExclusiveSpan(lex.LParen, Lscan) |
---|

46 | matches.closed = Lscan & lex.RParen |
---|

47 | matches.error = pablo.atEOF(Lscan) |
---|

48 | unclosed = Lscan & lex.LParen | Rscan & lex.RParen |
---|

49 | while unclosed: |
---|

50 | unclosedLParen = unclosed & lex.LParen |
---|

51 | unclosedRParen = unclosed & lex.RParen |
---|

52 | Lscan = pablo.AdvanceThenScanTo(unclosedLParen, unclosed) |
---|

53 | Rscan = pablo.AdvanceThenScanTo(unclosedRParen, unclosed) |
---|

54 | matches.instring |= pablo.SpanUpTo(unclosedLParen, Lscan) |
---|

55 | matches.closed |= Lscan & lex.RParen |
---|

56 | matches.error |= pablo.atEOF(Lscan) |
---|

57 | unclosed = Lscan & lex.LParen | Rscan & lex.RParen |
---|

58 | # |
---|

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

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

61 | matches.error = matches.error | (lex.RParen &~ matches.closed) |
---|

62 | |
---|

63 | |
---|

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

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

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

67 | |
---|

68 | |
---|