目前我的前端可以解析诸如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 fsparser_formula.mlyparser.mly