Skip to content

Commit bbc027e

Browse files
committed
Add end position
* Changes types of OpamParserTypes, to `foo_kind` the main type value and `foo` the type with a position type file_name = string type pos = { filename: file_name; start: int * int; (* line, column *) stop: int * int; (* line, column *) } type 'a with_pos = { pkind : 'a; pos : pos } type value_kind = | Int of int [...] and value = value_kind with_pos
1 parent 283f83b commit bbc027e

5 files changed

Lines changed: 324 additions & 193 deletions

File tree

src/opamBaseParser.mly

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,25 @@
1313

1414
open OpamParserTypes
1515

16-
(** OPAM config file generic type parser *)
16+
(** Opam config file generic type parser *)
17+
18+
let get_pos_full ?(s=1) n =
19+
let spos = Parsing.rhs_start_pos s in
20+
let epos = Parsing.rhs_end_pos n in
21+
Lexing.({
22+
filename = spos.pos_fname;
23+
start = spos.pos_lnum, spos.pos_cnum - spos.pos_bol;
24+
stop = epos.pos_lnum, epos.pos_cnum - epos.pos_bol;
25+
})
1726

1827
let get_pos n =
19-
let pos = Parsing.rhs_start_pos n in
20-
Lexing.(pos.pos_fname,
21-
pos.pos_lnum,
22-
pos.pos_cnum - pos.pos_bol)
28+
let spos = Parsing.rhs_start_pos n in
29+
let epos = Parsing.rhs_end_pos n in
30+
Lexing.({
31+
filename = spos.pos_fname;
32+
start = spos.pos_lnum, spos.pos_cnum - spos.pos_bol;
33+
stop = epos.pos_lnum, epos.pos_cnum - epos.pos_bol;
34+
})
2335

2436
%}
2537

@@ -31,11 +43,11 @@ let get_pos n =
3143
%token LBRACE RBRACE
3244
%token COLON
3345
%token <int> INT
34-
%token <OpamParserTypes.relop> RELOP
46+
%token <OpamParserTypes.relop_kind> RELOP
3547
%token AND
3648
%token OR
37-
%token <OpamParserTypes.pfxop> PFXOP
38-
%token <OpamParserTypes.env_update_op> ENVOP
49+
%token <OpamParserTypes.pfxop_kind> PFXOP
50+
%token <OpamParserTypes.env_update_op_kind> ENVOP
3951

4052
%left COLON
4153
%left ATOM
@@ -50,6 +62,8 @@ let get_pos n =
5062
%start main value
5163
%type <string -> OpamParserTypes.opamfile> main
5264
%type <OpamParserTypes.value> value
65+
%type <OpamParserTypes.value list> values
66+
%type <OpamParserTypes.opamfile_item> item
5367

5468
%%
5569

@@ -64,28 +78,46 @@ items:
6478
;
6579

6680
item:
67-
| IDENT COLON value { Variable (get_pos 1, $1, $3) }
81+
| IDENT COLON value {
82+
{ pos = get_pos_full 3;
83+
pelem =
84+
Variable ({ pos = get_pos 1; pelem = $1 }, $3);
85+
}
86+
}
6887
| IDENT LBRACE items RBRACE {
69-
Section (get_pos 1,
70-
{section_kind=$1; section_name=None; section_items= $3})
88+
{ pos = get_pos_full 4;
89+
pelem =
90+
Section ({section_kind = { pos = get_pos 1; pelem = $1 };
91+
section_name = None;
92+
section_items =
93+
{ pos = get_pos_full ~s:2 4; pelem = $3 };
94+
})
95+
}
7196
}
7297
| IDENT STRING LBRACE items RBRACE {
73-
Section (get_pos 1,
74-
{section_kind=$1; section_name=Some $2; section_items= $4})
98+
{ pos = get_pos_full 4;
99+
pelem =
100+
Section ({section_kind = { pos = get_pos 1; pelem = $1 };
101+
section_name = Some { pos = get_pos 2; pelem = $2 };
102+
section_items =
103+
{ pos = get_pos_full ~s:2 4; pelem = $4 };
104+
})
105+
}
75106
}
76107
;
77108

78109
value:
79110
| atom %prec ATOM { $1 }
80-
| LPAR values RPAR { Group (get_pos 1,$2) }
81-
| LBRACKET values RBRACKET { List (get_pos 1,$2) }
82-
| value LBRACE values RBRACE { Option (get_pos 2,$1, $3) }
83-
| value AND value { Logop (get_pos 2,`And,$1,$3) }
84-
| value OR value { Logop (get_pos 2,`Or,$1,$3) }
85-
| atom RELOP atom { Relop (get_pos 2,$2,$1,$3) }
86-
| atom ENVOP atom { Env_binding (get_pos 1,$1,$2,$3) }
87-
| PFXOP value { Pfxop (get_pos 1,$1,$2) }
88-
| RELOP atom { Prefix_relop (get_pos 1,$1,$2) }
111+
| LPAR values RPAR {{ pos = get_pos_full 3 ; pelem = Group { pos = get_pos_full ~s:1 3; pelem = $2 } }}
112+
| LBRACKET values RBRACKET {{ pos = get_pos_full 3 ; pelem = List { pos = get_pos_full ~s:1 3; pelem = $2 } }}
113+
| value LBRACE values RBRACE {{ pos = get_pos_full 4 ;
114+
pelem = Option ($1, { pos = get_pos_full ~s:2 4; pelem = $3 }) }}
115+
| value AND value {{ pos = get_pos_full 3 ; pelem = Logop ({ pos = get_pos 2 ; pelem = `And },$1,$3) }}
116+
| value OR value {{ pos = get_pos_full 3 ; pelem = Logop ({ pos = get_pos 2 ; pelem = `Or },$1,$3) }}
117+
| atom relop atom {{ pos = get_pos_full 3 ; pelem = Relop ($2,$1,$3) }}
118+
| atom envop atom {{ pos = get_pos_full 3 ; pelem = Env_binding ($1,$2,$3) }}
119+
| pfxop value {{ pos = get_pos_full 2 ; pelem = Pfxop ($1,$2) }}
120+
| relop atom {{ pos = get_pos_full 2 ; pelem = Prefix_relop ($1,$2) }}
89121
;
90122

91123
values:
@@ -94,12 +126,21 @@ values:
94126
;
95127

96128
atom:
97-
| IDENT { Ident (get_pos 1,$1) }
98-
| BOOL { Bool (get_pos 1,$1) }
99-
| INT { Int (get_pos 1,$1) }
100-
| STRING { String (get_pos 1,$1) }
129+
| IDENT {{ pos = get_pos 1 ; pelem = Ident $1 }}
130+
| BOOL {{ pos = get_pos 1 ; pelem = Bool $1 }}
131+
| INT {{ pos = get_pos 1 ; pelem = Int $1 }}
132+
| STRING {{ pos = get_pos 1 ; pelem = String $1 }}
101133
;
102134

135+
relop:
136+
| RELOP {{ pos = get_pos 1 ; pelem = $1 }}
137+
138+
envop:
139+
| ENVOP {{ pos = get_pos 1 ; pelem = $1 }}
140+
141+
pfxop:
142+
| PFXOP {{ pos = get_pos 1 ; pelem = $1 }}
143+
103144
%%
104145

105146
let main t l f =

src/opamLexer.mli

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ exception Error of string
1717
(** Raised on any lexing error with a description of the fault. Note that
1818
[Failure "lexing: empty token"] is never raised by the lexer. *)
1919

20-
val relop: string -> relop
20+
val relop: string -> relop_kind
2121
(** Inverse of {!OpamPrinter.relop} *)
2222

23-
val logop: string -> logop
23+
val logop: string -> logop_kind
2424
(** Inverse of {!OpamPrinter.logop} *)
2525

26-
val pfxop: string -> pfxop
26+
val pfxop: string -> pfxop_kind
2727
(** Inverse of {!OpamPrinter.pfxop} *)
2828

29-
val env_update_op: string -> env_update_op
29+
val env_update_op: string -> env_update_op_kind
3030
(** Inverse of {!OpamPrinter.env_update_op} *)
3131

3232

src/opamParserTypes.mli

Lines changed: 56 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,72 +11,87 @@
1111

1212
(** Defines the types for the opam format lexer and parser *)
1313

14+
(** Source file positions *)
15+
type file_name = string
16+
type pos =
17+
{ filename: file_name;
18+
start: int * int; (* line, column *)
19+
stop: int * int; (* line, column *)
20+
}
21+
type 'a with_pos =
22+
{ pelem : 'a;
23+
pos : pos
24+
}
25+
1426
(** Relational operators *)
15-
type relop = [ `Eq (** [=] *)
16-
| `Neq (** [!=] *)
17-
| `Geq (** [>=] *)
18-
| `Gt (** [>] *)
19-
| `Leq (** [<=] *)
20-
| `Lt (** [<] *)
21-
]
27+
type relop_kind =
28+
[ `Eq (** [=] *)
29+
| `Neq (** [!=] *)
30+
| `Geq (** [>=] *)
31+
| `Gt (** [>] *)
32+
| `Leq (** [<=] *)
33+
| `Lt (** [<] *)
34+
]
35+
and rel_op = relop_kind with_pos
2236

2337
(** Logical operators *)
24-
type logop = [ `And (** [&] *) | `Or (** [|] *) ]
38+
type logop_kind = [ `And (** [&] *) | `Or (** [|] *) ]
39+
and log_op = logop_kind with_pos
2540

2641
(** Prefix operators *)
27-
type pfxop = [ `Not (** [!] *) | `Defined (** [?] *) ]
28-
29-
type file_name = string
30-
31-
(** Source file positions: [(filename, line, column)] *)
32-
type pos = file_name * int * int
42+
type pfxop_kind = [ `Not (** [!] *) | `Defined (** [?] *) ]
43+
and pfx_op = pfxop_kind with_pos
3344

3445
(** Environment variable update operators *)
35-
type env_update_op = Eq (** [=] *)
36-
| PlusEq (** [+=] *)
37-
| EqPlus (** [=+] *)
38-
| ColonEq (** [:=] *)
39-
| EqColon (** [=:] *)
40-
| EqPlusEq (** [=+=] *)
46+
type env_update_op_kind =
47+
| Eq (** [=] *)
48+
| PlusEq (** [+=] *)
49+
| EqPlus (** [=+] *)
50+
| ColonEq (** [:=] *)
51+
| EqColon (** [=:] *)
52+
| EqPlusEq (** [=+=] *)
53+
and env_update_op = env_update_op_kind with_pos
4154

4255
(** Base values *)
43-
type value =
44-
| Bool of pos * bool
56+
type value_kind =
57+
| Bool of bool
4558
(** [bool] atoms *)
46-
| Int of pos * int
59+
| Int of int
4760
(** [int] atoms *)
48-
| String of pos * string
61+
| String of string
4962
(** [string] atoms *)
50-
| Relop of pos * relop * value * value
63+
| Relop of rel_op * value * value
5164
(** Relational operators with two values (e.g. [os != "win32"]) *)
52-
| Prefix_relop of pos * relop * value
65+
| Prefix_relop of rel_op * value
5366
(** Relational operators in prefix position (e.g. [< "4.07.0"]) *)
54-
| Logop of pos * logop * value * value
67+
| Logop of log_op * value * value
5568
(** Logical operators *)
56-
| Pfxop of pos * pfxop * value
69+
| Pfxop of pfx_op * value
5770
(** Prefix operators *)
58-
| Ident of pos * string
71+
| Ident of string
5972
(** Identifiers *)
60-
| List of pos * value list
73+
| List of value list with_pos
6174
(** Lists of values ([[x1 x2 ... x3]]) *)
62-
| Group of pos * value list
75+
| Group of value list with_pos
6376
(** Groups of values ([(x1 x2 ... x3)]) *)
64-
| Option of pos * value * value list
77+
| Option of value * value list with_pos
6578
(** Value with optional list ([x1 {x2 x3 x4}]) *)
66-
| Env_binding of pos * value * env_update_op * value
79+
| Env_binding of value * env_update_op * value
6780
(** Environment variable binding ([FOO += "bar"]) *)
81+
and value = value_kind with_pos
6882

6983
(** An opamfile section *)
70-
type opamfile_section = {
71-
section_kind : string; (** Section kind (e.g. [extra-source]) *)
72-
section_name : string option; (** Section name (e.g. ["myfork.patch"]) *)
73-
section_items : opamfile_item list (** Content of the section *);
74-
}
84+
type opamfile_section =
85+
{ section_kind : string with_pos; (** Section kind (e.g. [extra-source]) *)
86+
section_name : string with_pos option; (** Section name (e.g. ["myfork.patch"]) *)
87+
section_items : opamfile_item list with_pos (** Content of the section *);
88+
}
7589

7690
(** An opamfile is composed of sections and variable definitions *)
77-
and opamfile_item =
78-
| Section of pos * opamfile_section (** e.g. [kind ["name"] { ... }] *)
79-
| Variable of pos * string * value (** e.g. [opam-version: "2.0"] *)
91+
and opamfile_item_kind =
92+
| Section of opamfile_section (** e.g. [kind ["name"] { ... }] *)
93+
| Variable of string with_pos * value (** e.g. [opam-version: "2.0"] *)
94+
and opamfile_item = opamfile_item_kind with_pos
8095

8196
(** A file is a list of items and the filename *)
8297
type opamfile = {

0 commit comments

Comments
 (0)