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

パーサー モジュールがないため、コードを試すことができません。

あなたがこれを持っている必要があるように私には見えます:

| end_quote             { CSTRING(Buffer.contents string) }

あなたのコードでは、コンパイラはこの式が type ではないことを訴えていunitます。実際、その値はトークンであり、これが返したいものです。この時点でスキャナーを呼び出す必要はありません。あなたはすでにトークンを持っています。

于 2013-10-04T17:04:03.353 に答える