当前位置: 首页 >> 程序设计 >> 使用Antlr和JfreeChart实现项目源代码行数计算图表
 

使用Antlr和JfreeChart实现项目源代码行数计算图表

作者:      来源:tyrone1979/archive/2006/04/19/669673.aspx     发表时间:2006-04-19     浏览次数:      字号:    

中国源码网内相关主题链接
  • 使用Antlr和JfreeChart实现项...
  • Antlr的功能在我的其他文章里提到了就不多说了,JFreeChart是一个功能强大的Java开源图表生成组件。

    是不是经常有人问你,你做的项目一共有多少行代码,你编写了多少行代码?

    本文的程序轻松帮你回答这个问题。

    我越来越喜欢用Antlr来完成分析问题,虽然它在性能和简易性方面不如Lex/Yacc相比,那它能很容易的结合到Java项目里。

     

    1 计算文件行数,和空行行数

     

    //----------------------------------------------------------------------------

    // The Colimas source statistics scanner

    //----------------------------------------------------------------------------

    header{

           package org.colimas.src.parser;

    }

    class SourceStatisticsParser extends Parser;

    options {

           k = 2;                                   // two token lookahead

           codeGenMakeSwitchThreshold = 2;  // Some optimizations

           codeGenBitsetTestThreshold = 3;

           defaultErrorHandler = false;             

    }

     

    file :    //遍历文件

        (CODE)+  file  //有文字多行

           | (EMPTY)+ file //无文字多行

           | CODE       //文件最后一样

           | EOF        //文件结束符

           ;

     

          

    class SourceStatisticsLexer extends Lexer;

    options {

           testLiterals=true;                    // test for literals

           k=2;                   // 2 characters of lookahead

           codeGenBitsetTestThreshold=20;

           charVocabulary='\u0003'..'\uFFFF';

    }

    {

           private long codeline=0; //有字符行数

          

           private long emptyline=0; //空行行数

          

           private long totalline=0; //文件行数=有字符行数+空行行数

          

           public long getCodeline(){

                  return this.codeline;

           }

          

           public long getEmptyline(){

                  return this.emptyline;

           }

          

           public long getTotalline(){

                  return this.codeline+this.emptyline;

           }

    }

     

    CHAR_LITERAL

           : ~('\uFFFF' | '\r' |'\n') //结束符,回车符,换行符以外的所有字符

           ;

     

    CHAR  : (CHAR_LITERAL)+; //多个字符

     

    EMPTY

      :   ('\r')? ('\n') // DOS/Windows

          // increment the line count in the scanner

          {

            newline(); //用于调试

            emptyline++;  //空行加1

            $setType(Token.SKIP);

          }

      ;

    CODE :  CHAR  ( (('\r')? ('\n')) |'\uFFFF')

           {     

                  newline();

                  codeline++; }

           ;

    该程序将被Antlr编译生成Java SourceStatisticsLexer类和SourceStatisticsParser

     

    2 保存行数

    遍历指定一个目录内所有文件。

    //递归方法

                  public void passDirectory(File dir){

                                File[] files=dir.listFiles();

                                for(int i=0;i<files.length;i++){

                                              if(files[i].isDirectory()){

                                                            System.out.println(files[i].getAbsolutePath());

                                                            passDirectory(files[i]);

                                              }else{

                                                            //调用LexerParser,得到行数并保存到hash表里。

                                                            setLineStat(files[i]);

                                              }

                                                           

                                }

                               

                  }

    //实例化Lexer分析器

     

                  public void setLineStat(File file){

                                                           

    this.lexer=

                                                                          new SourceStatisticsLexer(in);

                                                            if(!FileExtension.checkAscii(type)){ //如果是文本文件则计算行数,否则跳过

                                                                          files.put(type,stat);

                                                                          return;

                                                            }

                                                            this.lexer.setFilename(file.getName());

    //实例化Parser分析器

     

                                                            this.parser = new SourceStatisticsParser(lexer);

                                                            parser.file(); //遍历分析

     

    //将行数保存到Map

     

                                                            stat.addCodeLines(lexer.getCodeline());                                                                                         stat.addEmptyLines(lexer.getEmptyline());

                                                            files.put(type,stat);

    ///////////////////////////////////////////////////////////////////////////

    计算所有文件的总行数

                                                            directoryCodeLines+=lexer.getCodeline();

                                                            directoryEmptyLines+=lexer.getEmptyline();

                                                            in.close();

                                             

    ////////////////////////////////////////////////////////////////////////////

    这样所有的文件行数将根据文件类型保存在以文件类型为KeyHashMap里。

     

    3 生成饼状图与柱状图

     

    饼状图与柱状图都需要先组织数据集,例如饼状图的数据集

                  /**

                   *<p>create data set </p>

                   * @see org.colimas.src.graph.Chart#createDataset(java.util.Map)

                   */

                  public Dataset createDataset(Map files) {

            // row keys...

            Set keys=files.keySet();

     

            // create the dataset...

            DefaultPieDataset dataset = new DefaultPieDataset();

            Object[] types=(Object[])keys.toArray();

            for(int i=0;i<types.length;i++){

                        FileStat file=(FileStat)files.get(types[i]);

                        try {

                                      String desc=FileExtension.getFileDesc((String)types[i]);

                                      if(desc==null)

                                                    desc="other files";

                                      String type=desc; //获得文件类型的文件描述

                    dataset.setValue(type,file.getFiles());  //文件类型的文件数。

                                              } catch (Exception e) {

                                                            e.printStackTrace();

                                              }

                                             

            }

            return dataset;

                  }

    然后就能生成图表了

                  /**

                   *<p>create chart </p>

                   * @see org.colimas.src.graph.Chart#createChart(org.jfree.data.general.Dataset)

                   */

                  public JFreeChart createChart(Dataset dataset) {

                                JFreeChart chart =null;

                                if (dataset instanceof PieDataset){

                                              chart = ChartFactory.createPieChart(

                              "File Statistics 1",  // chart title

                              (PieDataset)dataset,             // data

                              true,               // include legend

                              true,

                              false

                          );

                          PiePlot plot = (PiePlot) chart.getPlot();

                          plot.setSectionOutlinesVisible(false);

                          plot.setLabelFont(new Font("SansSerif", Font.PLAIN, 12));

                          plot.setNoDataMessage("No data available");

                          plot.setCircular(false);

                          plot.setLabelGap(0.02);

                                }

            return chart;

                  }

     

     

    4 显示

    JFrame的类里显示饼状图

                  /**

         * Creates a panel

         * @return A panel.

         */

        public JPanel createPIEPanel(Map files) {

              PIEChart pie=new PIEChart();

            JFreeChart chart = pie.createChart(pie.createDataset(files));

            return new ChartPanel(chart);

        }

    之后就像其他JPanel一样可以在JFrame里显示。

     

    5 结果:

    源代码可以在Colimas开源项目网站上下载

    :pserver:anonymous@cvs.sourceforge.net:/cvsroot/colimas

    ModuleDocBuild


    编辑 webmaster