1

目前我正在尝试用 Ocaml 编写一个解释器,这是我的 lexer.mll:

{

    open Parser
    exception Eof
}


rule main = parse
      [ ' ' '\t' ]  { main lexbuf } 
    | [ '\n' ]  { EOL } 
    | ['0'-'9']+ as lxm { LINE_NUMBER(int_of_string lxm) }
    | [^\\]*\.(\w+)$  as lxm { FILE_NAME lxm }
    | "get_line"    { GET_LINE }    
    (*| [ ^-?\b([0-9]{1,3}|1[0-9]{3}|20[0-4][0-9]|205[0-5])\b ]     { RANGE }   (* -2055 < RANGE < 2055 *)*)
    | eof   { raise Eof }

我真的很困惑为什么 ocamllex 在 { FILE_NAME lxm } 行给我一个错误。如果我放在#load "str.cma"词法分析器的开头,它会在该行打印出错误语法错误。

为什么?我很困惑...

编辑

应该[ [^\\]*\.(\w+)$ ] as lxm { FILE_NAME lxm }

但是问题还是没有解决...

4

1 回答 1

2

您的正则表达式中有很多部分无法识别:

  • \\:把它放在单引号之间以匹配“\”字符;
  • \.:只需将点放在单引号之间以匹配点,
  • \w: ocamllex 似乎不知道这个转义序列,你需要定义你的,
  • $: 定义你的行尾。

所以首先,把它放在词法规则之前:

let w = ['a'-'z' 'A'-'Z' '0'-'9' '_']
let eol = '\n' | "\r\n"

然后,将您的规则更改为

[^'\\' '\n']*'.'w+eol

匹配的表达式 ( lxm) 将包含行结束序列 ( '\n' 或"\r\n"),因此您需要将其删除。

当你尝试匹配一个字符串直到行尾时要小心,因为默认行为是匹配最长的字符串,所以如果你的正则表达式接受行尾,它一次可以匹配多行。这就是我禁止'\n'的原因。

于 2014-03-19T16:00:20.640 回答