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

时间:2017-08-08 19:57:38

标签: c# c streamreader streamwriter

我正在编写一些代替旧C代码的代码。原始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);

目前,原始文件的行是作为字符串读入的,这些字符串是通过流读取器分配的,然后该字符串稍后被写入一个编写器,所以我想迭代并查找包含任何函数的任何字符串将是一个好地方开始,一旦我有这些字符串,我可以以某种方式编辑它们。这就是我到目前为止,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比较陌生,所以如果我没有使用正确的术语,请耐心等待。我认为在“)”结束函数的字符串/行是最有意义的,但我不确定如何做到这一点。 提前谢谢!

1 个答案:

答案 0 :(得分:0)

快速而肮脏的解决方案将是这样的:

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. 正文块在字符串常量中不包含花括号
  4. 如果这些假设不适合您,那么您将需要查看解析器生成器,它将解析C文件并为您生成抽象语法树,您可以从中提取所需信息。一个例子是ANTLR。 C语法也可以在C.g4获得。