使用OCaml Menhir,有没有办法在处理之前访问一些东西?

问题描述 投票:0回答:1

我正在写一个解析器来解析和计算计算器中的函数导数。

我在实现乘积和商规则时遇到了一个问题:对于乘积的推导公式是(u*v)' = u'v+uv',因此我需要在最终输出中得到u和u'的值。而我现在的解析器,每当需要写u的时候,它已经被u'代替了,我不知道如何保存它的值,也不知道是否可能......

这里是解析器。

%token <string> VAR FUNCTION CONST
%token LEFT_B RIGHT_B PLUS MINUS TIMES DIV
%token DERIV
%token EOL

%start<string> main

%%

main:
t = toDeriv; EOL {t}
;

toDeriv:
DERIV; LEFT_B; e = expr; RIGHT_B {e}
;

expr:
u = expr; PLUS v = hat_funct {u^"+"^v}
  | u = expr; MINUS; v = hat_funct {u^"-"^v}
  | u = hat_funct {u}
;

hat_funct:
u = hat_funct TIMES v = funct {Printf.sprintf "%s * %s + %s * %s" u (A way to save v) v (A way to save u)}
  | u = hat_funct DIV v = funct {Printf.sprintf "(%s * %s - %s * %s)/%s^2" u (A way to save v) (A way to save u) v (A way to save v)}
  | u = funct {u}
;

funct:
f = func; LEFT_B; c = content; RIGHT_B {Derivatives.deriv_func f c}
;

content:
e = expr {e}
  | x = VAR {x}
  | k = CONST {k}

func:
f = FUNCTION {f}
  | k = CONST {k}
;

P.S : 我知道这可能不是最好的语法定义,它仍然是一个正在进行中的工作。

parsing ocaml menhir
1个回答
1
投票

直接回答你的问题,是的,你可以保持正在处理的状态。但事情不是这样做的。成语式的解决方案是写一个解析器,将输入语言解析成抽象语法树,然后写一个解算器,将这棵树作为输入并进行计算。你不应该在解析器中做任何事情,这是一个简单的自动机,不得有任何副作用。

为了使它不那么抽象,你想从解析器中得到的是函数 string -> expr,其中 expr 类型被定义为类似于

type expr = 
  | Var of string
  | Const of string 
  | Binop of binop * expr * expr
and binop = Add | Mul | Sub | Div
© www.soinside.com 2019 - 2024. All rights reserved.