【问题标题】:Lex: Avoid a quoted expressionLex:避免引用表达式
【发布时间】:2016-05-04 22:22:54
【问题描述】:

我正在尝试构建一个应该避免引用字符序列的 lex 程序。像 not(":=") 之类的东西。到目前为止,我已经写了这个,但似乎无法获得所需的输出:

/* Definitions */
assgn   ":="
symbol  [^{assgn}]

%%
.
":="    {printf("Found - %s\n",yytext);}
{symbol}  {printf("Error: Unmatched symbol \'%s\'\n", yytext);}
%

输入:

:= & | #

输出:

Found - :=
Error: Unmatched symbol ':' 
Error: Unmatched symbol '='
Error: Unmatched symbol '&'
Error: Unmatched symbol '|'
Error: Unmatched symbol '#'

期望的输出:

Found - :=
Error: Unmatched symbol '&'
Error: Unmatched symbol '|'
Error: Unmatched symbol '#'

我希望程序从整体上避免“:=”,但它仍然读取单个字符“:”。我该如何纠正这个问题?

【问题讨论】:

  • “避免”是什么意思?词法分析器必须匹配当前输入位置的 some 标记。它不搜索令牌。
  • 是的,你是对的。原谅歧义。我的意思是它应该“匹配”表达式并将其吃掉,因为它前面有一个'^'。每当出现“:=”时,它应该吃掉整个表达式,而不是将“:”和“=”识别为不匹配的符号。
  • 我不明白你在这种情况下所说的“吃”是什么意思。如果你想让 flex 识别 ":=" 并且在它看到它时什么都不做(即继续扫描它),那么你只需要使用一个什么都不做的动作(或者干脆忽略这个动作。)如果你的意思是别的,尝试用示例输入解释所需匹配的顺序。 (编辑问题。所需的精度不适合评论,无论如何这不是 cmets 的用途。)
  • 例如,对于输入“:= * & |”,只有'*'、'&'和'|'应该由于“:=”的否定而被打印出来
  • 我无法重现该问题。具有该输入的文件会产生所需的结果。我将删除仅包含 . 的行并将 {symbol} 替换为 . 但对于示例输入,它没有区别。

标签: regex quotes lex


【解决方案1】:

以下完整的 (f)lex 小程序完全符合我们的要求。 flex 不会重新扫描匹配的标记,除非您要求它(或者,当然,您的代码中有一些未定义的行为会破坏 flex 的内部数据结构。)

%{
  #include <stdio.h>
%}
%option nodefault noyywrap noinput nounput
%%

[[:space:]]+    /* Ignore spaces */
":="            {printf("Found - %s\n",yytext);}
.               {printf("Error: Unmatched symbol \'%s\'\n", yytext);}

将上述文件存储在only:=.l 中,我执行以下操作:

$ lex -o only:=.c only:=.l
$ gcc -o only:= -Wall only:=.c -lfl
$ ./only:=
:= & | #
Found - :=
Error: Unmatched symbol '&'
Error: Unmatched symbol '|'
Error: Unmatched symbol '#'

-lfl 添加了main() 的最小定义)

【讨论】:

  • 我已经知道它是一个字符类,因此只会匹配一个字符,这就是发生这种情况的原因。我不知道如何构建一个与字符串匹配的等效表达式,然后我可以否定该字符串。例如 ":=" 是一个匹配的字符串。我想要的是否定这场比赛。
  • @execode,不过,这没有任何意义。您的整个程序是一个不匹配“:=”的字符串。我认为您不想匹配整个输入。那么你真正想要匹配的是什么?
  • 嗯,简单地说,我想要的输出是除了“:=”之外的所有文本输入文件都应该打印。有意义吗?
  • 我有一组需要识别的符号,例如“:=", ">=", "%%" 等。我需要打印除此符号行话之外的任何不匹配符号有。例如。 ":"、"="、"&" 当它们作为单独的实体出现时。但该程序将它们识别为单独的实体,即使它们在一起。在代码中也有这个:“:=” {yylval = NULL; yycolumn = yycolumn + yyleng;返回 (ASSGNnum);}
  • 完成。编辑了问题。
猜你喜欢
  • 1970-01-01
  • 2012-11-28
  • 1970-01-01
  • 1970-01-01
  • 2016-07-17
  • 2021-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多