2

我尝试为一种程序制作前端......有两个特点:

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 := 4R4C5,被认为是一个identifier,而在"=123+R4C5"其中试图被翻译成一个公式时,R4C5被翻译为RC (4,5): rc

所以我不知道如何用 1 或 2 个词法分析器和 1 或 2 个解析器来实现这一点。

目前,我尝试在 1 个词法分析器和 1 个解析器中实现所有功能。这是代码的一部分,它不起作用,它仍然认为R4C5identifier,而不是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.mllparser.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,但它认为4INTEGER不是INTEGER_F,似乎formula lexbuf需要在入口点的主体中不时添加formula(虽然我不明白为什么在token入口点的正文中进行解析而不总是提及token lexbuf)。我尝试了几种可能性:| 'R' { R; formula lexbuf }, | 'R' { formula lexbuf; R }等,但它没有用...... 有人可以帮忙吗?

4

1 回答 1

1

我认为最简单的选择是拥有两个不同的词法分析器和两个不同的解析器;从全局解析器内部调用 lexer&parser 来获取公式。事后您可以看到两种语法之间共享了多少,并在可能的情况下分解事物。

于 2012-12-20T19:40:43.287 回答