blob: 72afb6230353397dca9f1e4888f7e2b14c074b12 (
plain)
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
|
module Lrama
class Grammar
class Code
class RuleAction < Code
def initialize(type: nil, token_code: nil, rule: nil)
super(type: type, token_code: token_code)
@rule = rule
end
private
# * ($$) yyval
# * (@$) yyloc
# * ($1) yyvsp[i]
# * (@1) yylsp[i]
#
# "Rule" class: keyword_class { $1 } tSTRING { $2 + $3 } keyword_end { $class = $1 + $keyword_end }
# "Position in grammar" $1 $2 $3 $4 $5 $6
# "Index for yyvsp" -4 -3 -2 -1 0
def reference_to_c(ref)
case
when ref.type == :dollar && ref.name == "$" # $$
tag = ref.ex_tag || lhs.tag
raise_tag_not_found_error(ref) unless tag
"(yyval.#{tag.member})"
when ref.type == :at && ref.name == "$" # @$
"(yyloc)"
when ref.type == :dollar # $n
i = -position_in_rhs + ref.index
tag = ref.ex_tag || rhs[ref.index - 1].tag
raise_tag_not_found_error(ref) unless tag
"(yyvsp[#{i}].#{tag.member})"
when ref.type == :at # @n
i = -position_in_rhs + ref.index
"(yylsp[#{i}])"
else
raise "Unexpected. #{self}, #{ref}"
end
end
def position_in_rhs
# If rule is not derived rule, User Code is only action at
# the end of rule RHS. In such case, the action is located on
# `@rule.rhs.count`.
@rule.position_in_original_rule_rhs || @rule.rhs.count
end
def rhs
(@rule.original_rule || @rule).rhs
end
def lhs
(@rule.original_rule || @rule).lhs
end
def raise_tag_not_found_error(ref)
raise "Tag is not specified for '$#{ref.value}' in '#{@rule.to_s}'"
end
end
end
end
end
|