Class: Expressir::Express::Parser
- Inherits:
-
Object
- Object
- Expressir::Express::Parser
- Defined in:
- lib/expressir/express/parser.rb
Defined Under Namespace
Classes: Parser
Class Method Summary collapse
-
.from_exp(content, skip_references: nil, include_source: nil, use_native: nil, use_streaming: false) ⇒ Model::ExpFile
Parses Express content string into an Express model.
-
.from_exp_streaming_builder(content, skip_references: nil, include_source: nil) ⇒ Model::ExpFile
Parse using streaming builder (construct-by-construct).
-
.from_file(file, skip_references: nil, include_source: nil, root_path: nil, use_native: nil) ⇒ Model::ExpFile
Parses Express file into an Express model.
-
.from_files(files, skip_references: nil, include_source: nil, root_path: nil, use_native: nil) {|filename, schemas, error| ... } ⇒ Model::Repository
Parses Express files into an Express model.
Class Method Details
.from_exp(content, skip_references: nil, include_source: nil, use_native: nil, use_streaming: false) ⇒ Model::ExpFile
Parses Express content string into an Express model
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 |
# File 'lib/expressir/express/parser.rb', line 794 def self.from_exp(content, skip_references: nil, include_source: nil, use_native: nil, use_streaming: false) # Streaming builder mode - uses Parsanol streaming callbacks if use_streaming && Parser.native_available? && defined?(Parsanol::Native.parse_with_builder) return from_exp_streaming(content, skip_references: skip_references, include_source: include_source) end use_native = Parser.native_available? if use_native.nil? begin # Use cached parser instance for performance (avoids ~7ms Parser.new overhead) ast = if use_native && Parser.native_available? Parser.parse_native(content) else Parser.cached_parser.parse(content) end rescue Parsanol::ParseFailed, StandardError => e raise Error::SchemaParseFailure.new("(from string)", e) end exp_file = ::Expressir::Express::Builder.build_with_remarks(ast, source: content, include_source: include_source) exp_file.schemas.each do |schema| schema.file = nil schema.file_basename = nil end unless skip_references Expressir::Benchmark.measure_references do resolve_references_model_visitor = ResolveReferencesModelVisitor.new resolve_references_model_visitor.visit(exp_file) end end exp_file end |
.from_exp_streaming_builder(content, skip_references: nil, include_source: nil) ⇒ Model::ExpFile
Parse using streaming builder (construct-by-construct)
840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 |
# File 'lib/expressir/express/parser.rb', line 840 def self.from_exp_streaming_builder(content, skip_references: nil, include_source: nil) grammar_json = Parser.cached_grammar_json builder = ::Expressir::Express::StreamingBuilder.new(source: content, include_source: include_source) begin exp_file = Parsanol::Native.parse_with_builder(grammar_json, content, builder) rescue StandardError => e raise Error::SchemaParseFailure.new("(streaming)", e) end exp_file.schemas.each do |schema| schema.file = nil schema.file_basename = nil end unless skip_references Expressir::Benchmark.measure_references do resolve_references_model_visitor = ResolveReferencesModelVisitor.new resolve_references_model_visitor.visit(exp_file) end end exp_file end |
.from_file(file, skip_references: nil, include_source: nil, root_path: nil, use_native: nil) ⇒ Model::ExpFile
Parses Express file into an Express model
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 |
# File 'lib/expressir/express/parser.rb', line 697 def self.from_file(file, skip_references: nil, include_source: nil, root_path: nil, use_native: nil) # rubocop:disable Metrics/AbcSize Expressir::Benchmark.measure_file(file) do source = File.read file # remove root path from file path schema_file = root_path ? Pathname.new(file.to_s).relative_path_from(root_path).to_s : file.to_s use_native = Parser.native_available? if use_native.nil? begin ast = if use_native && Parser.native_available? begin Parser.parse_native(source) rescue StandardError # Native parser may fail on non-ASCII or edge cases; # fall back to Ruby parser Parser.cached_parser.parse source end else Parser.cached_parser.parse source end rescue Parsanol::ParseFailed => e # Instead of just printing, raise a proper error with file context raise Error::SchemaParseFailure.new(schema_file, e) end @exp_file = ::Expressir::Express::Builder.build_with_remarks(ast, source: source, include_source: include_source) # Set file path on the ExpFile and propagate to schemas @exp_file.path = schema_file @exp_file.schemas.each do |schema| schema.file = schema_file schema.file_basename = File.basename(schema_file, ".exp") end unless skip_references Expressir::Benchmark.measure_references do @resolve_references_model_visitor = ResolveReferencesModelVisitor.new @resolve_references_model_visitor.visit(@exp_file) end end @exp_file end end |
.from_files(files, skip_references: nil, include_source: nil, root_path: nil, use_native: nil) {|filename, schemas, error| ... } ⇒ Model::Repository
Parses Express files into an Express model
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 |
# File 'lib/expressir/express/parser.rb', line 754 def self.from_files(files, skip_references: nil, include_source: nil, root_path: nil, use_native: nil) all_exp_files = [] files.each do |file| exp_file = from_file(file, skip_references: true, root_path: root_path, use_native: use_native) all_exp_files << exp_file # Call the progress block if provided yield(file, exp_file&.schemas, nil) if block_given? rescue StandardError => e # Call the progress block with the error if provided yield(file, nil, e) if block_given? # Re-raise the error if it's not a schema parse failure # This allows handling of specific schema parse failures while still propagating other errors raise unless e.is_a?(Error::SchemaParseFailure) end @repository = Model::Repository.new(files: all_exp_files) unless skip_references Expressir::Benchmark.measure_references do @resolve_references_model_visitor = ResolveReferencesModelVisitor.new @resolve_references_model_visitor.visit(@repository) end end @repository end |