Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 区分';减去';F#lex/yacc解析器中的运算符和负数_Parsing_F#_Fsyacc_Fslex - Fatal编程技术网

Parsing 区分';减去';F#lex/yacc解析器中的运算符和负数

Parsing 区分';减去';F#lex/yacc解析器中的运算符和负数,parsing,f#,fsyacc,fslex,Parsing,F#,Fsyacc,Fslex,我正在尝试使用FsLex和FsYacc解析一个简单的脚本语言,但在区分负数和负数时遇到了问题 如果我计算术语“1-2”,解析器将返回所需的AST:减号(numberTerral(1.0),numberTerral(2.0))。但是如果我计算术语“1-2”,lexer将产生数字1,后面是数字-2,这是无效的输入 我已经做了一个最小的程序来重现我的问题。Ast的定义如下: module Ast type Expression = | NumberLiteral of double | Mi

我正在尝试使用FsLex和FsYacc解析一个简单的脚本语言,但在区分负数和负数时遇到了问题

如果我计算术语“1-2”,解析器将返回所需的AST:
减号(numberTerral(1.0),numberTerral(2.0))
。但是如果我计算术语“1-2”,lexer将产生数字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) }
lexer代码如下所示:

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) }
{
模块Lexer
打开Microsoft.FSharp.Text.Lexing
开放解析器
}
让空白=“”
让数字=['0'-'9']
设数字='-'?位+
规则令牌=解析
|空白*{token lexbuf}
|'-'{负}
|数字{lexbuf |>LexBuffer.lexemstring |>System.Double.Parse |>number}
|eof{eof}
解析器如下所示:

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) }
%{
开放式Ast
%}
%开始
%符号EOF减号
%令牌号
%键入start
%%
开始:
|表达式EOF{$1}
表达方式:
|编号{NumberLiteral$1}
|表情
减号表达式{减号($1,$3)}
我最初的想法是不将
-
作为lexer中数字的一部分来处理,并让解析器确定
减号
标记应该产生减号运算符还是负数。不幸的是,这也会导致输入“-2”被计算为负数,因为空格会被占用


但我认为这一定是一个共同的问题,必须存在一个共同的解决方案。那么我该如何最好地处理这个问题呢?

通常的解决方案是
-2
实际上是一个表达式。如果您觉得计算
-2
效率太低(或者您可以将其作为生产
减号表达式的特例处理),则可以“常量折叠”——直接计算参数为常量的表达式