Skip to content

How to add new parser?

Rodrigo Siqueira de Melo edited this page Feb 12, 2016 · 4 revisions

As explained in the architectural section, if you want to add a new parser you have to create one concrete class per abstract class inside the package abstract container. To make it clear, we will show step by step (if you are in a hurry, go to the last section).

Create folder on the correct place

Firstly, go to lib/kuniri/language/ and creates one folder with the language name which you want to write a parser. Example:

cd lib/kuniri/language/
mkdir lib/kuniri/language/[languageName]

Create specific files

Secondly, you have to create one file for each element that your parser have and make it inherit from the abstract element. For example, in the case of Java we have: attributes, classes, constructors, methods, etc. So, you have to create one file called attributeJava, classJava, etc. We have a specific way to give a name to our files, you have to follow this rule: [element]_[language_name].rb . See below the example:

cd lib/kuniri/language/java/
touch attribute_java.rb
touch class_java.rb
touch method_java.rb

Fill out the new classes

Your third step, it is fill out all the classes that you create. Basically, all classes have this simple template:

require_relative 'needed element'

module Languages

  module [Language Name]

    # Handle ruby attribute
    class [ElementLanguageName] < Languages::[Abstract Container Class]
      # Specific method signatures and implementations
    end
  end
end

As an example, suppose we create Java parser and we are working on class extraction. We will have something similar to the code below:

require_relative '../abstract_container/structured_and_oo/class.rb'
require_relative '../container_data/structured_and_oo/class_data.rb'
require_relative '../../util/html_logger'
require_relative '../../core/setting'

module Languages

  module Java

    class ClassJava < Languages::Class

      public

        def initialize
          # Some initialization code
        end

        def get_class(pLine)
          result = detect_class(pLine)
          return nil unless result

          # Here we can have a bunch of code

          return classCaptured
        end

      protected

        def detect_class(pLine)
          regexExpression = /^\s*class\s+(.*)/
          # ... code ...
          return nil unless pLine =~ regexExpression
          return pLine.scan(regexExpression)[0].join("")
        end

        def get_inheritance(pString)
          # ... code ...
        end

      def remove_unnecessary_information(pString)
          # ... code ...
      end

      def prepare_final_string(pString)
        # ... code ...
      end

    # class
    end
  
  # Ruby
  end

# Languages
end

Add test

Yes, part of the cycle have a test! You have to implement a test for each new class, and you have to add the test files in spec/language/[Language name]. We strongly recommend you to create some samples of code for use in your tests, the correct place to add it is in spec/samples.

One shortcut

We have a simple shortcut, for create all files described above. 😄 All you have to do is type:

rake parser:create [languageName]

This command will create all required folder, and files. Then you just have to focus on code.

If you want to remove an parse, just type:

rake parser:remove [languageName]