正则表达式模式匹配switch语句C ++

时间:2015-01-28 05:32:28

标签: c++ regex

我正在尝试编写一个在bash脚本中使用的正则表达式模式,该脚本检查switch语句(C ++)的语法。

我想要遵循的switch语句的语法如下:

switch(expression)
{
   case constant-expression:
       statement(s);
       break; // must be present
   case constant-expression:
       statement(s);
       break; // must be present

   ....
   ....

   default :  // must be present
       statement(s);
       break; // must be present
}

请注意,即使breakdefault声明不是必须的,我也希望检查它们的存在。

我写了这个正则表达式模式来匹配开关块。

switch(.*?)\n(\s)*?{(\n(.*?))*?(\n(\s)*case(.*?):?(\n(.*?))*?break;)+(\n(.*?))*?\n(\s)*(default:)?(\n(\s)*)*(break|return(.*?))?;(\n(\s)*(.*?))*}

它成功匹配了切换块,但问题是它匹配switch,即使缺少break和default语句。我尝试将+运算符与breakdefault字词一起使用,但它们似乎无效。

编辑更新:

是否可以使用解析器匹配开关块,例如以下开关块?

switch (PC_INT[address.port][address.pin]) 
    {
    #if defined (__AVR_ATmega2560__) || defined(__AVR_AT90CAN128__)
        case EINT_0:
            // Mask the interrupt so it doesn't fire anymore, i.e put a zero in the mask register.
            EIMSK &= ~(1 << INT0);
            break;
        case EINT_1:
            EIMSK &= ~(1 << INT1);
            break;
            ....
        default:
            return GPIO_INT_OUT_OF_RANGE;

    #elif defined(__AVR_ATmega64M1__) || defined(__AVR_ATmega64C1__)
        case EINT_0:
            // Mask the interrupt so it doesn't fire anymore, i.e put a zero in the mask register.
            EIMSK &= ~(1 << INT0);
            break;
        case EINT_1:
            EIMSK &= ~(1 << INT1);
            break;
            ....    
        default:
            return GPIO_INT_OUT_OF_RANGE;
    #else
        #error "GPIO interrupts not implemented for this configuration."
    #endif
    }

1 个答案:

答案 0 :(得分:4)

非贪婪的模式(如.*?)并不神奇。

您显然希望.*?中的(\<case:.*?\<break;\s*)+(正则表达式的简化形式)与case:不匹配。为什么不呢?换句话说,文字:

case 1:
  do_something();
case 2:
  do_something_else();
  break;

肯定匹配case.*?break;; .*?匹配1: do_something(); case 2: do_something_else();

.*?也不是围栏。如果case.*?break(more)与第一个break后面的文字不匹配,但与case之后的文字相符,则(more)可能与break之后的第一个default:不匹配第二个。

至于(default:)? 显然是可选的,这正是你的正则表达式所说的:

flex

我不认为正则表达式是可以挽救的。你不能用正则表达式解析C或C ++。

您确实需要使用更好的解析基础架构。您可以使用bisonlibclang构建一个简单的解析器,它可以用于不与预处理器一起玩游戏的源代码,但您可能最好使用真正的C ++解析库,例如{{ 1}}。