Skip to content

EBNF.parse with :ebnf fails to parse leading '-' inside character classes #17

@phdavis1027

Description

@phdavis1027

Describe the bug
When trying to convert the EBNF specification of XML 1.0 found here, I get this exception:

/home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/ebnf-2.6.0/lib/ebnf/peg/parser.rb:256:in 'EBNF::PEG::Parser#parse': ERROR [line: 14] syntax error, expecting :HEX, :SYMBOL, :O_RANGE, :RANGE, :STRING1, :STRING2, "(", :primary, :postfix, :seq (found "[-'()+,./:=?;!*\#@$_%") (EBNF::PEG::Parser::Error)
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/ebnf-2.6.0/lib/ebnf/parser.rb:309:in 'EBNF::Parser#initialize'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/ebnf-2.6.0/lib/ebnf/base.rb:125:in 'Class#new'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/ebnf-2.6.0/lib/ebnf/base.rb:125:in 'EBNF::Base#initialize'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/ebnf-2.6.0/lib/ebnf.rb:29:in 'Class#new'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/ebnf-2.6.0/lib/ebnf.rb:29:in 'EBNF.parse'
        from /home/phillipdavis/everyday/dev/mboa/maqam/lib/maqam.rb:16:in 'Maqam::Generator#initialize'
        from (irb):2:in 'Class#new'
        from (irb):2:in '<main>'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/irb-1.17.0/lib/irb/workspace.rb:110:in 'Kernel#eval'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/irb-1.17.0/lib/irb/workspace.rb:110:in 'IRB::WorkSpace#evaluate'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/irb-1.17.0/lib/irb/context.rb:591:in 'IRB::Context#evaluate_expression'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/irb-1.17.0/lib/irb/context.rb:557:in 'IRB::Context#evaluate'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/irb-1.17.0/lib/irb.rb:217:in 'block (2 levels) in IRB::Irb#eval_input'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/irb-1.17.0/lib/irb.rb:534:in 'IRB::Irb#signal_status'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/irb-1.17.0/lib/irb.rb:209:in 'block in IRB::Irb#eval_input'
        from /home/phillipdavis/everyday/dev/mboa/maqam/.gems/ruby/3.4.0/gems/irb-1.17.0/lib/irb.rb:296:in 'block in IRB::Irb#each_top_level_statement'
        ... 25 levels...

To reproduce
Steps to reproduce the behavior:

EBNF.parse(/* the grammar */).make_bnf

Expected behavior
It converts the grammar into a BNF

Screenshots
N/A

Desktop (please complete the following information):
N/A
Smartphone (please complete the following information):
N/A

Additional context

Gems included by the bundle:
  * addressable (2.8.9)
  * ast (2.4.3)
  * base64 (0.3.0)
  * bcp47_spec (0.2.1)
  * bigdecimal (3.3.1)
  * date (3.5.1)
  * ebnf (2.6.0)
  * erb (6.0.2)
  * htmlentities (4.4.2)
  * io-console (0.8.2)
  * irb (1.17.0)
  * jennifer (0.0.0 5f71c9d)
  * json (2.18.1)
  * json-schema (6.1.0)
  * language_server-protocol (3.17.0.5)
  * link_header (0.0.8)
  * lint_roller (1.1.0)
  * logger (1.7.0)
  * maqam (0.1.0)
  * matrix (0.4.3)
  * mcp (0.8.0)
  * minitest (5.27.0)
  * ostruct (0.6.3)
  * parallel (1.27.0)
  * parser (3.3.10.2)
  * pp (0.6.3)
  * prettyprint (0.2.0)
  * prism (1.9.0)
  * psych (5.3.1)
  * public_suffix (7.0.5)
  * racc (1.8.1)
  * rainbow (3.1.1)
  * rake (13.3.1)
  * rantly (3.0.0)
  * rbs (3.10.3)
  * rdf (3.3.4)
  * rdoc (7.2.0)
  * readline (0.0.4)
  * regexp_parser (2.11.3)
  * reline (0.6.3)
  * rubocop (1.85.0)
  * rubocop-ast (1.49.0)
  * ruby-progressbar (1.13.0)
  * scanf (1.0.0)
  * stringio (3.2.0)
  * sxp (2.0.0)
  * tsort (0.2.0)
  * unicode-display_width (3.2.0)
  * unicode-emoji (4.2.0)
  * unicode-types (1.11.0)
phillipdavis in ~/.../mboa/maqam on master✗  λ bundle exec ruby --version
ruby 3.4.8 (2025-12-17 revision 995b59f666) +PRISM [x86_64-linux]

To be honest, I'm not sure whether this is a bug in this library or a mistake in the grammar itself. Either way, I'd be willing to put together a pull request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions