从文件中修剪一个函数,以便只剩下的字符是函数名和参数

问题描述:

我正在编写一些代码来替换旧的C exe。原始的c文件会读取一个文件,然后修剪内容并将它们放入两个新文件,一个.c和一个.h文件。我正在做同样的事情,但在C#中。除了如何修剪一个函数,只有函数名和参数被放入.h文件,我已经找到了一切。 这是两个的功能的示例:从文件中修剪一个函数,以便只剩下的字符是函数名和参数

void 
M_SCP_Msg_ClearNVMemory(
    Marshal_dataFunc* _argDataFunc_, Marshal_dataFuncArg _argDataFuncArg_, void const* _argSrc_) 
{ 
    SCP_Msg_ClearNVMemory const* _src_ = (SCP_Msg_ClearNVMemory const*)_argSrc_; 

M_uint8_t(_argDataFunc_, _argDataFuncArg_, &_src_->operation); 

} 

void 
MA_SCP_Msg_ClearNVMemory(
    Marshal_dataFunc* argDataFunc, Marshal_dataFuncArg argDataFuncArg, 
    void const* argSrc, unsigned argNSrcElem) 
{ 

SCP_Msg_ClearNVMemory const* src = (SCP_Msg_ClearNVMemory const*)argSrc; 

for (; argNSrcElem > 0; --argNSrcElem) 
{ 
    M_SCP_Msg_ClearNVMemory(argDataFunc, argDataFuncArg, src++); 
} 
} 

这将是所期望的输出:

extern void M_SCP_Msg_ClearNVMemory(
    Marshal_dataFunc* argDataFunc, Marshal_dataFuncArg argDataFuncArg, void const* argSrc); 

extern void MA_SCP_Msg_ClearNVMemory(
    Marshal_dataFunc* argDataFunc, Marshal_dataFuncArg argDataFuncArg, 
    void const* argSrc, unsigned argNSrcElem); 

目前,原始文件的线被读入作为其通过分配串streamreader,然后这个字符串被写入到一个streamwriter,所以我想迭代通过,并找到任何包含任何函数的字符串将是一个很好的开始,一旦我有这些字符串,我可以以某种方式编辑它们。这是我到目前为止,finList是字符串和fin的列表,我将写入输出文件的字符串。

List<string> finList = new List<string>(); 
finList.AddRange(fin.Split('\n')); 
    for (int x = 0; x < finList.Count; x++) 
     { 
      if (finList[x] == "void" || finList[x] == "_Bool" || finList[x] == "bool" || finList[x] == "unsigned") 
       { 
        finList[x] = im not sure what to do here 
        fin = string.Empty; 
       } 
     } 

     for (int x = 0; x < finList.Count; x++) 
     { 
      fin += finList[x]; 
     } 

任何方向或帮助将不胜感激。我对C#和C相对来说比较新,所以如果我没有使用正确的术语,请耐心等待。我认为在“)”结束函数的字符串/行是最有意义的,但我不确定如何做到这一点。 在此先感谢!

+0

如果您想要一个强大的解决方案,您必须编写一个C语法分析器并提取所有函数定义。即使您修复了代码中的错误,它也会在注释掉的函数上失败,然后在所有其他类型的角落中失败。你需要用C#编写吗?使用脚本语言!他们是为此而制造的。 –

+0

我同意,编写脚本似乎是一个更简单的解决方案,但该项目需要C#,它应该是一种学习如何将C转换为C#的方法。但感谢您的意见。我甚至没有想过评论的问题。 – John

+0

而且你可能忘记了引用的字符串,并且对代码的格式做出了无效的假设。你想解析C代码,并且需要C代码解析器,无论你使用哪种语言,这些解析器都需要数千行代码。你的问题的答案是:为C语言获取语法和词法分析器文件并生成一个编译器!其他一切只是非法假设的破解。 –

快速和肮脏的解决办法是这样的:

int bracketLevel = 0; 
int squareBracketLevel = 0; 
var methods = new List<string>(); 
var isMethodMode = true; // track if we are in method definition or in method body 
var isMethod = false; // if we have seen parenthesis in definition 
var builder = new StringBuilder(); 

for (int i = 0; i < fin.Length; i++) 
{ 
    if (isMethodMode) 
    { 
     switch (fin[i]) 
     { 
      case '(': 
       isMethod = true; 
       builder.Append(fin[i]); 
       bracketLevel++; 
       break; 
      case ')': 
       builder.Append(fin[i]); 
       bracketLevel--; 
       break; 
      case '{': 
       if (bracketLevel > 0) continue; 
       if (isMethod) 
       { 
        methods.Add(builder.ToString().Trim()); 
        builder.Clear(); 
        isMethod = false; 
       } 
       isMethodMode = false; 
       squareBracketLevel++; 
       break; 
      default: 
       builder.Append(fin[i]); 
       break; 
     } 
    } 
    else 
    { 
     switch (fin[i]) 
     { 
      case '{': 
       squareBracketLevel++; 
       break; 
      case '}': 
       squareBracketLevel--; 
       if (squareBracketLevel == 0) 
       { 
        isMethodMode = true; 
       } 
       break; 
     } 
    } 
} 

可变fin包含加载C文件。尽管这适用于你的例子有几个假设:

  1. C代码是有效的(无错配的括号)
  2. 其中将包括括号(这包括注释功能在评论中已经提到)没有评论
  3. 体块不包含字符串花括号常量

如果这些假设不成立的,那么你将不得不看看到解析器生成将解析C文件,并生成抽象语法树为你从中你可以提取所需的信息。一个例子是ANTLR。 C语法也可在C.g4