FsLex와 FsYacc를 사용하여 간단한 스크립트 언어를 구문 분석하려고하는데 마이너스 연산자를 음수와 구별하는 데 문제가 있습니다.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"입력이 음수로 평가 될 수도 있습니다.
그러나 일반적인 문제 여야하며 일반적인 해결 방법이 있어야한다고 가정합니다. 그럼 어떻게 처리해야합니까?