2014-08-29 5 views
0

저는 간단한 계산을 파싱하여 lexing과 parsing (F # toolset 기반)에 대해 배우고 있습니다. lexer가 전체 문자열을 소비하지 않고 있다는 점에서 갇혀 있습니다.fslex learning : Lexer advanceing

let lexeme = LexBuffer<_>.LexemeString 
// ... 
rule test = parse 
    | digit+ { Console.WriteLine("1_" + (lexeme lexbuf)); test lexbuf; } 
    | '+'  { Console.WriteLine("2_" + (lexeme lexbuf)); test lexbuf; } 
    | '-'  { Console.WriteLine("3_" + (lexeme lexbuf)); test lexbuf; } 
    | '*'  { Console.WriteLine("4_" + (lexeme lexbuf)); test lexbuf; } 
    | '/'  { Console.WriteLine("5_" + (lexeme lexbuf)); test lexbuf; } 
    | '('  { Console.WriteLine("6_" + (lexeme lexbuf)); test lexbuf; } 
    | ')'  { Console.WriteLine("7_" + (lexeme lexbuf)); test lexbuf; } 
    | eof  {() } 

여기에 예 최종 'test lexbuf'은 필자가 제공하는 전체 문자열이 소비되도록 보장하기 위해 필자에게 필 요하다.

이후 실제 구현에서는 그렇게하지 않았다. 예. 첫 번째 숫자는 모두입니다.

rule calculator = parse 
    | digit+ { NUMBER (Convert.ToInt32(lexeme lexbuf)) } 
    | '+'  { PLUS } 
    | '-'  { MINUS } 
    | '*'  { TIMES } 
    | '/'  { DIV } 
    | '('  { LPAREN } 
    | ')'  { RPAREN } 
    | eof  { EOF } 

나는 꽤 유사한 구조로 많은 예제를 보았다. 나는 무엇이 없는가.

답변

0

문제는 단순히 자체 사전에 렉서에서 기대할 수없는 것이 었습니다. 나에게 스트림으로 생각하면 무슨 일이 일어나는지 이해하는 데 도움이됩니다.

전진은 파서와 함께 작동합니다. 파서는 렉서에게 토큰 반환을 계속 요청할 것입니다.

0

공백 및/또는 개행 문자가 텍스트 입력에있을 가능성이 높습니다. 따라서이를 처리하기위한 규칙이 필요합니다 (예 : 토큰을 만드는 대신 lexbuf를 전진시켜 버림). 같은 뭔가 :

let whitespace = [' ' '\t' ] 
let newline = ('\n' | '\r' '\n') 

... 

| whitespace { calculator lexbuf } 
| newline { lexbuf.EndPos <- lexbuf.EndPos.NextLine; calculator lexbuf }