1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
local type = type
local function mult(a, b)
if a == 1 then return b end
if b == 1 then return a end
return {operator= '*', a, b}
end
local function infix_action(sym, a, b)
if sym == '*' then
return mult(a, b)
else
return {operator= sym, a, b}
end
end
local function prefix_action(sym, a)
return {operator= sym, a}
end
local function enum_action(id)
return "%" .. id
end
local function func_eval_action(func_name, arg_expr)
return {func = func_name, arg = arg_expr}
end
local function ident_action(id) return id end
local function literal_action(name)
return {literal= name}
end
-- return true iff expr is a variable (with enums or not).
-- if it is a variable returns, in addition, the var_name and the enumeration flag
local function is_variable(expr)
if type(expr) == 'string' then
local esc_name = string.match(expr, "^%%(.*)")
return true, esc_name or expr, (esc_name ~= nil)
else
return false
end
end
local function is_number(expr)
return type(expr) == 'number'
end
return {
infix = infix_action,
ident = ident_action,
literal = literal_action,
prefix = prefix_action,
enum = enum_action,
func_eval = func_eval_action,
number = function(x) return x end,
exprlist = function(a, ls) if ls then ls[#ls+1] = a else ls = {a} end; return ls end,
schema = function(x, y, conds, enums) return {x= x, y= y, conds= conds, enums= enums} end,
is_variable = is_variable,
is_number = is_number,
}
|