2011-04-26 6 views
6

나는 Appel의 "Modern Compiler Implementation in ML"을 따르고 있으며 Ocamllex를 사용하여 렉서를 작성하려고합니다.문자열을 렉싱하기 위해 Ocamllex 사용하기 (The Tiger Compiler)

사양은 이스케이프 시퀀스 변환 후 렉서가 문자열을 반환하도록 요청합니다.

rule tiger = parse 
... 
| '"' 
    { let buffer = Buffer.create 1 in 
     STRING (stringl buffer lexbuf) 
    } 
and stringl buffer = parse 
| '"' { Buffer.contents buffer } 
| "\\t" { Buffer.add_char buffer '\t'; stringl buffer lexbuf } 
| "\\n" { Buffer.add_char buffer '\n'; stringl buffer lexbuf } 
| "\\n" { Buffer.add_char buffer '\n'; stringl buffer lexbuf } 
| '\\' '"' { Buffer.add_char buffer '"'; stringl buffer lexbuf } 
| '\\' '\\' { Buffer.add_char buffer '\\'; stringl buffer lexbuf } 
| eof { raise End_of_file } 
| _ as char { Buffer.add_char buffer char; stringl buffer lexbuf } 

더 나은 방법이 있나요 : 다음 코드는 ocamllex 입력 파일에서 발췌 한 것입니다?

답변

5

Ocaml lexer이 어떻게 수행되는지 살펴볼 수 있습니다 (and string 검색). 본질적으로 좋은 로컬 버퍼가 없으면 (이 시점에서 코드를 좀 더 멋지게 만들지 만 조금 덜 효율적입니다.) 더 많은 이스케이프가 지원되므로 좀 더 복잡하고 이스케이프 테이블 (char_for_backslash)를 사용하여 유사한 규칙을 인수 분해합니다.

또한 "\\n"을 두 번 반복했으며, 1은 문자열 길이를 매우 비관적으로 추정 한 것으로 여기서는 불필요한 크기 조정을 피하기 위해 20을 사용하고 싶습니다.

+0

고마워요! 예제의 금광. 나는 Ocaml 컴파일러 코드가 그렇게 명확하지 않다고 생각하지 않았다. – nimrodm

+1

@nimrodm 여러분은 또한 거기에있는 코드 중 일부는 꽤 오래된 것이므로 모든 것이 OCaml 개발의 현재 모범 사례를 반영하지는 않는다는 것을 명심해야합니다. – gasche