Giter Club home page Giter Club logo

aligner's Introduction

Aligner Build Status

Sublime Text plugin for automatic code alignment.

This project is a tool for automatic code alignment. Formatting source code so that similar syntactic structures are arranged one above the other is often used to improve readability.

First of all, for convenience, the lines of code are split into tokens having a generic type. For example, the identifiers have type :id, and the brackets have type :bracket. The project implemented a type hierarchy, which simplifies the setup. It is defined in heirarchy.rb.

Each type must match the regular expression that recognizes token of this type. Moreover, the sequence of regular expressions must follow the hierarchy. That is more general regular expressions are used later. This sequence is described in the class TypeData, the file staff.rb.

To achieve maximum flexibility and independence of the type of language in which the source code is written, parser of the context-free grammars is implemented.

It works in conjunction with the algorithm based on dynamic programming, which finds matching having a maximum weight of two arrays of tokens.

The grammar in BNF is in file grammar.rb. Grammar should be designed so that if the rule of convolution can be applied, it should be applied, otherwise any sequence of tokens should still be correct.

Here is the example of grammar:

@@grammar.add_rule(:main, [:expr    ], [:reducible]);
@@grammar.add_rule(:expr, [:expr, :p], [:reducible]);
@@grammar.add_rule(:expr, [:p       ], [:reducible]);
t1 = [:expr, TokenTemplate.new(['=']), :expr]
@@grammar.add_rule(:expr, t1)
@@grammar.add_rule(:p, [:t], [:reducible])
@@grammar.add_rule(:t, [TokenTemplate.new(:id)], [:reducible]);

This grammar defines the assignment operation. The first argument to the procedure of adding rules - nonterminal. :main - axiom of the grammar. The second argument is the rule itself. It may consist of nonterminals and templates of tokens. A template can define a valid token type, a specific value, and excluded values.

Grammar shown corresponds to the following recorded in the canonical Backus–Naur form:

main ::= expr
expr ::= expr p | p | expr '=' expr
p    ::= t
t    ::= <any identifier>

Flag :reducible indicates that this rule has no effect on meta-expression being fitted. Meta-expression is an array of tokens, which also contains other meta-expression. Each level of the obtained tree structure is compared in the matching process only with the corresponding level of the other meta-expression. Consider the example:

f(a, b + c   )
f(   b + c, a)

and

f(a    , b + c)
f(b + c, a    )

When using the grammar, the program causes the alignment of the second type, in spite of the fact that different function arguments are similar in spelling. Such behavior is, of course, leads to improvement of readability.

To maximize the quality for each language you need to write its own grammar.

Examples of work

From

@@types_inheritance[:space] = nil;
@@types_inheritance[:quote] = nil;
@@types_inheritance[:regexp] = nil;
@@types_inheritance[:id] = nil;
@@types_inheritance[:spchar] = nil;

To

@@types_inheritance[:space ] = nil;
@@types_inheritance[:quote ] = nil;
@@types_inheritance[:regexp] = nil;
@@types_inheritance[:id    ] = nil;
@@types_inheritance[:spchar] = nil;

From

switch (state)                                
{                                            
    case State.QLD: city = "Brisbane"; break; 
    case State.WA: city = "Perth"; break;     
    case State.NSW: city = "Sydney"; break;   
    default: city = "???"; break;             
}            

To

switch (state)                                
{
    case State.QLD:city = "Brisbane"; break;
    case State.WA :city = "Perth"   ; break;
    case State.NSW:city = "Sydney"  ; break;
    default       :city = "???"     ; break;
}                                            

##Learning

Due to the fact that different people are accustomed to different ways of setting padding between tokens, you must use the simplest method of fine-tuning. The project implements a method of learning. The input is properly formatted string. The resulting information is aggregated and used in the future for proper indenting.

There are 2 types of training: minimum and maximum indents.

Training starts with the command ruby learner_test.rb <lang_type>. It is not required by default. The resulting information is stored in files max_by_type_<lang_type>.dat and min_by_type_<lang_type>.dat.

##Installation

First of all, make sure that your system has a ruby interpreter ver. >= 1.9. In Ubuntu you can use following command:

sudo apt-get install ruby

To install the plugin, clone it to your Siblime Text 2/3 Package directory with following command:

cd ~/.config/sublime-text-3/Packages
git clone https://github.com/generall/aligner.git AutoAligner

Or you may install it with Package Control using name AutoAligner.

Default hotkey for alignment is: ["ctrl+k","ctrl+a"].

##Prospection

Here is a list of things that have to be improved.

  • Automatic detection of similar lines for fully automated code alignment.
  • Customization for different languages.
    • extended grammar
    • extended set of types of token
    • Customized languages:
      • C
      • java
  • Extended machine learning for alignment decision
    • experiments with Markov chain learing
  • to be continued...

The expected course of action to add the grammar.

In file staff.rb add new regexp array by following pattern:

@@regexp_array[:new_grammar_name] =
[
		# [<reg_exp>, <tag>, <is_necessary>, <min_simularity>, <min_previous_space>, <min_follow_space> ]
		[/^'(\\.|[^'])*'/                 , :quote       , true , 0.1, 0, 1], 
		...
] 

Add BNF to file grammar.rb.

aligner's People

Contributors

generall avatar quasiyoke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

quasiyoke selukov

aligner's Issues

fails on

  [ 1, 1  ],
  [ 2, 1  ],
  [ 2, 1  ],
  [ 1.5, 1],
  [ 2, 1.5],
  [ 2, 1  ],
  [ 2, 2  ],
  [ 2, 1  ],
  [ 1, 2  ],
  [ 2, 2  ],
  [ 5, 1  ],
  [ 5, 1  ],
  [ 5, 1  ],
  [ 5, 1  ],
  [ 5, 1  ],
  [ 5, 1  ],
  [ 5, 1  ],
  [ 5, 2  ],
  [ 5, 5  ],
  [ 5, 6  ],
  [ 5, 6  ],
  [ 5, 6  ],
  [ 5, 6  ],

bug

check this:
uint32_t props[MAX_PROPS];
uint32_t props_size;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.