怎么写啊,  各位大侠帮下忙啊。。思路也行,代码就更好。

解决方案 »

  1.   

    要写怎样的正则?考虑到要计算大括号还有if,while,swich等,感觉好复杂啊,想了好久都不行
      

  2.   

    额,那就奇怪了,你为什么说:
    考虑到要计算大括号还有if,while,swich等,感觉好复杂啊,想了好久都不行?
      

  3.   

    失败,实在是太失败啊,十五分钟变成了一个多小时,唉
    下面代码经过两次测试,一次是课程实验时写的一个程序,有31个函数,测试与实际相符import java.io.*;
    import java.util.*;
    import java.util.regex.*;
    /**
     * 2011-7-3 0:41:37
     * @author Administrator
     */
    public class Test {
        public Test(String filePath){
            try{
                FileInputStream fis=new FileInputStream(filePath);
                byte b[]=new byte[1024];
                ByteArrayOutputStream bos=new ByteArrayOutputStream();
                while(fis.available()>0){
                    int num=fis.read(b);
                    bos.write(b, 0, num);
                }
                String code=new String(bos.toByteArray());
                //说明一下这里使用StringTokenizer而不用Scanner的原因
                //我想把形如int prime(int a,int b)这种函数头在读取时分开成如下字符串(各字符串以空格间隔)
                // int prime ( int a , int b )
                //这样在以后的判断中比较方便。在这里,"("作为分隔符,但是读取时得读取进来,我想了一会儿,Scanner
                //好像是不能返回读取到时的分隔符的,所以改用了StringTokenizer
                String delimeter=new String("(),{}\t\r\n* ");
                //说明一下,对于*,这个东西是比较烦的,定义的时候有下面三种情况
                // int *p
                // int* p
                // int * p
                //这样在检查函数的参数表时,是比较麻烦的。所以在这里,直接将*忽略,这样并不影响参数表的
                //结构。
                StringTokenizer st=new StringTokenizer(code,delimeter,true);
                ArrayList<String> list=new ArrayList<String>();
                while(st.hasMoreTokens()){
                    String s=st.nextToken();
                    if(!s.matches("[\\s\\*]+")){
                        list.add(s);
                    }
                }            
                String namePattern=new String("[_a-zA-Z]\\w*");
                int functionNumber=0;
                for(int i=0;i<list.size();i++){
                    String text=list.get(i);
                    //看看是否是左括号
                    if(text.equals("(")){
                        //检查其上一个字符串是否符合函数名规则
                        if(i==0){
                            continue;
                        }
                        String funName=list.get(i-1);
                        if(!funName.matches(namePattern)){
                            continue;
                        }
                        //现在可以说明括号的左边符合函数名的规则了,(说明一下,如VC6.0的C语言中一个
                        //函数的函数头,不一定要定义返回值类型的,所以这里检查过括号左边的函数名后没有
                        //检查是否有返回值类型的定义。现在看括号右边的情况,形如 if(a>b)这种情况,其
                        //括号左边是符合函数名规则的
                        //按参数表规则检查,如果遇到一个类型定义,就应该接一个变量名(这里是检查函数的定义,
                        //不是函数申明,所以类型名后面的变量名不能省略),再接一个逗号或者是右括号
                        //第一步,如果右边直接是右括号,直接通过
                        //如果不是,检查参数格式
                        int rightPosition=0;
                        if(i>=list.size()-1){
                            continue;
                        }
                        if(!list.get(i+1).equals(")")){
                            boolean success=false;
                            for(int j=i+1;j+2<list.size();j+=3){
                                //三个字符串依次为:变量类型 变量名 逗号或者右括号
                                if(!list.get(j).matches(namePattern)||!list.get(j+1).matches(namePattern)){
                                    break;
                                }
                                String para3=list.get(j+2);
                                if(para3.equals(",")){
                                    continue;
                                }
                                else if(para3.equals(")")){
                                    success=true;
                                    rightPosition=j+2;
                                    break;
                                }
                                else{
                                    break;
                                }
                            }
                            if(!success){
                                continue;
                            }
                        }
                        else{
                            rightPosition=i+1;
                        }
                        //现在函数头是没问题了,可是要检查一下有没有函数体,因为不能将函数提前申明
                        //也算进去。判断方法很简单,rightPosition记住了右括号的位置,现在检查下一字符串
                        //是不是{
                        if(list.get(rightPosition+1).equals("{")){
                            //如果是的,现在是没有问题了
                            functionNumber++;
                            //但是我们做一些小小的优化,其实其他可以优化的地方也很多
                            //这里的优化是,既然现在成功了,那么下次再检查的时候,就应该从这个函数的后面开始
                            //检查,而不是从这个函数头的第二个字符串后面检查,所以,现在做一个跳跃
                            //跳跃的方法是找到"}",当然,在函数体中可能出现N个"}",而我们要找的是与函数头的"{"
                            //所对应的"}"
                            int leftNum=0;
                            for(int j=rightPosition+2;j<list.size();j++){
                                String s=list.get(j);
                                if(s.equals("{")){
                                    leftNum++;
                                }
                                else if(s.equals("}")){
                                    if(leftNum==0){
                                        //找到匹配的了
                                        i=j;
                                        break;
                                    }
                                    else{
                                        leftNum--;
                                    }
                                }
                                //说明一下,如果直到跳循环还没找到,那就蛋疼了,说明这个
                                //程序有问题。这个计算程序是针对没问题的程序写的,对于有
                                //问题的程序,哈哈,我没考虑
                            }
                        }
                        else{
                            continue;
                        }
                    }
                }
                System.out.println("函数个数:"+functionNumber);
            }catch(Exception e){
                
            }
        }
        public static void main(String args[]){
            new Test("test.c");
        }
    }
      

  4.   

    0. 把文件读入内存
    1. 把文件中的注意去掉
    3. 根据函数的特点有返回值,名字,(), {},使用正则表达式来进行搜索
    [\\w]+\\s+\\w+(\\.+)\\s+\\{\\.+\\}
    注意\\.+这里要处理贪婪的问题,这个去查一下相关文档