Split grammar statement parsing into separate methods
This commit is contained in:
parent
62cb5c03f2
commit
1547528ecf
@ -28,15 +28,45 @@ class Propane
|
||||
|
||||
def parse_statement!
|
||||
@next_line_number = @line_number
|
||||
if consume!(/\A\s+/)
|
||||
# Skip white space.
|
||||
elsif consume!(/\A#.*\n/)
|
||||
# Skip comment lines.
|
||||
elsif md = consume!(/\Amodule\s+(\S+)\s*;/)
|
||||
if parse_white_space!
|
||||
elsif parse_comment_line!
|
||||
elsif parse_module_statement!
|
||||
elsif parse_class_statement!
|
||||
elsif parse_token_statement!
|
||||
elsif parse_tokenid_statement!
|
||||
elsif parse_drop_statement!
|
||||
elsif parse_rule_statement!
|
||||
else
|
||||
if @input.size > 25
|
||||
@input = @input.slice(0..20) + "..."
|
||||
end
|
||||
raise Error.new("Unexpected grammar input at line #{@line_number}: #{@input.chomp}")
|
||||
end
|
||||
@line_number = @next_line_number
|
||||
end
|
||||
|
||||
def parse_white_space!
|
||||
consume!(/\A\s+/)
|
||||
end
|
||||
|
||||
def parse_comment_line!
|
||||
consume!(/\A#.*\n/)
|
||||
end
|
||||
|
||||
def parse_module_statement!
|
||||
if md = consume!(/\Amodule\s+(\S+)\s*;/)
|
||||
@modulename = md[1]
|
||||
elsif md = consume!(/\Aclass\s+(\S+)\s*;/)
|
||||
end
|
||||
end
|
||||
|
||||
def parse_class_statement!
|
||||
if md = consume!(/\Aclass\s+(\S+)\s*;/)
|
||||
@classname = md[1]
|
||||
elsif md = consume!(/\Atoken\s+(\S+?)(?:\s+([^\n]+?))?\s*(?:;|<<\n(.*?)^>>\n)/m)
|
||||
end
|
||||
end
|
||||
|
||||
def parse_token_statement!
|
||||
if md = consume!(/\Atoken\s+(\S+?)(?:\s+([^\n]+?))?\s*(?:;|<<\n(.*?)^>>\n)/m)
|
||||
name, pattern, code = *md[1, 3]
|
||||
if pattern.nil?
|
||||
pattern = name
|
||||
@ -54,17 +84,29 @@ class Propane
|
||||
end
|
||||
pattern = Pattern.new(pattern: pattern, token: token, line_number: @line_number, code: code, code_id: code_id)
|
||||
@patterns << pattern
|
||||
elsif md = consume!(/\Atokenid\s+(\S+?)\s*;/m)
|
||||
end
|
||||
end
|
||||
|
||||
def parse_tokenid_statement!
|
||||
if md = consume!(/\Atokenid\s+(\S+?)\s*;/m)
|
||||
name = md[1]
|
||||
unless name =~ /^[a-zA-Z_][a-zA-Z_0-9]*$/
|
||||
raise Error.new("Invalid token name #{name.inspect}")
|
||||
end
|
||||
token = Token.new(name: name, id: @tokens.size, line_number: @line_number)
|
||||
@tokens << token
|
||||
elsif md = consume!(/\Adrop\s+(\S+)\s*;/)
|
||||
end
|
||||
end
|
||||
|
||||
def parse_drop_statement!
|
||||
if md = consume!(/\Adrop\s+(\S+)\s*;/)
|
||||
pattern = md[1]
|
||||
@patterns << Pattern.new(pattern: pattern, line_number: @line_number, drop: true)
|
||||
elsif md = consume!(/\A(\S+)\s*->\s*([^\n]*?)(?:;|<<\n(.*?)^>>\n)/m)
|
||||
end
|
||||
end
|
||||
|
||||
def parse_rule_statement!
|
||||
if md = consume!(/\A(\S+)\s*->\s*([^\n]*?)(?:;|<<\n(.*?)^>>\n)/m)
|
||||
rule_name, components, code = *md[1, 3]
|
||||
unless rule_name =~ /^[a-zA-Z_][a-zA-Z_0-9]*$/
|
||||
raise Error.new("Invalid rule name #{name.inspect}")
|
||||
@ -72,13 +114,7 @@ class Propane
|
||||
components = components.strip.split(/\s+/)
|
||||
# Reserve rule ID 0 for the "real" start rule.
|
||||
@rules << Rule.new(rule_name, components, code, @line_number, @rules.size + 1)
|
||||
else
|
||||
if @input.size > 25
|
||||
@input = @input.slice(0..20) + "..."
|
||||
end
|
||||
raise Error.new("Unexpected grammar input at line #{@line_number}: #{@input.chomp}")
|
||||
end
|
||||
@line_number = @next_line_number
|
||||
end
|
||||
|
||||
# Check if the input string matches the given regex.
|
||||
|
Loading…
x
Reference in New Issue
Block a user