0

我在用 ocaml 编译我的词法分析器时收到警告:

File "lexer.mll", line 42, characters 26-57:
Warning 10: this expression should have type unit.

我想解析字符串,我制定了一个特殊的规则,当词法分析器读取一个引号时开始,当我读取另一个引号时结束,在这种情况下返回字符串并为每个其他字符调用规则标记。

这是文件:

{
    open Int32
    open Lexing
    open Parser

    exception LexicalError of string * Lexing.position * Lexing.position

    let string = Buffer.create 50

    let error s lexbuf =
       raise (LexicalError(s, Lexing.lexeme_start_p lexbuf, Lexing.lexeme_end_p lexbuf))


    let kwords = [ "boolean", BOOLEAN; "class", CLASS; "else", ELSE;
                   "extends", EXTENDS; "for", FOR; "if", IF; "instanceof",
                   INSTANCEOF; "int", INT; "new", NEW; "null", NULL;  "public",
                   PUBLIC; "return", RETURN; "static", STATIC; "this", THIS;
                   "void", VOID; "String", STRING; ]

    let ident_or_kword s = 
       try
          List.assoc s kwords
       with
          Not_found -> IDENT(s)
}

let blank = [' ' '\t' '\n']+
let digit = ['0'-'9']
let alpha = ['a'-'z''A'-'Z']
let ident = ((alpha | '_')(alpha | '_' | digit)*)
let car   = [' '-'~']
let end_quote = '"'

rule comment = parse
| "*/"                  { token lexbuf }
| eof                   { error "End Of File" lexbuf }
| _                     { comment lexbuf } 

and chaine = parse
| end_quote             { CSTRING(Buffer.contents string); token lexbuf }
| car as c              { Buffer.add_char string c; token lexbuf }
| eof                   { error "End Of File" lexbuf }
| _ as c                { error (String.make 1 c) lexbuf }

and token = parse
| blank                 { token lexbuf }
| "/*"                  { comment lexbuf }
| ident as id           { ident_or_kword id }
| '"'                   { chaine lexbuf }
| '.'                   { MEMBER }
| '='                   { ASSIGN }
| "=="                  { EQ }
| "!="                  { DIFF }
| '<'                   { LESS }
| "<="                  { LESS_EQ }
| '>'                   { GREATER }
| ">="                  { GREATER_EQ }
| "++"                  { PLUS_PLUS }
| '+'                   { PLUS }
| "--"                  { MINUS_MINUS }
| '-'                   { MINUS }
| '*'                   { TIMES }
| '/'                   { DIV }
| '%'                   { MOD }
| "&&"                  { AND }
| "||"                  { OR }
| '!'                   { BANG }
| '('                   { LP }
| ')'                   { RP }
| '{'                   { LB }
| '}'                   { RB }
| '['                   { LC }
| ']'                   { RC }
| ';'                   { SC }
| ','                   { COMMA }
| "true|false" as bool  { CBOOL(bool_of_string bool) }
| digit+ as int         {
             try
                 CINT(of_string int)
             with
                 _ -> error int lexbuf }
| eof                   { EOF }
| _ as c                { error (String.make 1 c) lexbuf }
4

1 回答 1

1

我无法尝试您的代码,因为我没有您的 Parser 模块。

在我看来你需要这个:

| end_quote             { CSTRING(Buffer.contents string) }

在您的代码中,编译器抱怨此表达式不是 type unit。实际上它的值是一个令牌,这是你想要返回的。我很确定,此时无需调用扫描仪。你已经有了你的令牌。

于 2013-10-04T17:04:03.353 回答