Module: Ibex::Frontend::BootstrapParserRules
- Included in:
- BootstrapParser
- Defined in:
- lib/ibex/frontend/parser/rules.rb,
sig/ibex/frontend/parser/rules.rbs
Overview
Parses productions and extended RHS items.
Constant Summary collapse
Instance Method Summary collapse
- #alternative_end?(lhs) ⇒ Boolean
- #parse_action ⇒ AST::InlineAction
- #parse_alternative(lhs) ⇒ AST::Alternative
- #parse_group ⇒ AST::item
- #parse_item ⇒ AST::item
- #parse_named_reference ⇒ String?
- #parse_node_annotation ⇒ AST::NodeAnnotation?
- #parse_rule ⇒ AST::Rule
- #parse_rules ⇒ Array[AST::Rule]
- #parse_separated_list ⇒ AST::SeparatedList
- #parse_suffix(item) ⇒ AST::item
- #rule_start?(lhs) ⇒ Boolean
- #separated_list? ⇒ Boolean
Instance Method Details
#alternative_end?(lhs) ⇒ Boolean
170 171 172 173 |
# File 'lib/ibex/frontend/parser/rules.rb', line 170 def alternative_end?(lhs) # @type self: BootstrapParser %i[| ; inline node eof user_code].include?(current.type) || keyword?("end") || rule_start?(lhs) end |
#parse_action ⇒ AST::InlineAction
109 110 111 112 113 |
# File 'lib/ibex/frontend/parser/rules.rb', line 109 def parse_action # @type self: BootstrapParser token = advance AST::InlineAction.new(code: token_string(token), loc: token.location) end |
#parse_alternative(lhs) ⇒ AST::Alternative
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/ibex/frontend/parser/rules.rb', line 45 def parse_alternative(lhs) # @type self: BootstrapParser location = current.location items = [] #: Array[AST::item] precedence = nil #: String? until alternative_end?(lhs) if accept(:"=") precedence = parse_symbol_name break end items << parse_item end action = nil #: AST::InlineAction? last_item = items.last if last_item.is_a?(AST::InlineAction) items.pop action = last_item end node_annotation = parse_node_annotation AST::Alternative.new( items: items, action: action, precedence: precedence, node_annotation: node_annotation, loc: location ) end |
#parse_group ⇒ AST::item
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/ibex/frontend/parser/rules.rb', line 136 def parse_group # @type self: BootstrapParser opening = advance extended_only!(opening.location, "EBNF groups") alternatives = [[]] #: Array[Array[AST::item]] until current.type == :")" fail_at(opening.location, "unterminated EBNF group") if current.type == :eof if accept(:|) alternatives << [] next end fail_at(current.location, "actions inside EBNF groups are not supported") if current.type == :action alternatives.last << parse_item end expect(:")") parse_suffix(AST::Group.new(alternatives: alternatives, loc: opening.location)) end |
#parse_item ⇒ AST::item
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/ibex/frontend/parser/rules.rb', line 88 def parse_item # @type self: BootstrapParser return parse_action if current.type == :action if current.type == :empty token = advance extended_only!(token.location, "%empty") return AST::Empty.new(loc: token.location) end return parse_separated_list if separated_list? return parse_parameterized_reference if parameterized_call? return parse_group if current.type == :"(" token = expect_symbol named_reference = parse_named_reference item = AST::SymbolReference.new(name: token_string(token), named_reference: named_reference, loc: token.location) parse_suffix(item) end |
#parse_named_reference ⇒ String?
116 117 118 119 120 121 122 123 |
# File 'lib/ibex/frontend/parser/rules.rb', line 116 def parse_named_reference # @type self: BootstrapParser return nil unless current.type == :":" extended_only!(current.location, "named references") advance token_string(expect(:identifier)) end |
#parse_node_annotation ⇒ AST::NodeAnnotation?
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/ibex/frontend/parser/rules.rb', line 70 def parse_node_annotation # @type self: BootstrapParser marker = accept(:node) return unless marker extended_only!(marker.location, "@node") name = expect(:identifier) expect(:"(") fields = [] #: Array[String] unless current.type == :")" fields << token_string(expect(:identifier)) fields << token_string(expect(:identifier)) while accept(:",") end expect(:")") AST::NodeAnnotation.new(name: token_string(name), fields: fields, loc: marker.location) end |
#parse_rule ⇒ AST::Rule
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/ibex/frontend/parser/rules.rb', line 23 def parse_rule # @type self: BootstrapParser inline = accept(:inline) extended_only!(inline.location, "inline rules") if inline lhs = expect(:identifier) parameters = parse_rule_parameters(lhs) expect(:":") alternatives = [] #: Array[AST::Alternative] loop do alternatives << parse_alternative(lhs) next if accept(:|) accept(:";") break end AST::Rule.new( lhs: token_string(lhs), parameters: parameters, alternatives: alternatives, loc: lhs.location, inline: !!inline ) end |
#parse_rules ⇒ Array[AST::Rule]
14 15 16 17 18 19 20 |
# File 'lib/ibex/frontend/parser/rules.rb', line 14 def parse_rules # @type self: BootstrapParser rules = [] #: Array[AST::Rule] rules << parse_rule until keyword?("end") || %i[eof user_code].include?(current.type) fail_expected("at least one rule") if rules.empty? rules end |
#parse_separated_list ⇒ AST::SeparatedList
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/ibex/frontend/parser/rules.rb', line 156 def parse_separated_list # @type self: BootstrapParser function = advance extended_only!(function.location, "separated lists") expect(:"(") item = parse_item expect(:",") separator = parse_item expect(:")") AST::SeparatedList.new(item: item, separator: separator, nonempty: function.value == "separated_nonempty_list", loc: function.location) end |
#parse_suffix(item) ⇒ AST::item
126 127 128 129 130 131 132 133 |
# File 'lib/ibex/frontend/parser/rules.rb', line 126 def parse_suffix(item) # @type self: BootstrapParser while (wrapper = EXTENDED_SUFFIXES[current.type]) extended_only!(current.location, "EBNF suffixes") item = wrapper.new(item: item, loc: advance.location) end item end |
#rule_start?(lhs) ⇒ Boolean
176 177 178 179 180 181 182 |
# File 'lib/ibex/frontend/parser/rules.rb', line 176 def rule_start?(lhs) # @type self: BootstrapParser return false unless current.type == :identifier && current.location.column <= lhs.location.column return true if lookahead.type == :":" parameterized_rule_start? end |
#separated_list? ⇒ Boolean
185 186 187 188 |
# File 'lib/ibex/frontend/parser/rules.rb', line 185 def separated_list? # @type self: BootstrapParser %w[separated_list separated_nonempty_list].include?(current.value) && lookahead.type == :"(" end |