Assign pattern code IDs in Generator instead of Grammar
This commit is contained in:
1 parent
e7e30c4f28
commit
150be33826
4 files changed
+17
-19
No files matched your search
@@ -28,6 +28,7 @@ class Propane
|
||||
def process_grammar!
|
||||
tokens_by_name = {}
|
||||
@grammar.tokens.each do |token|
|
||||
# Check for token name conflicts.
|
||||
if tokens_by_name.include?(token.name)
|
||||
raise Error.new("Duplicate token name #{token.name.inspect}")
|
||||
end
|
||||
@@ -35,9 +36,11 @@ class Propane
|
||||
end
|
||||
rule_sets = {}
|
||||
@grammar.rules.each do |rule|
|
||||
# Check for token/rule name conflict.
|
||||
if tokens_by_name.include?(rule.name)
|
||||
raise Error.new("Rule name collides with token name #{rule.name.inspect}")
|
||||
end
|
||||
# Build rule sets of all rules with the same name.
|
||||
@_rule_set_id ||= @grammar.tokens.size
|
||||
unless rule_sets[rule.name]
|
||||
rule_sets[rule.name] = RuleSet.new(rule.name, @_rule_set_id)
|
||||
@@ -46,9 +49,17 @@ class Propane
|
||||
rule.rule_set = rule_sets[rule.name]
|
||||
rule_sets[rule.name] << rule
|
||||
end
|
||||
# Check for start rule.
|
||||
unless rule_sets["Start"]
|
||||
raise Error.new("Start rule not found")
|
||||
end
|
||||
# Generate lexer user code IDs for lexer patterns with user code blocks.
|
||||
@grammar.patterns.select do |pattern|
|
||||
pattern.code
|
||||
end.each_with_index do |pattern, code_id|
|
||||
pattern.code_id = code_id
|
||||
end
|
||||
# Map rule components from names to Token/RuleSet objects.
|
||||
@grammar.rules.each do |rule|
|
||||
rule.components.map! do |component|
|
||||
if tokens_by_name[component]
|
||||
@@ -61,7 +72,9 @@ class Propane
|
||||
end
|
||||
end
|
||||
determine_possibly_empty_rulesets!(rule_sets)
|
||||
# Generate the lexer.
|
||||
@lexer = Lexer.new(@grammar.patterns)
|
||||
# Generate the parser.
|
||||
@parser = Parser.new(@grammar, rule_sets, rule_sets["Start"], @log)
|
||||
end
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ class Propane
|
||||
@patterns = []
|
||||
@tokens = []
|
||||
@rules = []
|
||||
@code_id = 0
|
||||
@line_number = 1
|
||||
@next_line_number = @line_number
|
||||
@input = input.gsub("\r\n", "\n")
|
||||
@@ -78,15 +77,12 @@ class Propane
|
||||
end
|
||||
pattern ||= name
|
||||
consume!(/\s+/)
|
||||
if code = parse_code_block!
|
||||
code_id = @code_id
|
||||
@code_id += 1
|
||||
else
|
||||
unless code = parse_code_block!
|
||||
consume!(/;/, "expected pattern or `;' or code block")
|
||||
end
|
||||
token = Token.new(name: name, id: @tokens.size, line_number: @line_number)
|
||||
@tokens << token
|
||||
pattern = Pattern.new(pattern: pattern, token: token, line_number: @line_number, code: code, code_id: code_id)
|
||||
pattern = Pattern.new(pattern: pattern, token: token, line_number: @line_number, code: code)
|
||||
@patterns << pattern
|
||||
end
|
||||
end
|
||||
@@ -132,9 +128,7 @@ class Propane
|
||||
unless code = parse_code_block!
|
||||
raise Error.new("Line #{@line_number}: expected code block to follow pattern")
|
||||
end
|
||||
code_id = @code_id
|
||||
@code_id += 1
|
||||
@patterns << Pattern.new(pattern: pattern, line_number: @line_number, code: code, code_id: code_id)
|
||||
@patterns << Pattern.new(pattern: pattern, line_number: @line_number, code: code)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ class Propane
|
||||
|
||||
# @option options [Integer, nil] :code_id
|
||||
# Code block ID.
|
||||
attr_reader :code_id
|
||||
attr_accessor :code_id
|
||||
|
||||
# @return [String, nil]
|
||||
# Pattern.
|
||||
@@ -32,8 +32,6 @@ class Propane
|
||||
# Optional parameters.
|
||||
# @option options [String, nil] :code
|
||||
# Code block to execute when the pattern is matched.
|
||||
# @option options [Integer, nil] :code_id
|
||||
# Code block ID.
|
||||
# @option options [Boolean] :drop
|
||||
# Whether this is a drop pattern.
|
||||
# @option options [String, nil] :pattern
|
||||
@@ -44,7 +42,6 @@ class Propane
|
||||
# Line number where the token was defined in the input grammar.
|
||||
def initialize(options)
|
||||
@code = options[:code]
|
||||
@code_id = options[:code_id]
|
||||
@drop = options[:drop]
|
||||
@pattern = options[:pattern]
|
||||
@token = options[:token]
|
||||
|
||||
Reference in new issue
Block a user