强制CL-Lex阅读整个单词

时间:2012-03-28 04:01:28

标签: lisp lexer

我正在使用CL-Lex来实现词法分析器(作为CL-YACC的输入),我的语言有几个关键词,如“let”和“in”。然而,虽然词法分析器识别出这样的关键词,但它确实太多了。当它找到诸如“init”之类的单词时,它将第一个标记返回为IN,而它应该为“init”字返回一个“CONST”标记。

这是词法分析器的简单版本:

(define-string-lexer lexer
     (...)
     ("in"   (return (values :in $@)))
     ("[a-z]([a-z]|[A-Z]|\_)"  (return (values :const $@))))

如何强制词法分析器完全读取整个单词,直到出现一些空格?

2 个答案:

答案 0 :(得分:8)

这既是对Kaz的错误的纠正,也是对OP的信任投票。

在他最初的回答中,Kaz说明了Unix lex优先顺序完全落后。来自lex文档:

  

Lex可以处理模棱两可的规范。当多个表达式可以   匹配当前输入,Lex选择如下:

     
      
  1. 最长匹配是首选。

  2.   
  3. 在符合相同数量字符的规则中,给出了规则   首先是首选。

  4.   

此外,Kaz批评OP使用Perl-regex字边界匹配的解决方案是错误的。碰巧的是,你被允许(没有折磨内疚)来匹配词法生成器支持的任何方式的单词。 CL-LEX使用Perl正则表达式,它使用\b作为方便的语法来处理更加繁琐的lex近似值:

%{
#include <stdio.h>
%}

WC      [A-Za-z']
NW      [^A-Za-z']

%start      INW NIW

{WC}  { BEGIN INW; REJECT; }
{NW}  { BEGIN NIW; REJECT; }

<INW>a { printf("'a' in wordn"); }
<NIW>a { printf("'a' not in wordn"); }

在所有条件相同的情况下,找到一种明确匹配他的话的方法可能比替代方案更好。

尽管Kaz想要打他,但OP正确地回答了他自己的问题,提出了一个利用他选择的词法分析器灵活性的解决方案。

答案 1 :(得分:1)

上面的示例词法分析器有两个规则,两个规则都匹配正好两个字符的序列。而且,它们有共同的匹配(第二种匹配的语言是第一种的严格超集)。

在经典的Unix lex中,如果两个规则都匹配相同的输入长度,则优先级将在规范中首先出现。否则,最长的匹配将占主导地位。

(虽然没有RTFM,但我不能说这就是CL-LEX中发生的事情,它确实对这种情况下发生的事情做出了合理的假设。)

看起来你缺少一个正则表达式Kleene运算符来匹配第二个规则中的较长令牌。