1

如何使用 awk 解析如下 switch-case 语句?我想用 awk 创建简单的 C 语法检查器。该检查器必须读取代码并返回是否存在语法错误。如果有,awk 应该在上面打印什么错误。

switch(number)
{
    case 1  : number = 'a'; break;
    case 2  : number = 'b'; break;
    default : number = 'x'; 
}

对于for()语句,如下所示:

for(i=0;i<10;i++) 
    {
        number = 'A';
    }

我当前的switch-case语句代码是:

#parser_switchcase.awk
{
for(i=1; i<=NF; i++)
{
  if($i~/switch\([[:alnum:]]+\)/)
    print("switch(VALID_VARIABLE)")
}

}

上面我的第一个 C switch-case代码的结果:

master@master:~/Dokumen/Root$ awk -f parser_switchcase.awk soalswitch 
switch(VALID_VARIABLE)

但实际上它需要很多改进。它不完整。

我需要 awk 建议来阅读和检查我上面输入的代码示例。没错,所以我只需要 awk 解析这些代码,而不是附加功能、附加代码等外部可能性,只需要上面代码中提到的内容。

4

2 回答 2

1

使用 awk 进行 C 语法检查是一个勇敢的项目。

我将gcc用于语法检查。尝试这个:

gcc -fsyntax-only test.c
于 2013-07-17T15:52:51.460 回答
1

正如其他人所建议的那样,awk这不是这项工作的正确工具......
但是如果您可以保证您的代码符合相当严格和精确的结构,例如问题中提出的结构,您可以编写一个非常基本的awk解释器它。

例如:

BEGIN {
  ERROR = "ERROR: ";
  WARNING = "WARNING: ";
}

# Start of switch statment
/switch/ { 
  # Cursory check for valid variable name: must start with a letter or underscore,
  # and be composed of alphanumeric characters or underscores.
  if ($0 !~ /switch\([A-Za-z_]+[A-Za-z0-9_]*\)/)
    print ERROR "switch statement '" $0 "' has a syntax error.";

  switch_stmnt = 1;
  next;
}

# Start of for statement
/for/ {
  # For loop can have lots of various stuff between parentheses, so hard to check.
  # But, if you know it will always be `(i=0;i<10;i++)`, then it's much easier to 
  # create a rule.
  if ($0 !~ /for\(.*;.*;.*\)/)
    print ERROR "for statement '" $0 "' has a syntax error.";

  for_stmnt = 1;
  next;
}

# Start of case statement
/case/ { 
  # Check if in switch
  if (! switch_stmnt)
    print ERROR "case statement '" $0 "' outside of switch statement.";

  # Already in a case statement
  if (case_stmnt)
    print WARNING "case statement fall-through.";

  # Check syntax
  if ($2 !~ /[A-Za-z0-9_]+/ || $3 != ":")
    print ERROR "case statement '" $0 "' has a syntax error.";

  case_stmnt = 1;
}

# Default
/default/ {
  # Check if in switch
  if (! switch_stmnt)
    print ERROR "default statement '" $0 "' outside of switch statement.";

  # Already in a case statement
  if (case_stmnt)
    print WARNING "case statement fall-through.";
}

# Break
/break;/ {
  if (case_stmnt) { case_stmnt = 0; }
  else if (for_stmnt) { }
  else { print ERROR "'break' outside of case statement or for loop."; }
}

# Start of control structure
/{/ { ++brace; }

# End of control structure
/}/ {
  if (switch_stmnt) {
    switch_stmnt = 0;
    case_stmnt = 0;
  }
  else if (for_stmnt)
    for_stmnt = 0;

  if (brace == 0)
    print ERROR "Extra closing brace '}' with no matching open brace.";

  --brace;
}

{
  # Do syntax checking on regular lines, eg. "number = 'a';"
  next;
}

END {
  if (switch_stmnt || for_stmnt || brace)
    print ERROR "Unterminated for or switch statement at end of file.";
}

这会检查一些语句是否符合一些规则。您可以使用更多的正则表达式规则和标志来扩展它。特别困难的是没有关键字的普通语句,因为这些可能是声明、赋值、函数调用等。但是,如果你只进行number = 'a';上述的赋值,那么匹配这些行也不太难(比如/[A-Za-z_]+[A-Za-z0-9_]* = '.'/

于 2014-06-02T05:38:05.713 回答