(f)lex PRINTA $和PRINT A $之间的差

问题描述 投票:0回答:1

我正在解析BASIC:

530 FOR I=1 TO 9:C(I,1)=0:C(I,2)=0:NEXT I

在这种情况下使用的模式是:

FOR  { return TOK_FOR; }
TO   { return TOK_TO; }
NEXT { return TOK_NEXT; }
(many lines later...)
[A-Za-z_@][A-Za-z0-9_]*[\$%\!#]? {
          yylval.s = g_string_new(yytext);
          return IDENTIFIER;
        }
(many lines later...)
[ \t\r\l]   { /* eat non-string whitespace */ }

删除空间时出现问题,这在8k RAM时代很常见。因此,在[[Super Star Trek中实际找到的行是:

530 FORI=1TO9:C(I,1)=0:C(I,2)=0:NEXTI
现在我知道为什么会这样:“ FORI”比“ FOR”长,在我的模式中它是有效的IDENTIFIER,因此它与IDENTIFIER匹配。

MS BASIC中的原始规则是变量名称只能是两个字符,因此没有*,因此匹配将失败。但是此版本还支持GW BASIC和Atari BASIC,这允许使用长名称的变量。因此,“ FORI”是我的扫描仪中的合法变量名称,因此匹配时间最长,因此可以匹配。

现在,当我look at the manual时,唯一的相似示例故意返回错误。看来我需要的是“匹配ID,但仅当它与定义的%token不同时”,是否存在这种情况?

flex-lexer lex
1个回答
0
投票
即使关键字已连接标识符,也很容易识别它们。棘手的是确定应在哪种情况下应用该技术。

这是使用尾随上下文来识别关键字的简单模式:

tail [[:alnum:]]*[$%!#]? %% FOR/{tail} { return TOK_FOR; } TO/{tail} { return TOK_TO; } NEXT/{tail} { return TOK_NEXT; } /* etc. */ [[:alpha:]]{tail} { /* Handle an ID */ }

有效地,这只是扩展了关键字匹配而没有扩展匹配的标记。

但是我怀疑问题是否如此简单。例如,应该如何标记FORFORTO

© www.soinside.com 2019 - 2024. All rights reserved.