Advertisement
Tyler_Elric

Untitled

Mar 18th, 2013
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.92 KB | None | 0 0
  1. #import re
  2.  
  3. def check_chunk_bounds(chunks,m):
  4.     #try:
  5.     if chunks[0][0] in m.keys():
  6.         end,close,escape = 0,m[chunks[0][0]],"\\"
  7.         trim_chars = "".join(set(close + chunks[0][0]))
  8.         while (chunks[end][-1]!=close and chunks[end][-2]!=escape):end+=1
  9.         end=end+1 if end+1<len(chunks) else None
  10.         chunk=("".join(chunks[:end])).strip(trim_chars)
  11.         print(chunk)
  12.         return chunk,(chunks[end:] if end else [])
  13.     #except IndexError as e:print(e)
  14.     #finally:return None,chunks
  15.     return None,chunks
  16.  
  17. class ChunkBase(object):
  18.     prefix='@'
  19.     def __init__(self,v):self.val = v
  20.     def __str__(self):return self.prefix+self.val
  21.  
  22. class RegexChunk(ChunkBase):
  23.     prefix='regex:'
  24.  
  25. class OtherChunk(ChunkBase):
  26.     prefix='value:'
  27.  
  28. class Rule:
  29.     def __init__(self,spec):
  30.         chunks,spec=spec.split(),[]
  31.         types={
  32.             RegexChunk:{'"':'"',"'":"'"},
  33.             OtherChunk:{'[':']','{':'}','(':')','<':'>'}
  34.         }
  35.         while len(chunks)>0:
  36.             progressed=False
  37.             for chunk_type,chunk_closures in types.items():
  38.                 chunk,chunks = check_chunk_bounds(chunks,chunk_closures)
  39.                 if chunk is not None:
  40.                     spec.append(chunk_type(chunk))
  41.                     progressed=True
  42.                     break
  43.             if not progressed:
  44.                 spec.append(ChunkBase(chunks[0]))
  45.                 chunks=chunks[1:]
  46.         self.chunks=spec
  47.  
  48. class Grammar:
  49.     def __init__(self,ospec):
  50.         #Ignore comments.
  51.         rule_specs="\n".join([rs[:rs.find("//")].strip() for rs in ospec.split("\n")])
  52.         rule_specs=[rs.strip() for rs in rule_specs.split(";") if len(rs.strip())>0]
  53.         rules={}
  54.         for spec in rule_specs:
  55.             ind = spec.find(":")
  56.             if ind<0:
  57.                 raise LogicError("Missing ':' identifier.")
  58.             name = spec[:ind].strip()
  59.             if any([(c in " \n\t") for c in name]):
  60.                 raise LogicError("Grammar Rule can't have white-space in its name.")
  61.             rule = spec[ind+1:].strip()
  62.             rules[name]=Rule(rule)
  63.         self.rules=rules
  64.  
  65. g=Grammar(r"""
  66. number: 'AHA\' HAH';// CAWMENTS. CAWMENTS ERRYWHER.
  67. KA_DURP: DZ:RLKJAF;//wuthaha
  68. """)
  69.  
  70. for name,rule in g.rules.items():
  71.     print(name,":",*[chunk for chunk in rule.chunks])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement