我尝试为一种程序制作前端......有两个特点:
1)当我们遇到以 开头的字符串时=
,我想将字符串的其余部分读取为 aformula
而不是字符串值。例如,"123"
, "TRUE"
,"TRUE+123"
被认为具有string
作为类型,而"=123"
, "=TRUE"
,"=TRUE+123"
被认为具有Syntax.formula
作为类型。顺便一提,
(* in syntax.ml *)
and expression =
| E_formula of formula
| E_string of string
...
and formula =
| F_int of int
| F_bool of bool
| F_Plus of formula * formula
| F_RC of rc
and rc =
| RC of int * int
2)在公式内部,某些字符串的解释与外部不同。例如,在一个实际上是一个变量的命令R4C5 := 4
中R4C5
,被认为是一个identifier
,而在"=123+R4C5"
其中试图被翻译成一个公式时,R4C5
被翻译为RC (4,5): rc
。
所以我不知道如何用 1 或 2 个词法分析器和 1 或 2 个解析器来实现这一点。
目前,我尝试在 1 个词法分析器和 1 个解析器中实现所有功能。这是代码的一部分,它不起作用,它仍然认为R4C5
是identifier
,而不是rc
:
(* in lexer.mll *)
let begin_formula = double_quote "="
let end_formula = double_quote
let STRING = double_quote ([^ "=" ])* double_quote
rule token = parse
...
| begin_formula { BEGIN_FORMULA }
| 'R' { R }
| 'C' { C }
| end_formula { END_FORMULA }
| lex_identifier as li
{ try Hashtbl.find keyword_table (lowercase li)
with Not_found -> IDENTIFIER li }
| STRING as s { STRING s }
...
(* in parser.mly *)
expression:
| BEGIN_FORMULA f = formula END_FORMULA { E_formula f }
| s = STRING { E_string s }
...
formula:
| i = INTEGER { F_int i }
| b = BOOL { F_bool b }
| f0 = formula PLUS f1 = formula { F_Plus (f0, f1) }
| rc { F_RC $1 }
rc:
| R i0 = INTEGER C i1 = INTEGER { RC (i0, i1) }
有人可以帮忙吗?
新想法:我正在考虑坚持使用 1 个词法分析器 + 1 个解析器,并在词法分析器中为公式创建一个入口点,就像我们通常所做的那样comment
......这里有一些更新lexer.mll
和parser.mly
:
(* in lexer.mll *)
rule token = parse
...
| begin_formula { formula lexbuf }
...
| INTEGER as i { INTEGER (int_of_string i) }
| '+' { PLUS }
...
and formula = parse
| end_formula { token lexbuf }
| INTEGER as i { INTEGER_F (int_of_string i) }
| 'R' { R }
| 'C' { C }
| '+' { PLUS_F }
| _ { raise (Lexing_error ("unknown in formula")) }
(* in parser.mly *)
expression:
| formula { E_formula f }
...
formula:
| i = INTEGER_F { F_int i }
| f0 = formula PLUS_F f1 = formula { F_Plus (f0, f1) }
...
我做了一些测试,例如解析"=R4"
,问题是它可以很好地解析R
,但它认为4
而INTEGER
不是INTEGER_F
,似乎formula lexbuf
需要在入口点的主体中不时添加formula
(虽然我不明白为什么在token
入口点的正文中进行解析而不总是提及token lexbuf
)。我尝试了几种可能性:| 'R' { R; formula lexbuf }
, | 'R' { formula lexbuf; R }
等,但它没有用...... 有人可以帮忙吗?