我目前正在学习基于解析简单计算的lexing和解析(基于F#工具集)而且我被困在我的词法分析器不会推进使用整个字符串:
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 }
答案 1 :(得分:0)
问题在于你根本无法指望词法分析器自行前进。对我而言,将其视为一个流有助于理解正在发生的事情。
推进仅与解析器结合使用。解析器将继续要求词法分析器返回令牌。