>b's YML 2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
5.1 KiB

  1. # YML 2.7.0 language definition
  2. # written by VB.
  3. import re
  4. from .pyPEG import keyword, _and, _not
  5. # pyPEG:
  6. #
  7. # basestring: terminal symbol (characters)
  8. # keyword: terminal symbol (keyword)
  9. # matchobj: terminal symbols (regex, use for scanning symbols)
  10. # function: named non-terminal symbol, recursive definition
  11. # if you don't want naming in output, precede name with an underscore
  12. # tuple: production sequence
  13. # integer: count in production sequence:
  14. # 0: following element is optional
  15. # -1: following element can be omitted or repeated endless
  16. # -2: following element is required and can be repeated endless
  17. # list: options, choose one of them
  18. # _not: next element in production sequence is matched only if this would not
  19. # _and: next element in production sequence is matched only if this would, too
  20. newSyntax = True
  21. def oldSyntax():
  22. global newSyntax
  23. newSyntax = False
  24. def _if(cond, val):
  25. if cond:
  26. return val
  27. else:
  28. return ()
  29. def listing(x): return x, -1, (",", x)
  30. r = re.compile
  31. comment = [r(r"//.*"), r(r"/\*.*?\*/", re.S)]
  32. _symbol = r"(?=\D)\w(\w|:)*"
  33. symbol = r(_symbol, re.U)
  34. pointer = r(r"\*" + _symbol, re.U)
  35. ppointer = r(r"\*\*" + _symbol, re.U)
  36. macro = r(r"\%" + _symbol, re.U)
  37. reference = r(r"\&" + _symbol, re.U)
  38. NameStartChar = r''':|[A-Z]|_|[a-z]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|[\u00F8-\u02FF]|[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]'''
  39. NameChar = NameStartChar + r'''|-|\.|[0-9]|\u00B7|[\u0300-\u036F]|[\u203F-\u2040]'''
  40. _xmlSymbol = "(" + NameStartChar + ")(" + NameChar + ")*"
  41. xmlSymbol = r(_xmlSymbol)
  42. aliasSymbol = r(r"-|(" + _xmlSymbol + r")")
  43. literal = [r(r'""".*?"""', re.S), r(r"'''.*?'''", re.S), r(r"""0x[a-f0-9]+|-?\d+\.\d*|-?\.\d+|-?\d+|".*?"|'.*?'""")]
  44. filename = [("'", r(r"[^']*"), "'"), ('"', r(r'[^"]*'), '"'), r(r"[^\s;]+")]
  45. ws = r(r"\s+", re.U)
  46. def pyExp(): return "!", r(r"(!=|\\!|[^!])+"), "!"
  47. value = [literal, pyExp]
  48. def tagQuote(): return r(r"\].*|\<.*?\>")
  49. def lineQuote(): return r(r"\|.*")
  50. def quote(): return [r(r"\d*>.*"), (literal, 0, [";", "."])]
  51. def parm(): return [([xmlSymbol, pyExp, pointer, macro], "=", [value, pointer, symbol]), value, pointer]
  52. def parm_eq(): return [xmlSymbol, pyExp, pointer, macro], "=", [value, pointer, symbol]
  53. parm_eq.__name__ = "parm"
  54. _func = [symbol, ppointer, pointer, reference], _if(newSyntax, (-1, ("[", listing(parm), "]"))), 0, ("(", listing(parm), ")"), 0, listing(parm), -1, parm_eq
  55. def pythonCall(): return keyword("python"), _func, [";", "."]
  56. def declParm(): return [pointer, macro, xmlSymbol], 0, ("=", [literal, symbol])
  57. def alias(): return keyword("alias"), aliasSymbol
  58. def descend(): return r(r"[+@*]" + _symbol, re.U)
  59. def base(): return keyword("is"), symbol
  60. def shape(): return symbol
  61. def decl(): return symbol, 0, base, 0, ("<", listing(shape), ">"), -1, descend, _if(newSyntax, (-1, ("[", 0, listing(declParm), "]"))), 0, ("(", 0, listing(declParm), ")"), 0, alias, 0, content
  62. def python(): return [r(r"!!.*?!!", re.S), r(r"!.*")]
  63. def operator(): return 0, keyword("define"), keyword("operator"), literal, keyword("as"), r(r".*")
  64. def constant(): return 0, keyword("define"), [pointer, symbol], "=", literal, 0, [";", "."]
  65. def in_ns(): return keyword("in"), xmlSymbol, [_decl, ("{", -2, _decl, "}")]
  66. _decl = keyword("decl"), listing(decl), [";", "."]
  67. def textsection(): return r(r'(\|\|(\>*)(.*?)\|\|(\>*))\s*$', re.S | re.M)
  68. def textsectionu(): return r(r'(\>\>.*?\>\>)', re.S)
  69. def include(): return keyword("include"), 0, reverse, 0, [ktext, kxml], 0, kpointer, filename, 0, [";", "."]
  70. def func(): return _func, 0, content
  71. def funclist(): return listing(func)
  72. _cmd = funclist, 0, [";", "."]
  73. _inner = [include, textsection, textsectionu, pythonCall, _cmd, quote, lineQuote, tagQuote, pyExp]
  74. _cc = "{", -1, _inner, "}"
  75. def content_plain(): return [ (_l, 0, _p, 0, _b, 0, _cc), (_p, 0, _b, 0, _cc), (_b, 0, _cc), _cc ]
  76. content_plain.__name__ = "content"
  77. def func_plain(): return _func, 0, content_plain
  78. func_plain.__name__ = "func"
  79. def flist_plain(): return -2, func_plain
  80. flist_plain.__name__ = "funclist"
  81. def xbase(): return flist_plain
  82. def generic(): return flist_plain
  83. def subscript(): return flist_plain
  84. def parentheses(): return "(", 0, funclist, ")"
  85. def fparm(): return flist_plain
  86. _l = _if(newSyntax, ("<", listing(generic), ">"))
  87. _p = _if(not newSyntax, parentheses), _if(newSyntax, ("(", 0, listing(fparm), ")"))
  88. _b = (":", listing(xbase))
  89. _c = [_inner, _cc]
  90. def content(): return [ (_l, 0, _p, 0, _b, 0, _c), (_p, 0, _b, 0, _c), (_b, 0, _c), _c ]
  91. def reverse(): return keyword("reverse")
  92. def ktext(): return keyword("text")
  93. def kxml(): return keyword("xml")
  94. def kpointer(): return keyword("from")
  95. def ymlCStyle(): return -1, [_decl, in_ns, include, python, operator, constant, tagQuote, lineQuote, quote, _cmd]