Class: Highway::Compiler::Parse::Parser
- Inherits:
-
Object
- Object
- Highway::Compiler::Parse::Parser
- Defined in:
- lib/highway/compiler/parse/parser.rb
Overview
This class is responsible for syntactic analysis of a configuration file. This is the first phase of the compiler.
Instance Method Summary collapse
-
#initialize(interface:) ⇒ Parser
constructor
Initialize an instance.
-
#parse(path:) ⇒ Highway::Compiler::Parse::Tree::Root
Parse the configuration file.
Constructor Details
#initialize(interface:) ⇒ Parser
Initialize an instance.
23 24 25 |
# File 'lib/highway/compiler/parse/parser.rb', line 23 def initialize(interface:) @interface = interface end |
Instance Method Details
#parse(path:) ⇒ Highway::Compiler::Parse::Tree::Root
Parse the configuration file.
The parser is backwards compatible with previous versions of configuration files.
This method only loads the file, searches for the version declaration and then delegates the wotk to parser of a particular version.
The parser produces a parse tree which is then used by semantic analysis phase to produce semantic tree.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/highway/compiler/parse/parser.rb', line 41 def parse(path:) # Load the file. unless File.exist?(path) @interface.fatal!("The configuration file '#{path}' does not exist.") end begin raw = YAML.load_file(path) rescue StandardError => error @interface.fatal!("The configuration file '#{path}' is not a valid YAML file.") end # Make sure it contains a hash. unless raw.is_a?(Hash) @interface.fatal!("The configuration file does not contain a top-level dictionary.") end # Specify the known versions and their corresponding subparsers. known = { 1 => Parse::Versions::V1, } # Find and validate the version. unless version = (Integer(raw.fetch("version", nil)) rescue nil) @interface.fatal!("Missing or invalid value of: 'version'.") end unless known.keys.include?(version) expected_versions = known.keys.map { |v| "'#{v}'" }.join(", ") @interface.fatal!("Invalid value of: 'version'. Expected one of: [#{expected_versions}], got: '#{version}'.") end # Delegate the work to parser of a specific version. subparser = known[version].new(interface: @interface) # Parse and return the tree. subparser.parse(raw: raw) end |