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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
require "forwardable"
module Lrama
class Grammar
class Code < Struct.new(:type, :token_code, keyword_init: true)
extend Forwardable
def_delegators "token_code", :s_value, :line, :column, :references
# $$, $n, @$, @n is translated to C code
def translated_code
case type
when :user_code
translated_user_code
when :initial_action
translated_initial_action_code
end
end
# * ($1) error
# * ($$) *yyvaluep
# * (@1) error
# * (@$) *yylocationp
def translated_printer_code(tag)
t_code = s_value.dup
references.reverse.each do |ref|
first_column = ref.first_column
last_column = ref.last_column
case
when ref.value == "$" && ref.type == :dollar # $$
# Omit "<>"
member = tag.s_value[1..-2]
str = "((*yyvaluep).#{member})"
when ref.value == "$" && ref.type == :at # @$
str = "(*yylocationp)"
when ref.type == :dollar # $n
raise "$#{ref.value} can not be used in %printer."
when ref.type == :at # @n
raise "@#{ref.value} can not be used in %printer."
else
raise "Unexpected. #{self}, #{ref}"
end
t_code[first_column..last_column] = str
end
return t_code
end
alias :translated_error_token_code :translated_printer_code
private
# * ($1) yyvsp[i]
# * ($$) yyval
# * (@1) yylsp[i]
# * (@$) yyloc
def translated_user_code
t_code = s_value.dup
references.reverse.each do |ref|
first_column = ref.first_column
last_column = ref.last_column
case
when ref.value == "$" && ref.type == :dollar # $$
# Omit "<>"
member = ref.tag.s_value[1..-2]
str = "(yyval.#{member})"
when ref.value == "$" && ref.type == :at # @$
str = "(yyloc)"
when ref.type == :dollar # $n
i = -ref.position_in_rhs + ref.value
# Omit "<>"
member = ref.tag.s_value[1..-2]
str = "(yyvsp[#{i}].#{member})"
when ref.type == :at # @n
i = -ref.position_in_rhs + ref.value
str = "(yylsp[#{i}])"
else
raise "Unexpected. #{self}, #{ref}"
end
t_code[first_column..last_column] = str
end
return t_code
end
# * ($1) error
# * ($$) yylval
# * (@1) error
# * (@$) yylloc
def translated_initial_action_code
t_code = s_value.dup
references.reverse.each do |ref|
first_column = ref.first_column
last_column = ref.last_column
case
when ref.value == "$" && ref.type == :dollar # $$
str = "yylval"
when ref.value == "$" && ref.type == :at # @$
str = "yylloc"
when ref.type == :dollar # $n
raise "$#{ref.value} can not be used in initial_action."
when ref.type == :at # @n
raise "@#{ref.value} can not be used in initial_action."
else
raise "Unexpected. #{self}, #{ref}"
end
t_code[first_column..last_column] = str
end
return t_code
end
end
end
end
|