rubymetaprogrammingparslet

Ruby: How to generate lines of code inside a program?


I am developing a parser in Ruby using the parslet library.

The language I am parsing has a lot of keywords that can be merged into a single parsing rule like this:

rule(:keyword) {  
    str('keyword1')     |
    str('keyword2')     | 
    str('keyword2')     ... 

}

Is there a good way to generate this set of lines of code dynamically, by reading a text file with all the keywords? This would help me keep my parser clean and small, making it easier to add new keywords without modifying the code.

The pseudo-code of what I want to embed inside the rule(:keyword) would be somethings like this:

File.read("keywords.txt").each { |k| write_line " str(\'#{k}\') "} 

So far, the workaround I have found is to have a separate ruby program loading the parser code as:

keywords = ["keyword1", "keyword2","keyword3"]

subs = {:keyword_list => keywords .inject("") { |a,k| a << "str('#{k}') | \n"} }

eval( File.read("parser.rb") % subs)

where the parser code has the following lines:

rule(:keywords){ 
   %{keyword_list} 
 }

Is there a more elegant way to achieve this?


Solution

  • You can try something like this:

    rule(:keyword) {  
      File.readlines("keywords.txt").map { |k| str(k.chomp) }.inject(&:|)
    }