2014-08-29 22 views
0

我目前正在学习基于解析一个简单的计算lexing和解析(基于F#工具集),我卡在我的词法分析器没有前进消耗整个字符串:fslex学习:Lexer没有前进

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 }