transformer.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. package transformer
  2. import "fmt"
  3. import "reflect"
  4. import "strings"
  5. import "kumachan/parser"
  6. import "kumachan/parser/ast"
  7. import "kumachan/parser/syntax"
  8. import . "kumachan/transformer/node"
  9. /**
  10. * AST Transformer
  11. *
  12. * This package is responsible for transforming the AST output
  13. * of the `parser` package into typed and well-structured form
  14. * according to the declarative configurations defined in
  15. * the `node` subpackage.
  16. */
  17. type Tree = *ast.Tree
  18. type Pointer = int
  19. type Context = map[string] interface{}
  20. type Transformer = func(Tree, Pointer) reflect.Value
  21. func Transform (tree Tree) Module {
  22. var next_id uint64 = 0
  23. var generate_id = func() uint64 {
  24. var id = next_id
  25. next_id += 1
  26. return id
  27. }
  28. var dive func(Tree, Pointer, []syntax.Id) (Pointer, bool)
  29. dive = func (tree Tree, ptr Pointer, path []syntax.Id) (Pointer, bool) {
  30. if len(path) == 0 {
  31. return ptr, true
  32. }
  33. var parser_node = &tree.Nodes[ptr]
  34. var L = parser_node.Length
  35. for i := 0; i < L; i += 1 {
  36. var child_ptr = parser_node.Children[i]
  37. var child = &tree.Nodes[child_ptr]
  38. if child.Part.Id == path[0] {
  39. if child.Part.PartType == syntax.Recursive && child.Length == 0 {
  40. return -1, false
  41. } else {
  42. return dive(tree, child_ptr, path[1:])
  43. }
  44. }
  45. }
  46. return -1, false
  47. }
  48. var transform Transformer
  49. transform = func (tree Tree, ptr Pointer) reflect.Value {
  50. var parser_node = &tree.Nodes[ptr]
  51. var info = GetNodeInfoById(parser_node.Part.Id)
  52. var node = reflect.New(info.Type)
  53. var meta = node.Elem().FieldByName("Node").Addr().Interface().(*Node)
  54. meta.Span = parser_node.Span
  55. meta.Point = tree.Info[meta.Span.Start]
  56. meta.UID = generate_id()
  57. var transform_dived = func (child_info *NodeChildInfo, f Transformer) {
  58. var field_index = child_info.FieldIndex
  59. var field = info.Type.Field(field_index)
  60. var field_value = node.Elem().Field(field_index)
  61. var path = child_info.DivePath
  62. var dived_ptr, exists = dive(tree, ptr, path)
  63. if exists {
  64. field_value.Set(f(tree, dived_ptr))
  65. } else {
  66. if child_info.Fallback != -1 {
  67. var fallback_id = child_info.Fallback
  68. var L = parser_node.Length
  69. for i := 0; i < L; i += 1 {
  70. var child_ptr = parser_node.Children[i]
  71. var child_parser_node = &tree.Nodes[child_ptr]
  72. if child_parser_node.Part.Id == fallback_id {
  73. var value = transform(tree, child_ptr)
  74. if field.Type.Kind() == reflect.Slice {
  75. var t = reflect.MakeSlice(field.Type, 1, 1)
  76. t.Index(0).Set(value)
  77. field_value.Set(t)
  78. } else {
  79. field_value.Set(value)
  80. }
  81. break
  82. }
  83. }
  84. } else if child_info.Optional {
  85. if field.Type.Kind() == reflect.Slice {
  86. var empty_slice = reflect.MakeSlice(field.Type, 0, 0)
  87. field_value.Set(empty_slice)
  88. } else if field.Type.Kind() == reflect.Bool {
  89. field_value.Set(reflect.ValueOf(false))
  90. }
  91. } else {
  92. var path_strlist = make([]string, len(path))
  93. for i, segment := range path {
  94. path_strlist[i] = syntax.Id2Name[segment]
  95. }
  96. var path_str = strings.Join(path_strlist, ".")
  97. panic(fmt.Sprintf (
  98. "transform(): path `%v` cannot be found in `%v`",
  99. path_str, syntax.Id2Name[parser_node.Part.Id],
  100. ))
  101. }
  102. }
  103. }
  104. if info.First != -1 {
  105. if parser_node.Length > 0 {
  106. var field_value = node.Elem().Field(info.First)
  107. field_value.Set(transform(tree, parser_node.Children[0]))
  108. } else {
  109. panic(fmt.Sprintf (
  110. "transform(): cannot get first child of empty node `%v`",
  111. syntax.Id2Name[parser_node.Part.Id],
  112. ))
  113. }
  114. }
  115. if info.Last != -1 {
  116. var L = parser_node.Length
  117. if L > 0 {
  118. var field_value = node.Elem().Field(info.Last)
  119. field_value.Set(transform(tree, parser_node.Children[L-1]))
  120. } else {
  121. panic(fmt.Sprintf (
  122. "transform(): cannot get last child of empty node `%v`",
  123. syntax.Id2Name[parser_node.Part.Id],
  124. ))
  125. }
  126. }
  127. for _, child_info := range info.Children {
  128. transform_dived(&child_info, transform)
  129. }
  130. for _, child_info := range info.Strings {
  131. transform_dived (
  132. &child_info,
  133. func (tree Tree, dived_ptr Pointer) reflect.Value {
  134. var dived_node = &tree.Nodes[dived_ptr]
  135. if dived_node.Part.PartType == syntax.MatchToken {
  136. var content = GetTokenContent(tree, dived_ptr)
  137. var L = len(content)
  138. if L >= 2 {
  139. if content[0] == '\'' && content[L-1] == '\'' {
  140. content = content[1: L-1]
  141. } else if content[0] == '"' && content[L-1] == '"' {
  142. content = content[1: L-1]
  143. }
  144. }
  145. return reflect.ValueOf(content)
  146. } else {
  147. panic(fmt.Sprintf (
  148. "cannot get token content of non-token part %v",
  149. syntax.Id2Name[dived_node.Part.Id],
  150. ))
  151. }
  152. },
  153. )
  154. }
  155. for _, child_info := range info.Options {
  156. transform_dived (
  157. &child_info,
  158. func (tree Tree, _ Pointer) reflect.Value {
  159. return reflect.ValueOf(true)
  160. },
  161. )
  162. }
  163. for _, list_info := range info.Lists {
  164. transform_dived (
  165. &list_info.NodeChildInfo,
  166. func (tree Tree, dived_ptr Pointer) reflect.Value {
  167. var item_id = list_info.ItemId
  168. var tail_id = list_info.TailId
  169. var item_ptrs = FlatSubTree(tree, dived_ptr, item_id, tail_id)
  170. var field_index = list_info.FieldIndex
  171. var field = info.Type.Field(field_index)
  172. if field.Type.Kind() != reflect.Slice {
  173. panic("cannot transform list to non-slice field")
  174. }
  175. var N = len(item_ptrs)
  176. var slice = reflect.MakeSlice(field.Type, N, N)
  177. for i, item_ptr := range item_ptrs {
  178. slice.Index(i).Set(transform(tree, item_ptr))
  179. }
  180. return slice
  181. },
  182. )
  183. }
  184. return node.Elem()
  185. }
  186. return transform(tree, 0).Interface().(Module)
  187. }
  188. func FlatSubTree (
  189. tree Tree, ptr Pointer,
  190. extract syntax.Id, next syntax.Id,
  191. ) []Pointer {
  192. var sequence = make([]int, 0)
  193. for NotEmpty(tree, ptr) {
  194. var extract_ptr = -1
  195. var next_ptr = -1
  196. var node = &tree.Nodes[ptr]
  197. var L = node.Length
  198. for i := 0; i < L; i += 1 {
  199. var child_ptr = node.Children[i]
  200. var child = &tree.Nodes[child_ptr]
  201. if child.Part.Id == extract {
  202. extract_ptr = child_ptr
  203. }
  204. if child.Part.Id == next {
  205. next_ptr = child_ptr
  206. }
  207. }
  208. if extract_ptr == -1 {
  209. panic("cannot extract part " + syntax.Id2Name[extract])
  210. }
  211. sequence = append(sequence, extract_ptr)
  212. if next_ptr == -1 {
  213. panic("next part " + syntax.Id2Name[next] + " not found")
  214. }
  215. ptr = next_ptr
  216. }
  217. return sequence
  218. }
  219. func GetTokenContent (tree Tree, ptr int) []rune {
  220. var node = &tree.Nodes[ptr]
  221. return tree.Tokens[node.Pos + node.Amount - 1].Content
  222. }
  223. func NotEmpty (tree Tree, ptr Pointer) bool {
  224. return tree.Nodes[ptr].Length > 0
  225. }
  226. func Empty (tree Tree, ptr Pointer) bool {
  227. return !NotEmpty(tree, ptr)
  228. }
  229. func PrintNodeRecursively (
  230. buf *strings.Builder,
  231. node reflect.Value, name string, depth int, is_last []bool,
  232. ) {
  233. var T = node.Type()
  234. if T.Kind() == reflect.Interface {
  235. PrintNodeRecursively(buf, node.Elem(), name, depth, is_last)
  236. return
  237. }
  238. const INC = 2
  239. const SPACE = " "
  240. parser.Repeat(depth+1, func (i int) {
  241. if depth > 0 && i < depth {
  242. if is_last[i] {
  243. parser.Fill(buf, INC, "", SPACE)
  244. } else {
  245. parser.Fill(buf, INC, "│", SPACE)
  246. }
  247. } else {
  248. if is_last[depth] {
  249. parser.Fill(buf, INC, "└", "─")
  250. } else {
  251. parser.Fill(buf, INC, "├", "─")
  252. }
  253. }
  254. })
  255. var RuneList = reflect.TypeOf([]rune{})
  256. if T.Kind() == reflect.Struct && T.NumField() > 0 {
  257. buf.WriteString("┬─")
  258. } else if T.Kind() == reflect.Slice && !(T.AssignableTo(RuneList)) {
  259. if node.Len() > 0 {
  260. buf.WriteString("┬─")
  261. } else {
  262. buf.WriteString("──")
  263. }
  264. } else {
  265. buf.WriteString("──")
  266. }
  267. fmt.Fprintf(buf, "\033[1m\033[%vm", parser.GetANSIColor(depth))
  268. fmt.Fprintf(buf, "[%v] %v", name, T.String())
  269. fmt.Fprintf(buf, "\033[0m")
  270. fmt.Fprintf(buf, "\033[%vm", parser.GetANSIColor(depth))
  271. buf.WriteRune(' ')
  272. var newline = func () {
  273. fmt.Fprintf(buf, "\033[0m\n")
  274. }
  275. switch T.Kind() {
  276. case reflect.Bool:
  277. fmt.Fprintf(buf, "(%v)", node.Interface().(bool))
  278. newline()
  279. case reflect.Slice:
  280. if T.AssignableTo(reflect.TypeOf([]rune{})) {
  281. fmt.Fprintf(buf, "'%v'", string(node.Interface().([]rune)))
  282. newline()
  283. } else {
  284. var L = node.Len()
  285. if L == 0 {
  286. buf.WriteString("(empty)")
  287. }
  288. fmt.Fprintf(buf, "\033[0m")
  289. buf.WriteRune('\n')
  290. for i := 0; i < L; i += 1 {
  291. var child = node.Index(i)
  292. is_last = append(is_last, i == L-1)
  293. PrintNodeRecursively (
  294. buf, child, fmt.Sprintf("%d", i),
  295. (depth + 1), is_last,
  296. )
  297. is_last = is_last[:len(is_last)-1]
  298. }
  299. }
  300. case reflect.Struct:
  301. var L = node.NumField()
  302. newline()
  303. for i := 0; i < L; i += 1 {
  304. var field = node.Field(i)
  305. var field_info = T.Field(i)
  306. if field_info.Name == "Node" {
  307. continue
  308. }
  309. if field_info.Type.Kind() == reflect.Interface && field.IsNil() {
  310. continue
  311. }
  312. is_last = append(is_last, i == L-1)
  313. PrintNodeRecursively (
  314. buf, field, field_info.Name,
  315. (depth + 1), is_last,
  316. )
  317. is_last = is_last[:len(is_last)-1]
  318. }
  319. default:
  320. newline()
  321. }
  322. }
  323. func PrintNode (node reflect.Value) {
  324. var buf strings.Builder
  325. var is_last = make([]bool, 0, 1000)
  326. is_last = append(is_last, true)
  327. PrintNodeRecursively(&buf, node, "Module", 0, is_last)
  328. fmt.Println(buf.String())
  329. }
  330. /**
  331. * The following operator processing techniques are deprecated,
  332. * since prefix expressions dominate the new syntax.
  333. */
  334. type Operator struct {
  335. Match string
  336. Priority int
  337. Assoc LeftRight
  338. Lazy bool
  339. }
  340. type LeftRight int
  341. const (
  342. Left LeftRight = iota
  343. Right
  344. )
  345. func ReduceExpression(operators []Operator) [][3]int {
  346. /**
  347. * Reduce Expression using the Shunting Yard Algorithm
  348. *
  349. * N = the number of operators
  350. * input = [1, -1, 2, -2, ..., (N-1), -(N-1), N, 0]
  351. * (positive: operand, negative: operator, 0: pusher)
  352. * output = index stack of operands (pos: operand, neg: reduced_operand)
  353. * temp = index stack of operators
  354. * reduced = [[operand1, operand2, operator], ...]
  355. */
  356. var pusher = Operator { Priority: -1, Assoc: Left }
  357. var N = len(operators)
  358. var input = make([]int, 0, 2*N+1+1)
  359. var output = make([]int, 0, N+1)
  360. var temp = make([]int, 0, N+1)
  361. var reduced = make([][3]int, 0, N)
  362. /* Initialize the Input */
  363. for i := 0; i <= N; i++ {
  364. // add operand index (incremented by 1)
  365. input = append(input, i+1)
  366. if i < N {
  367. // add operator index (incremented by 1 and negated)
  368. input = append(input, -(i+1))
  369. }
  370. }
  371. // add pusher
  372. input = append(input, 0)
  373. /* Read the Input */
  374. for _, I := range input {
  375. if I > 0 {
  376. // positive index => operand, push it to output stack
  377. var operand_index = I-1
  378. output = append(output, operand_index)
  379. } else {
  380. // non-positive index => operator
  381. // this index will be -1 if I == 0 (operator is pusher)
  382. var operator_index = -I-1
  383. // read the operator stack
  384. for len(temp) > 0 {
  385. // there is an operator on the operator stack
  386. var this *Operator
  387. if operator_index >= 0 {
  388. // index is non-negative => normal operator
  389. this = &operators[operator_index]
  390. } else {
  391. // index is -1 => pusher
  392. this = &pusher
  393. }
  394. // get the dumped operator on the top of the stack
  395. var dumped_op_index = temp[len(temp)-1]
  396. var dumped = operators[dumped_op_index]
  397. // determine if we should reduce output by the dumped operator
  398. var should_reduce bool
  399. if (this.Assoc == Left) {
  400. should_reduce = dumped.Priority >= this.Priority
  401. } else {
  402. should_reduce = dumped.Priority > this.Priority
  403. }
  404. if should_reduce {
  405. // reduce the output stack
  406. temp = temp[0:len(temp)-1]
  407. var operand1 = output[len(output)-2]
  408. var operand2 = output[len(output)-1]
  409. output = output[0:len(output)-2]
  410. reduced = append(reduced, [3]int {
  411. operand1, operand2, dumped_op_index,
  412. })
  413. var reduced_index = len(reduced)-1
  414. output = append(output, -(reduced_index+1))
  415. } else {
  416. // important: if we should not reduce, exit the loop
  417. break
  418. }
  419. }
  420. // push the current operator to the operator stack
  421. temp = append(temp, operator_index)
  422. }
  423. }
  424. /* Return the Result */
  425. return reduced
  426. }