【发布时间】:2020-04-11 18:40:31
【问题描述】:
我正在尝试制作一个编译器,其中 lex 文件匹配以下 printf 和 scanf 语句的简单变体:
printf("\n Enter your string:");
scanf("%s",str);
scanf("%d",&prelength);
在 scanf 示例中,str 被声明为 char str[20],prelength 被声明为 int prelength。
我当前包含在我的 lex 文件中的正则表达式如下(分别用于 scanf 和 printf):
scanf\(\"([\w\W]*(%[d|c|f|lf|s])*)+\"(,\s*&?[a-zA-Z]+)*\);
printf\(\"([\w\W]*(%[d|c|f|lf|s])*)+\"(,\s*[a-zA-Z]+)*\);
我不知道为什么上面的正则表达式与上面给出的 printf 和 scanf 示例不匹配(类似于 c 中的那些,但更简单)。
【问题讨论】:
-
你的目标是什么?创建令牌供解析器使用?在没有解析器的情况下查找
scanf和printf的所有调用?还有什么?无论哪种情况,您确定在单个正则表达式中匹配整个函数调用是实现目标的最佳方式吗? -
@sepp2k ,目标的一部分是创建供解析器使用的令牌,是的。最终目标是检查格式说明符指示的类型是否与传递的变量的实际类型匹配(通过查找我已经实现的符号表)。也许我是从无知的角度说的,但我确实认为匹配整个功能应该满足我的要求。
-
你真的不应该这样写你的解析器。使用更简单的标记进行标记,例如“scanf”和“printf”,将括号作为单独的标记传递,将字符串作为单独的标记传递。
-
@adi 如果您将整个调用匹配为一个标记,那么您问题中输入的标记化将仅包含三个标记:一个用于 printf,两个用于 scanf。解析器所能做的就是将这三个标记放入一个列表中。然后,您将拥有一个仅包含三个没有嵌套结构的标记的语法树。为了对此进行任何类型的分析,您必须访问标记的文本,将其拆开并确定其结构,因为显然仅该标记序列还不足以提供足够的信息。 ...
-
... 换句话说,在您应该已经执行了这些步骤之后,您必须添加另一道标记化和解析。所以最初的标记化和解析步骤基本上是徒劳的。您真正想要的是可以解析成树的标记序列,您至少可以在其中访问被调用函数的各个参数。
标签: c regex compiler-construction yacc lex