definition.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. package syntax
  2. import (
  3. "regexp"
  4. "strings"
  5. )
  6. type Regexp = *regexp.Regexp
  7. func r (pattern string) Regexp { return regexp.MustCompile(`^` + pattern) }
  8. const DefaultRootPartName = "root"
  9. const ReplRootPartName = "repl_root"
  10. const IdentifierPartName = "Name"
  11. var __EscapeMap = map[string] string {
  12. "_bar": "|",
  13. }
  14. var __IgnoreTokens = [...] string {
  15. "Comment",
  16. "Blank",
  17. "LF",
  18. }
  19. const LF = `\n`
  20. const Blanks = ` \t\r `
  21. const Symbols = `\{\}\[\]\(\)\.,:;\&\|\\'"` + "`"
  22. const idEverywhereDisallow = (Symbols + Blanks + LF)
  23. const idHeadDisallow = (`0-9` + idEverywhereDisallow)
  24. const IdentifierRegexp = `[^`+idHeadDisallow +`][^`+idEverywhereDisallow+`]*`
  25. var __Tokens = [...] Token {
  26. // pragma and comment
  27. Token { Name: "Doc", Pattern: r(`///[^`+LF+`]*`) },
  28. Token { Name: "Comment", Pattern: r(`//[^`+LF+`]*`) },
  29. Token { Name: "Comment", Pattern: r(`/\*([^\*/]|\*[^/]|[^\*]/)*\*/`) },
  30. // blank
  31. Token { Name: "Blank", Pattern: r(`[`+Blanks+`]+`) },
  32. Token { Name: "LF", Pattern: r(`[`+LF+`]+`) },
  33. // literals
  34. Token { Name: "Text", Pattern: r(`'[^']*'`) },
  35. Token { Name: "Text", Pattern: r(`"[^"]*"`) },
  36. Token { Name: "Int", Pattern: r(`\-?0[xX][0-9A-Fa-f]+`) },
  37. Token { Name: "Int", Pattern: r(`\-?0[oO][0-7]+`) },
  38. Token { Name: "Int", Pattern: r(`\-?0[bB][01]+`) },
  39. Token { Name: "Float", Pattern: r(`\-?\d+(\.\d+)?[Ee][\+\-]?\d+`) },
  40. Token { Name: "Float", Pattern: r(`\-?\d+\.\d+`) },
  41. Token { Name: "Int", Pattern: r(`\-?\d+`) },
  42. Token { Name: "Char", Pattern: r("`.`") },
  43. Token { Name: "Char", Pattern: r(`\\u[0-9A-Fa-f]+`) },
  44. Token { Name: "Char", Pattern: r(`\\[a-z]`) },
  45. // symbols
  46. Token { Name: "(", Pattern: r(`\(`) },
  47. Token { Name: ")", Pattern: r(`\)`) },
  48. Token { Name: "[", Pattern: r(`\[`) },
  49. Token { Name: "]", Pattern: r(`\]`) },
  50. Token { Name: "{", Pattern: r(`\{`) },
  51. Token { Name: "}", Pattern: r(`\}`) },
  52. Token { Name: "...", Pattern: r(`\.\.\.`) },
  53. Token { Name: "..", Pattern: r(`\.\.`) },
  54. Token { Name: ".", Pattern: r(`\.`) },
  55. Token { Name: ",", Pattern: r(`\,`) },
  56. Token { Name: "::", Pattern: r(`\:\:`) },
  57. Token { Name: ":=", Pattern: r(`\:\=`) },
  58. Token { Name: ":", Pattern: r(`\:`) },
  59. Token { Name: ";", Pattern: r(`\;`) },
  60. Token { Name: "&", Pattern: r(`\&`) },
  61. Token { Name: "|", Pattern: r(`\|`) },
  62. Token { Name: `\`, Pattern: r(`\\`) },
  63. // keywords
  64. Token { Name: "If", Pattern: r(`if`), Keyword: true },
  65. Token { Name: "Else", Pattern: r(`else`), Keyword: true },
  66. Token { Name: "When", Pattern: r(`when`), Keyword: true },
  67. Token { Name: "Let", Pattern: r(`let`), Keyword: true },
  68. Token { Name: "New", Pattern: r(`new`), Keyword: true },
  69. // identifier
  70. Token { Name: "Name", Pattern: r(IdentifierRegexp) },
  71. }
  72. func GetTokens() ([] Token) { return __Tokens[:] }
  73. func GetIgnoreTokens() ([] string) { return __IgnoreTokens[:] }
  74. func GetIdentifierRegexp() *regexp.Regexp {
  75. return regexp.MustCompile(IdentifierRegexp)
  76. }
  77. var __ConditionalKeywords = [...] string {
  78. "@run",
  79. "@public", "@entry", "@asset", "@type", "@operator",
  80. "@method", "@const", "@message",
  81. "@native", "@interface", "@record", "@union",
  82. "@service", "@data", "@open", "@default",
  83. "@infix", "@variadic",
  84. "@singular", "@plural",
  85. "@=>", "@rec", "@end",
  86. }
  87. func GetKeywordList() ([] string) {
  88. var list = make([] string, 0)
  89. for _, v := range __ConditionalKeywords {
  90. var kw = strings.TrimPrefix(v, "@")
  91. list = append(list, kw)
  92. }
  93. for _, t := range __Tokens {
  94. if t.Keyword {
  95. var kw = strings.TrimPrefix(t.Pattern.String(), "^")
  96. list = append(list, kw)
  97. }
  98. }
  99. return list
  100. }
  101. var __SyntaxDefinition = [...] string {
  102. "root = stmt*",
  103. "stmt = decl_entry | decl_type " +
  104. "| decl_op | decl_method | decl_const | decl_msg",
  105. "repl_root = repl_assign | repl_run | repl_eval",
  106. "repl_assign = name := expr!",
  107. "repl_run = : @run expr!",
  108. "repl_eval = expr!",
  109. "decl_entry = @entry block!",
  110. "decl_type = docs @type name! type_params impl type_def!",
  111. "type_params? = [ name*, ]!",
  112. "name = Name",
  113. "docs? = doc+",
  114. "doc = Doc",
  115. "impl? = ( ref_base*, )!",
  116. "ref_base = module_prefix name",
  117. "module_prefix? = name :: ",
  118. "type_def = native_type_def | interface | record | union",
  119. "native_type_def = @native",
  120. "interface = service @interface {! method*, }!",
  121. "service? = @service",
  122. "method = docs name type!",
  123. "record = open data @record record_def!",
  124. "open? = @open",
  125. "data? = @data",
  126. "record_def = { field*, }!",
  127. "field = docs name type! field_default",
  128. "field_default? = @default (! expr! )!",
  129. "union = data @union {! union_item*_bar }!",
  130. "union_item = union_item_def_const | union_item_use_type",
  131. "union_item_def_const = @const union_const_def+,! ",
  132. "union_const_def = docs name",
  133. "union_item_use_type = type",
  134. "decl_op = docs public @operator infix variadic name! sig! body!",
  135. "public? = @public",
  136. "infix? = @infix",
  137. "variadic? = @variadic",
  138. "sig = type_params inputs! implicit output!",
  139. "inputs = record_def",
  140. "implicit? = inputs",
  141. "output = type",
  142. "body = native_body | block!",
  143. "native_body = @native (! text! )!",
  144. "decl_method = docs public @method receiver! .! name! type! body!",
  145. "receiver = name",
  146. "decl_const = docs public @const name! type! body!",
  147. "decl_msg = docs public @message msg_lang! name! inputs! msg_expr!",
  148. "msg_lang = name",
  149. "msg_expr = msg_expr_sp | msg_expr_plain",
  150. "msg_expr_sp = msg_singular msg_plural!",
  151. "msg_singular = @singular (! string! )!",
  152. "msg_plural = @plural (! string! )!",
  153. "msg_expr_plain = string",
  154. "type = ref",
  155. "ref = ref_base type_args",
  156. "type_args? = [ type*, ]!",
  157. "expr = cast* term pipe*",
  158. "cast = ( [ type! ]! )!",
  159. "pipe = pipe_call | pipe_ufcs | pipe_cast | pipe_get | pipe_interior",
  160. "pipe_call = call_ordered | call_unordered",
  161. "call_ordered = ( expr*, )!",
  162. "call_unordered = { arg_mapping*, }!",
  163. "arg_mapping = name arg_mapping_to",
  164. "arg_mapping_to? = : expr!",
  165. "pipe_ufcs = _bar ref! pipe_call!",
  166. "pipe_cast = . cast",
  167. "pipe_get = . name",
  168. "pipe_interior = . ( ref_base! )!",
  169. "term = infix_term | lambda | if | when | block | ref_term " +
  170. "| char | int | float | string ",
  171. "infix_term = ( infix_left operator! infix_right! )!",
  172. "infix_left = expr",
  173. "operator = ref",
  174. "infix_right = expr",
  175. "lambda = { & input_names rec @=>! expr! }!",
  176. "input_names? = ( name+,! )!",
  177. "rec? = @rec (! name! )!",
  178. "if = If (! cond! )! if_yes elif* Else! if_no",
  179. "cond = expr",
  180. "if_yes = block!",
  181. "if_no = block!",
  182. "elif = Else If (! cond! )! block!",
  183. "when = When (! expr+,! )! {! branch+,! }!",
  184. "branch = branch_pattern+_bar input_names @=>! expr!",
  185. "branch_pattern = Else | pattern",
  186. "pattern = pattern_single | pattern_multiple",
  187. "pattern_single = name",
  188. "pattern_multiple = ( name+,! )!",
  189. "block = { binding* expr! }!",
  190. "binding = binding_plain | binding_cps",
  191. "binding_plain = Let pattern! :=! expr! ,!",
  192. "binding_cps = \\ ref! cps_binding expr! ,!",
  193. "cps_binding? = pattern := ",
  194. "ref_term = new ref",
  195. "new? = New",
  196. "char = Char",
  197. "int = Int",
  198. "float = Float",
  199. "string = text string_part* ",
  200. "text = Text",
  201. "string_part = .. string_part_content!",
  202. "string_part_content = text | char | block",
  203. }