From 0d1ee74ca63a73ba716fb95166c22ca29fef7f91 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Thu, 9 May 2024 17:35:27 -0400 Subject: [PATCH] Give a better error message when a referenced ptype has not been declared --- lib/propane/generator.rb | 12 ++++++++++++ spec/propane_spec.rb | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/lib/propane/generator.rb b/lib/propane/generator.rb index 7c0444b..7611ad9 100644 --- a/lib/propane/generator.rb +++ b/lib/propane/generator.rb @@ -51,6 +51,7 @@ class Propane unless found_default raise Error.new("No patterns found for default mode") end + check_ptypes! # Add EOF token. @grammar.tokens << Token.new("$EOF", nil, nil) tokens_by_name = {} @@ -131,6 +132,17 @@ class Propane @parser = Parser.new(@grammar, rule_sets, @log) end + # Check that any referenced ptypes have been defined. + def check_ptypes! + (@grammar.patterns + @grammar.tokens + @grammar.rules).each do |potor| + if potor.ptypename + unless @grammar.ptypes.include?(potor.ptypename) + raise Error.new("Error: Line #{potor.line_number}: ptype #{potor.ptypename} not declared. Declare with `ptype` statement.") + end + end + end + end + # Generate and add rules for any optional components. def generate_optional_component_rules!(tokens_by_name) optional_rules_added = Set.new diff --git a/spec/propane_spec.rb b/spec/propane_spec.rb index ba09416..43b11d0 100644 --- a/spec/propane_spec.rb +++ b/spec/propane_spec.rb @@ -148,6 +148,42 @@ EOF expect(results.status).to_not eq 0 end + it "raises an error when a pattern referenced ptype has not been defined" do + write_grammar <> +/bar/ (no) << +>> +EOF + results = run_propane(capture: true) + expect(results.stderr).to match /Error: Line 4: ptype no not declared\. Declare with `ptype` statement\./ + expect(results.status).to_not eq 0 + end + + it "raises an error when a token referenced ptype has not been defined" do + write_grammar < bar; +bar (no) -> xyz; +EOF + results = run_propane(capture: true) + expect(results.stderr).to match /Error: Line 4: ptype no not declared\. Declare with `ptype` statement\./ + expect(results.status).to_not eq 0 + end + %w[d c].each do |language| context "#{language.upcase} language" do