parse.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. def parse_expr(expr):
  2. t1 = expr.split('=')
  3. t2 = list(map(lambda t: t.strip().rsplit(maxsplit=1), t1[:-1]))
  4. lex = (t2[0][0] if t2 else expr).split()
  5. head, args = (lex[0], lex[1:]) if lex else (None, [])
  6. keys = map(lambda t: t[1].strip(), t2)
  7. vals = list(map((lambda t: t[0].strip()), t2[1:])) + [t1[-1].strip()]
  8. for idx, val in enumerate(vals):
  9. if val == '!':
  10. vals[idx] = ''
  11. kwargs = dict(zip(keys, vals))
  12. return head, args, kwargs
  13. def subst_consts(expr, consts):
  14. res = expr
  15. idx = 0
  16. while idx < len(res):
  17. idx = res.find('$', idx)
  18. if idx == -1:
  19. break
  20. if len(res) == idx + 1:
  21. raise ValueError('Missing constant name')
  22. if res[idx + 1] == '(':
  23. const_name_start = idx + 2
  24. const_name_end = res.find(')', idx + 2)
  25. const_token_end = const_name_end + 1
  26. else:
  27. const_name_start = idx + 1
  28. for const_name_end in range(idx + 1, len(res)):
  29. if res[const_name_end].isspace():
  30. break
  31. else:
  32. const_name_end = len(res)
  33. const_token_end = const_name_end
  34. if const_name_end == -1:
  35. raise ValueError('Unterminated constant name')
  36. if const_name_start == const_name_end:
  37. raise ValueError('Missing constant name')
  38. const_name = res[const_name_start:const_name_end]
  39. if const_name not in consts:
  40. raise ValueError('Undefined constant: ' + const_name)
  41. res = res[:idx] + consts[const_name] + res[const_token_end:]
  42. idx += 1
  43. return res
  44. def exps(stream):
  45. expr = ''
  46. expr_line_num = 1
  47. for line_num, line in enumerate(stream, 1):
  48. if not line:
  49. continue
  50. if line.lstrip().startswith('#'):
  51. continue
  52. if expr and not line[0].isspace():
  53. yield expr, expr_line_num
  54. expr = ''
  55. if not expr:
  56. expr_line_num = line_num
  57. expr += line
  58. if expr:
  59. yield expr, expr_line_num