For example:
The first rule can actually be omitted, since it only 'copies' the default behaviour (unparse each subtree in left-to-right order).
Const( i ) -> [: i ]; Plus( e1, e2 ) -> [: e1 " + " e2 ]; Times( e1, e2 ) -> [: e1 " * " e2 ]; Times( e1 = Plus(*, *), e2 ) -> [: "(" e1 ") * " e2 ]; Times( e1, e2 = Plus(*, *)) -> [: e1 " * (" e2 ")" ]; Times( e1 = Plus(*, *), e2 = Plus(*, *)) -> [: "(" e1 ") * (" e2 ")" ];
The unparse rules can be used in the following way:
views are used to group unparse rules;
%{ /* make the include files available in the generated code, a la yacc */ #include "unpk.h" /* unparse (view) defs (generated by kimwitu) */ #include "printer.h" /* printer fn declaration (generated by kimwitu) */ %} int main() { expr e = Times( Plus( Const( 1 ), Const( 1 )), Plus( Const( 1 ), Const( 1 )) ); unparse_expr( e, printer, base_view ); }
base_view
is the default view.
printer
is a user-defined function that takes care of
outputting strings.
A simple printer function can be:
%{ #include "unpk.h" /* unparse (view) defs (generated by kimwitu) */ %} void printer( char*s, uview v) { fprintf( stdout, "%s", s ); }