--- alias: conversions backends: - ocaml # - java # - llvm # - haskell tests: - selector: ".foo-to-string" - selector: ".string-to-bar" - selector: ".random-string-to-bar" - selector: ".foo-to-bar" --- You can convert between tokens of one sort via `String`s by defining functions that are implemented by builtin hooks. ```k module CONVERSIONS imports STRING syntax Foo ::= "foo" [token] syntax Bar ::= "bar" [token] ``` The hook `STRING.token2string` allows conversion of any token to a string: ```k syntax String ::= FooToString(Foo) [function, functional, hook(STRING.token2string)] ``` ``` {.foo-to-string .input} FooToString(foo) ``` ``` {.foo-to-string .expected} "foo" ``` Similarly, the hook `STRING.string2Token` implements the inverse: ```k syntax Bar ::= StringToBar(String) [function, functional, hook(STRING.string2token)] ``` ``` {.string-to-bar .input} StringToBar("bar") ``` ``` {.string-to-bar .expected} bar ``` WARNING: This sort of conversion does *NOT* do any sort of parsing or validation. Thus, we can create arbitary tokens of any sort: ``` {.random-string-to-bar .input} StringToBar("The sun rises in the west.") ``` ``` {.random-string-to-bar .expected} The sun rises in the west. ``` Composing these two functions lets us convert from `Foo` to `Bar` ```k syntax Bar ::= FooToBar(Foo) [function] rule FooToBar(F) => StringToBar(FooToString(F)) ``` ``` {.foo-to-bar .input} FooToBar(foo) ``` ``` {.foo-to-bar .expected} foo ``` ```k endmodule ```