1
我想使用FsLex和FsYacc來分析一個簡單的腳本語言,並且我在區分minus運算符和負數時遇到了問題。在F#lex/yacc分析器中區分'負'運算符和負數
如果我評估術語「1 - 2」,解析器將返回所需的AST:Minus(NumberLiteral(1.0),NumberLiteral(2.0))
。但是,如果我評估術語「1-2」,詞法分析器將產生數字1,然後是數字-2,這不是有效的輸入。
我已經做了一個最小的程序來重現我的問題。 AST這樣定義:
module Ast
type Expression =
| NumberLiteral of double
| Minus of Expression * Expression
詞法分析器代碼如下所示:
{
module Lexer
open Microsoft.FSharp.Text.Lexing
open Parser
}
let whitespace = ' '
let digit = ['0' - '9']
let number = '-'?digit+
rule token = parse
| whitespace* { token lexbuf }
| '-' { MINUS }
| number { lexbuf |> LexBuffer<_>.LexemeString |> System.Double.Parse |> NUMBER }
| eof { EOF }
解析器是這樣的:
%{
open Ast
%}
%start start
%token EOF MINUS
%token <double> NUMBER
%type <Expression> start
%%
start:
| expression EOF { $1 }
expression:
| NUMBER { NumberLiteral $1 }
| expression
MINUS expression { Minus($1, $3) }
我最初的想法是不處理-
的一部分在詞法分析器中的數字,並讓解析器確定MINUS
標記是否應產生負運算符或負數。不幸的是,這也會導致輸入「-2」被評估爲負數,因爲空白將被消耗。
但我認爲這一定是一個普遍問題,必須有一個通用的解決方案。那麼我該如何最好地處理這個問題?