使用 OCaml Menhir,有没有办法在处理之前访问某些内容?
Using OCaml Menhir, is there a way to access something before it is processed?
我正在编写一个解析器来在计算器中解析和计算函数导数。
我在实施乘积和商规则时遇到了问题:
对于产品,推导公式是(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 : 我知道它可能根本不是最好的语法定义,它仍在进行中
直接回答您的问题,是的,您可以维护已处理内容的状态。但这不是做事的方式。惯用的解决方案是编写一个解析器,将输入语言解析为抽象语法树,然后编写一个求解器,将这棵树作为输入并计算它。你不应该在解析器中做任何事情,这是一个简单的自动机,不会有任何副作用。
为了不那么抽象,你想从解析器中得到的是函数 string -> expr
,其中 expr
类型的定义类似于
type expr =
| Var of string
| Const of string
| Binop of binop * expr * expr
and binop = Add | Mul | Sub | Div
我正在编写一个解析器来在计算器中解析和计算函数导数。
我在实施乘积和商规则时遇到了问题: 对于产品,推导公式是(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 : 我知道它可能根本不是最好的语法定义,它仍在进行中
直接回答您的问题,是的,您可以维护已处理内容的状态。但这不是做事的方式。惯用的解决方案是编写一个解析器,将输入语言解析为抽象语法树,然后编写一个求解器,将这棵树作为输入并计算它。你不应该在解析器中做任何事情,这是一个简单的自动机,不会有任何副作用。
为了不那么抽象,你想从解析器中得到的是函数 string -> expr
,其中 expr
类型的定义类似于
type expr =
| Var of string
| Const of string
| Binop of binop * expr * expr
and binop = Add | Mul | Sub | Div