简体   繁体   English

如何在 AWK 中解析 C switch-case 和 for Statement?

[英]How can I parse C switch-case and for Statement in AWK?

How to parse switch-case statement like below with awk?如何使用 awk 解析如下所示的 switch-case 语句? I want to create simple C syntax checker with awk.我想用 awk 创建简单的 C 语法检查器。 This checker must read the code and return whether there is syntax error or not.该检查器必须读取代码并返回是否存在语法错误。 If there is, awk should print what error on it.如果有,awk 应该在上面打印出什么错误。

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

And for for() statement, like this:对于for()语句,如下所示:

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

My current code for switch-case statement was:我当前的switch-case语句代码是:

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

}

result for my first C switch-case code above:上面我的第一个 C switch-case代码的结果:

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

but really it needs many improvements.但实际上它需要很多改进。 It is not complete.它并不完整。

I need awk suggestion just for reading and checking exactly code examples I have typed above.我需要 awk 建议只是为了阅读和检查我上面输入的代码示例。 Exactly, so I just need awk parsing code for those, not the outside possibility such as additional function, additional code, only what mentioned on the codes above.没错,所以我只需要 awk 解析这些代码,而不是外部可能性,例如附加功能、附加代码,只需要上面代码中提到的内容。

Using awk for C syntax checks is a brave project.使用 awk 进行 C 语法检查是一个勇敢的项目。 Have fun!玩得开心!

I would use gcc for syntax checks.Try this:我会使用gcc进行语法检查。试试这个:

gcc -fsyntax-only test.c

As others have suggested, awk is not the right tool for this job...正如其他人所建议的那样, awk不是这项工作的正确工具......
But if you can guarantee that your code conforms to a fairly rigid and exact structure, such as the one presented in the question, you could write a very basic awk interpreter for it.但是如果你能保证你的代码符合一个相当严格和精确的结构,比如问题中提出的结构,你可以为它编写一个非常基本的awk解释器。

For example:例如:

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.";
}

This checks that a few statements conform to a few rules.这会检查一些语句是否符合一些规则。 You can expand this with a lot more regex rules and flags.您可以使用更多正则表达式规则和标志来扩展它。 Especially difficult would be plain statements without keywords, since these could be declarations, assignments, function calls, etc. BUT, if you will only be making assignments such as number = 'a';没有关键字的普通语句尤其困难,因为它们可能是声明、赋值、函数调用等。但是,如果您只进行诸如number = 'a';赋值number = 'a'; as above, then it's also not too hard to match these lines (something like /[A-Za-z_]+[A-Za-z0-9_]* = '.'/ )如上所述,那么匹配这些行也不难(类似于/[A-Za-z_]+[A-Za-z0-9_]* = '.'/

Mix if before switch conditional.混合 if 在 switch 条件之前。

# ----------------------------------------------

A=strtonum(ARGV[2]);

 if (A >=  0 && A<  10 ) T=1;
 if (A >= 11 && A<  20 ) T=2;
 if (A >= 21                   ) T=3;

switch (T) {
     case 1: print "1\n"
                   break
     case 2: print "2\n"
                   break
     case 3: print "3\n"
                   break
    default: print "0\n"
                   break
   }
# --------------------------------

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM