@@ -102,8 +102,8 @@ type Writer(outputFileName, outputFileInterface) =
102
102
103
103
member x.WriteUInt16 ( i : int ) = fprintf os " %d us;" i
104
104
105
- member x.WriteCode ( code , pos ) =
106
- x.WriteLine " # %d \" %s \" " pos. pos_ lnum pos .pos_ fname
105
+ member x.WriteCode ( code , range : Range ) =
106
+ x.WriteLine " # %d \" %s \" " range.startPos. pos_ lnum range.startPos .pos_ fname
107
107
x.WriteLine " %s " code
108
108
let codeLines = code.Replace( " \r " , " " ) .Split([| '\n' |]) .Length
109
109
outputLineCount <- outputLineCount + codeLines
@@ -131,7 +131,7 @@ type Writer(outputFileName, outputFileInterface) =
131
131
132
132
133
133
// This is to avoid name conflicts against keywords.
134
- let generic_nt_name nt = " 'gentype_" + nt
134
+ let generic_nt_name ( nt , _range ) = " 'gentype_" + nt
135
135
let anyMarker = 0xffff
136
136
137
137
let actionCoding =
@@ -215,7 +215,7 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
215
215
216
216
writer.WriteLine " type token = " ;
217
217
writer.WriteLineInterface " type token = " ;
218
- for id, typ in spec.Tokens do
218
+ for ( id, _ range ), typ in spec.Tokens do
219
219
match typ with
220
220
| None ->
221
221
writer.WriteLine " | %s " id
@@ -228,7 +228,7 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
228
228
writer.WriteLine " // This type is used to give symbolic names to token indexes, useful for error messages" ;
229
229
writer.WriteLine " type tokenId = " ;
230
230
writer.WriteLineInterface " type tokenId = " ;
231
- for id, typ in spec.Tokens do
231
+ for ( id, _ range ), typ in spec.Tokens do
232
232
writer.WriteLine " | TOKEN_%s " id;
233
233
writer.WriteLineInterface " | TOKEN_%s " id;
234
234
writer.WriteLine " | TOKEN_end_of_input" ;
@@ -239,7 +239,7 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
239
239
writer.WriteLine " // This type is used to give symbolic names to token indexes, useful for error messages" ;
240
240
writer.WriteLine " type nonTerminalId = " ;
241
241
writer.WriteLineInterface " type nonTerminalId = " ;
242
- for nt in compiledSpec.nonTerminals do
242
+ for ( nt , _ range ) in compiledSpec.nonTerminals do
243
243
writer.WriteLine " | NONTERM_%s " nt;
244
244
writer.WriteLineInterface " | NONTERM_%s " nt;
245
245
@@ -248,7 +248,7 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
248
248
writer.WriteLine " // This function maps tokens to integer indexes" ;
249
249
writer.WriteLine " let tagOfToken (t:token) = " ;
250
250
writer.WriteLine " match t with" ;
251
- spec.Tokens |> List.iteri ( fun i ( id , typ ) ->
251
+ spec.Tokens |> List.iteri ( fun i (( id , _range ), typ ) ->
252
252
writer.WriteLine " | %s %s -> %d " id ( match typ with Some _ -> " _" | None -> " " ) i);
253
253
writer.WriteLineInterface " /// This function maps tokens to integer indexes" ;
254
254
writer.WriteLineInterface " val tagOfToken: token -> int" ;
@@ -257,7 +257,7 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
257
257
writer.WriteLine " // This function maps integer indexes to symbolic token ids" ;
258
258
writer.WriteLine " let tokenTagToTokenId (tokenIdx:int) = " ;
259
259
writer.WriteLine " match tokenIdx with" ;
260
- spec.Tokens |> List.iteri ( fun i ( id , typ ) -> writer.WriteLine " | %d -> TOKEN_%s " i id)
260
+ spec.Tokens |> List.iteri ( fun i (( id , _range ), typ ) -> writer.WriteLine " | %d -> TOKEN_%s " i id)
261
261
writer.WriteLine " | %d -> TOKEN_end_of_input" compiledSpec.endOfInputTerminalIdx;
262
262
writer.WriteLine " | %d -> TOKEN_error" compiledSpec.errorTerminalIdx;
263
263
writer.WriteLine " | _ -> failwith \" tokenTagToTokenId: bad token\" "
@@ -270,7 +270,7 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
270
270
writer.WriteLine " /// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production" ;
271
271
writer.WriteLine " let prodIdxToNonTerminal (prodIdx:int) = " ;
272
272
writer.WriteLine " match prodIdx with" ;
273
- compiledSpec.prods |> Array.iteri ( fun i ( nt , ntIdx , syms , code ) -> writer.WriteLine " | %d -> NONTERM_%s " i nt);
273
+ compiledSpec.prods |> Array.iteri ( fun i (( nt , _range ), ntIdx , syms , code ) -> writer.WriteLine " | %d -> NONTERM_%s " i nt);
274
274
writer.WriteLine " | _ -> failwith \" prodIdxToNonTerminal: bad production index\" "
275
275
276
276
writer.WriteLineInterface " " ;
@@ -284,7 +284,7 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
284
284
writer.WriteLine " // This function gets the name of a token as a string" ;
285
285
writer.WriteLine " let token_to_string (t:token) = " ;
286
286
writer.WriteLine " match t with " ;
287
- spec.Tokens |> List.iteri ( fun i ( id , typ ) -> writer.WriteLine " | %s %s -> \" %s \" " id ( match typ with Some _ -> " _" | None -> " " ) id);
287
+ spec.Tokens |> List.iteri ( fun i (( id , _range ), typ ) -> writer.WriteLine " | %s %s -> \" %s \" " id ( match typ with Some _ -> " _" | None -> " " ) id);
288
288
289
289
writer.WriteLineInterface " " ;
290
290
writer.WriteLineInterface " /// This function gets the name of a token as a string" ;
@@ -295,22 +295,22 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
295
295
writer.WriteLine " let _fsyacc_dataOfToken (t:token) = " ;
296
296
writer.WriteLine " match t with " ;
297
297
298
- for ( id, typ) in spec.Tokens do
298
+ for (( id, _ range ), typ) in spec.Tokens do
299
299
writer.WriteLine " | %s %s -> %s "
300
300
id
301
301
( match typ with Some _ -> " _fsyacc_x" | None -> " " )
302
302
( match typ with Some _ -> " Microsoft.FSharp.Core.Operators.box _fsyacc_x" | None -> " (null : System.Object)" )
303
303
304
304
let tychar = " 'cty"
305
305
306
- for ( key,_) in spec.Types |> Seq.countBy fst |> Seq.filter ( fun ( _ , n ) -> n > 1 ) do
306
+ for (( key, _ range ), _) in spec.Types |> Seq.countBy fst |> Seq.filter ( fun ( _ , n ) -> n > 1 ) do
307
307
failwithf " %s is given multiple %%t ype declarations" key;
308
308
309
- for ( key,_) in spec.Tokens |> Seq.countBy fst |> Seq.filter ( fun ( _ , n ) -> n > 1 ) do
309
+ for (( key, _ range ), _) in spec.Tokens |> Seq.countBy fst |> Seq.filter ( fun ( _ , n ) -> n > 1 ) do
310
310
failwithf " %s is given %%t oken declarations" key
311
311
312
- let types = Map.ofList spec.Types
313
- let tokens = Map.ofList spec.Tokens
312
+ let types = Map.ofList ( spec.Types |> List.map ( fun (( name , _range ), rest ) -> name , rest ))
313
+ let tokens = Map.ofList ( spec.Tokens |> List.map ( fun (( name , _range ), rest ) -> name , rest ))
314
314
315
315
let nStates = compiledSpec.states.Length
316
316
begin
@@ -457,7 +457,11 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
457
457
writer.WriteLine " |]" ;
458
458
end ;
459
459
460
- let getType nt = if types.ContainsKey nt then types.[ nt] else generatorState.generate_ nonterminal_ name nt
460
+ let getType (( name , _range ) as nt ) =
461
+ types
462
+ |> Map.tryFind name
463
+ |> Option.defaultWith ( fun _ -> generatorState.generate_ nonterminal_ name nt)
464
+
461
465
begin
462
466
writer.Write " let _fsyacc_reductions () =" ;
463
467
writer.WriteLine " [| " ;
@@ -469,10 +473,7 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
469
473
syms |> List.iteri ( fun i sym ->
470
474
let tyopt =
471
475
match sym with
472
- | Terminal t ->
473
- if tokens.ContainsKey t then
474
- tokens.[ t]
475
- else None
476
+ | Terminal ( name, range) -> tokens |> Map.tryFind name |> Option.flatten
476
477
| NonTerminal nt -> Some ( getType nt)
477
478
match tyopt with
478
479
| Some ty -> writer.WriteLine " let _%d = parseState.GetInput(%d ) :?> %s in" ( i+ 1 ) ( i+ 1 ) ty
@@ -481,7 +482,7 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
481
482
writer.WriteLine " (" ;
482
483
writer.WriteLine " (" ;
483
484
match code with
484
- | Some (_, pos) -> writer.WriteLine " # %d \" %s \" " pos.pos_ lnum pos.pos_ fname
485
+ | Some (_,{ startPos = pos } ) -> writer.WriteLine " # %d \" %s \" " pos.pos_ lnum pos.pos_ fname
485
486
| None -> ()
486
487
match code with
487
488
| Some ( code,_) ->
@@ -500,9 +501,9 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
500
501
writer.WriteLine " )" ;
501
502
// Place the line count back for the type constraint
502
503
match code with
503
- | Some (_, pos) -> writer.WriteLine " # %d \" %s \" " pos.pos_ lnum pos.pos_ fname
504
+ | Some (_, { startPos = pos } ) -> writer.WriteLine " # %d \" %s \" " pos.pos_ lnum pos.pos_ fname
504
505
| None -> ()
505
- writer.WriteLine " : %s ));" ( if types.ContainsKey nt then types .[ nt ] else generatorState.generate _ nonterminal _ name nt);
506
+ writer.WriteLine " : %s ));" ( getType nt);
506
507
done ;
507
508
writer.WriteLine " |]" ;
508
509
end ;
@@ -530,14 +531,14 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
530
531
writer.WriteLine " productionToNonTerminalTable = _fsyacc_productionToNonTerminalTable }"
531
532
writer.WriteLine " let engine lexer lexbuf startState = tables.Interpret(lexer, lexbuf, startState)"
532
533
533
- for ( id, startState) in List.zip spec.StartSymbols compiledSpec.startStates do
534
+ for (( id, _ range ), startState) in List.zip spec.StartSymbols compiledSpec.startStates do
534
535
if not ( types.ContainsKey id) then
535
- failwith ( " a %t ype declaration is required for for start token " + id);
536
+ failwith ( " a %t ype declaration is required for for start token " + id);
536
537
let ty = types.[ id] in
537
538
writer.WriteLine " let %s lexer lexbuf : %s =" id ty;
538
539
writer.WriteLine " engine lexer lexbuf %d :?> _" startState
539
540
540
- for id in spec.StartSymbols do
541
+ for ( id , _ range ) in spec.StartSymbols do
541
542
if not ( types.ContainsKey id) then
542
543
failwith ( " a %t ype declaration is required for start token " + id);
543
544
let ty = types.[ id] in
0 commit comments