Add new start rule ending with EOF token rather than appending EOF token to all user-specified start rules
This commit is contained in:
parent
2837dfda6b
commit
d6e5c4325d
@ -35,7 +35,7 @@ class Propane
|
|||||||
pattern = name
|
pattern = name
|
||||||
end
|
end
|
||||||
unless name =~ /^[a-zA-Z_][a-zA-Z_0-9]*$/
|
unless name =~ /^[a-zA-Z_][a-zA-Z_0-9]*$/
|
||||||
raise Error.new("Invalid token name #{name}")
|
raise Error.new("Invalid token name #{name.inspect}")
|
||||||
end
|
end
|
||||||
@tokens << Token.new(name: name, pattern: pattern, id: @tokens.size, line_number: line_number)
|
@tokens << Token.new(name: name, pattern: pattern, id: @tokens.size, line_number: line_number)
|
||||||
elsif sliced = input.slice!(/\Adrop\s+(\S+)\n/)
|
elsif sliced = input.slice!(/\Adrop\s+(\S+)\n/)
|
||||||
@ -43,8 +43,12 @@ class Propane
|
|||||||
@drop_tokens << Token.new(pattern: pattern, line_number: line_number)
|
@drop_tokens << Token.new(pattern: pattern, line_number: line_number)
|
||||||
elsif sliced = input.slice!(/\A(\S+)\s*->\s*(.*?)(?:;|<<\n(.*?)^>>\n)/m)
|
elsif sliced = input.slice!(/\A(\S+)\s*->\s*(.*?)(?:;|<<\n(.*?)^>>\n)/m)
|
||||||
rule_name, components, code = $1, $2, $3
|
rule_name, components, code = $1, $2, $3
|
||||||
|
unless rule_name =~ /^[a-zA-Z_][a-zA-Z_0-9]*$/
|
||||||
|
raise Error.new("Invalid rule name #{name.inspect}")
|
||||||
|
end
|
||||||
components = components.strip.split(/\s+/)
|
components = components.strip.split(/\s+/)
|
||||||
@rules << Rule.new(rule_name, components, code, line_number, @rules.size)
|
# Reserve rule ID 0 for the "real" start rule.
|
||||||
|
@rules << Rule.new(rule_name, components, code, line_number, @rules.size + 1)
|
||||||
else
|
else
|
||||||
if input.size > 25
|
if input.size > 25
|
||||||
input = input.slice(0..20) + "..."
|
input = input.slice(0..20) + "..."
|
||||||
|
@ -3,15 +3,13 @@ class Propane
|
|||||||
class Parser
|
class Parser
|
||||||
|
|
||||||
def initialize(start_rule_set)
|
def initialize(start_rule_set)
|
||||||
@token_eof = Token.new(name: "$", id: TOKEN_EOF)
|
@eof_token = Token.new(name: "$", id: TOKEN_EOF)
|
||||||
|
start_rule = Rule.new("$$", [start_rule_set, @eof_token], nil, nil, 0)
|
||||||
@item_sets = []
|
@item_sets = []
|
||||||
@item_sets_set = {}
|
@item_sets_set = {}
|
||||||
start_items = start_rule_set.rules.map do |rule|
|
start_item = Item.new(start_rule, 0)
|
||||||
rule.components << @token_eof
|
|
||||||
Item.new(rule, 0)
|
|
||||||
end
|
|
||||||
eval_item_sets = Set.new
|
eval_item_sets = Set.new
|
||||||
eval_item_sets << ItemSet.new(start_items)
|
eval_item_sets << ItemSet.new([start_item])
|
||||||
|
|
||||||
while eval_item_sets.size > 0
|
while eval_item_sets.size > 0
|
||||||
this_eval_item_sets = eval_item_sets
|
this_eval_item_sets = eval_item_sets
|
||||||
@ -22,7 +20,7 @@ class Propane
|
|||||||
@item_sets << item_set
|
@item_sets << item_set
|
||||||
@item_sets_set[item_set] = item_set
|
@item_sets_set[item_set] = item_set
|
||||||
item_set.following_symbols.each do |following_symbol|
|
item_set.following_symbols.each do |following_symbol|
|
||||||
unless following_symbol == @token_eof
|
unless following_symbol == @eof_token
|
||||||
following_set = item_set.build_following_item_set(following_symbol)
|
following_set = item_set.build_following_item_set(following_symbol)
|
||||||
eval_item_sets << following_set
|
eval_item_sets << following_set
|
||||||
end
|
end
|
||||||
@ -71,7 +69,7 @@ class Propane
|
|||||||
|
|
||||||
def process_item_set(item_set)
|
def process_item_set(item_set)
|
||||||
item_set.following_symbols.each do |following_symbol|
|
item_set.following_symbols.each do |following_symbol|
|
||||||
unless following_symbol == @token_eof
|
unless following_symbol == @eof_token
|
||||||
following_set = @item_sets_set[item_set.build_following_item_set(following_symbol)]
|
following_set = @item_sets_set[item_set.build_following_item_set(following_symbol)]
|
||||||
item_set.following_item_set[following_symbol] = following_set
|
item_set.following_item_set[following_symbol] = following_set
|
||||||
following_set.in_sets << item_set
|
following_set.in_sets << item_set
|
||||||
|
Loading…
x
Reference in New Issue
Block a user