目前我的前端可以解析诸如123
, "abcd"
, "=123"
, "=TRUE+123"
... 这样的普通表达式。以下是相关代码:
(* in `syntax.ml`: *)
and expression =
| E_integer of int
| E_string of string
(* in `parser.mly`: *)
expression:
| INTEGER { E_integer $1 }
| STRING { E_string $1 }
现在我想改进解析器,这样,当我们遇到以 开头的字符串时=
,我们会尝试将其评估为公式,而不是文字字符串。所以syntax.ml
变成了:
(* in `syntax.ml`: *)
and expression =
| E_integer of int
| E_string of string
| E_formula of formula
and formula =
| F_integer of int
| F_boolean of bool
| F_Add of formula * formula
问题是我不知道如何改变parser.mly
,我试过这个不起作用(This expression has type string but an expression was expected of type Syntax.formula
):
(* in `parser.mly`: *)
expression:
| INTEGER { E_integer $1 }
| STRING {
if String.sub $1 1 1 <> "="
then E_string $1
else E_formula (String.sub $1 2 ((String.length $1) - 1)) }
我不知道如何让解析器知道,对于以 开头的字符串=
,我需要根据...的规则进一步解析它formula
。有人可以帮忙吗?
根据以下评论gasche
:
我同意我需要一个公式解析器。现在的问题是我是否需要单独lexer.mll
的公式。我希望不会,因为只对整个程序进行一次 lex 是一种逻辑,不是吗?另外,我可以直接将公式语法添加到现有的parser.mly
吗?
在当前lexer.mll
,我有:
let STRING = double_quote ([^ '\x0D' '\x0A' '\x22'])* double_quote
rule token = parse
| STRING as s { STRING s }
我想我可以直接在这里做点什么:
let STRING = double_quote ([^ '\x0D' '\x0A' '\x22'])* double_quote
let FORMULA_STRING = double_quote = ([^ '\x0D' '\x0A' '\x22'])* double_quote
rule token = parse
| FORMULA_STRING as fs { XXXXX }
| STRING as s { STRING s }
我不知道我应该写什么地方,如果我分开的话XXXXX
,应该是什么?如果我只有其中包含所有语法,包括公式之一怎么办?Parser_formula.formula token fs
parser_formula.mly
parser.mly