class Units token INT ERR SHIFT SPACE MULTIPLY DIVIDE EXPONENT REAL NAME DATE TIME ZONE options no_result_var rule unit_spec: /* empty unit_spec allowed */ { yyaccept; } | origin_exp { yyaccept; } | error { yyerrok } ; origin_exp: unit_exp | unit_exp SHIFT value_exp { val[0].shift(val[2]) } | unit_exp SHIFT timestamp { val[0].shift(val[2]) } ; unit_exp: power_exp | number_exp | unit_exp power_exp { val[0].mul(val[1]) } | unit_exp MULTIPLY power_exp { val[0].mul(val[2]) } | unit_exp DIVIDE power_exp { val[0].divide(val[2]) } | unit_exp MULTIPLY number_exp { val[0].mul(val[2]) } | unit_exp DIVIDE number_exp { val[0].divide(val[2]) } ; power_exp: NAME { NameNode.new(val[0]) } | power_exp number_exp { val[0].pow(val[1]) } | power_exp EXPONENT value_exp { val[0].pow(val[2]) } | '(' origin_exp ')' { val[1] } ; value_exp: number_exp | '(' value_exp ')' { val[1] } ; number_exp: INT { NumberNode.new(val[0]) } | REAL { NumberNode.new(val[0]) } ; timestamp: time_exp | '(' timestamp ')' { val[1] } ; time_exp: DATE { TimeNode.new(val[0], 0.0, 0) } | DATE TIME { TimeNode.new(val[0], val[1], 0) } | DATE TIME ZONE { TimeNode.new(val[0], val[1], val[2]) } ; end ---- header require 'date' ---- inner