Project

General

Profile

Download (4.48 KB) Statistics
| Branch: | Tag: | Revision:
1
(********************************************************************)
2
(*                                                                  *)
3
(*  The LustreC compiler toolset   /  The LustreC Development Team  *)
4
(*  Copyright 2012 -    --   ONERA - CNRS - INPT                    *)
5
(*                                                                  *)
6
(*  LustreC is free software, distributed WITHOUT ANY WARRANTY      *)
7
(*  under the terms of the GNU Lesser General Public License        *)
8
(*  version 2.1.                                                    *)
9
(*                                                                  *)
10
(********************************************************************)
11

    
12
{
13

    
14
  (* open ParserLustreSpec *)
15
  open Parser_lustre
16
  open Utils
17

    
18
  module Lex = MenhirLib.LexerUtil
19

    
20
  let str_buf = Buffer.create 1024
21

    
22
  type error =
23
    | Undefined_token of string
24
    | Unfinished_string
25
    | Unfinished_comment
26

    
27
  exception Error of Location.t * error
28

    
29
let pp_error fmt =
30
  let open Format in
31
  function
32
  | Undefined_token s ->
33
    fprintf fmt "undefined token '%s'" s
34
  | Unfinished_comment ->
35
    fprintf fmt "unfinished comment"
36
  | Unfinished_string ->
37
    fprintf fmt "unfinished string"
38

    
39
let error lexbuf err =
40
  raise (Error (Location.curr lexbuf, err))
41

    
42
let newline token lexbuf =
43
  Lex.newline lexbuf;
44
  token lexbuf
45

    
46
(* As advised by Caml documentation. This way a single lexer rule is
47
   used to handle all the possible keywords. *)
48
let keyword_table =
49
  create_hashtable 20 [
50
  (* "true", TRUE; *)
51
  (* "false", FALSE; *)
52
  "function", FUNCTION;
53
  "if", IF;
54
  "then", THEN;
55
  "else", ELSE;
56
  "merge", MERGE;
57
  "arrow", ARROW;
58
  "fby", FBY;
59
  "when", WHEN;
60
  "whennot", WHENNOT;
61
  "every", EVERY;
62
  "node", NODE;
63
  "let", LET;
64
  "tel", TEL;
65
  "returns", RETURNS;
66
  "var", VAR;
67
  "import", IMPORT;
68
  (* "imported", IMPORTED; *)
69
  "int", TINT;
70
  "bool", TBOOL;
71
  (* "float", TFLOAT; *)
72
  "real", TREAL;
73
  "clock", TCLOCK;
74
  "not", NOT;
75
  "and", AND;
76
  "or", OR;
77
  "xor", OR;
78
  "mod", MOD;
79
  "pre", PRE;
80
  "div", DIV;
81
  "const", CONST;
82
  (* "include", INCLUDE; *)
83
  "assert", ASSERT;
84
   "ensure", ENSURE;
85
  "require", REQUIRE;
86
  (* "observer", OBSERVER; *)
87
  "invariant", INVARIANT;
88
  "mode", MODE;
89
  "assume", ASSUME;
90
  "contract", CONTRACT;
91
  "guarantee", GUARANTEES;
92
  "exists", EXISTS;
93
  "forall", FORALL;
94
  "c_code", CCODE;
95
  "matlab", MATLAB;
96
  "by", BY
97
  ]
98

    
99
}
100

    
101

    
102
let newline = ('\010' | '\013' | "\013\010")
103
let notnewline = [^ '\010' '\013']
104
let blank = [' ' '\009' '\012']
105

    
106
rule token = parse
107
  | "(*"                           { comment_line 0 lexbuf }
108
  | "--" notnewline* (newline|eof) { newline token lexbuf }
109
  | newline                        { newline token lexbuf }
110
  | blank +                        { token lexbuf }
111
  | (('-'? ['0'-'9'] ['0'-'9']* as l) '.' (['0'-'9']* as r)) as s
112
    {REAL (Real.create (l^r) (String.length r) s)}
113
  | (('-'? ['0'-'9']+ as l)  '.' (['0'-'9']+ as r) ('E'|'e') (('+'|'-') ['0'-'9'] ['0'-'9']* as exp)) as s
114
    {REAL (Real.create (l^r) (String.length r + -1 * int_of_string exp) s)}
115
  | '-'? ['0'-'9']+ 
116
    {INT (int_of_string (Lexing.lexeme lexbuf)) }
117
  | (['0'-'9']+) as i '-' "induction"
118
    {KINDUCTION (int_of_string i)}
119
  (* | '/' (['_' 'A'-'Z' 'a'-'z'] ['A'-'Z' 'a'-'z' '_' '0'-'9']* '/')+ as s
120
       {IDENT s}
121
  *)
122
  | ['_' 'A'-'Z' 'a'-'z'] ['A'-'Z' 'a'-'z' '_' '0'-'9']*
123
    {let s = Lexing.lexeme lexbuf in
124
     try
125
       Hashtbl.find keyword_table s
126
     with Not_found ->
127
       IDENT s}
128
  | "->" {ARROW}
129
  | "=>" {IMPL}
130
  | "<=" {LTE}
131
  | ">=" {GTE}
132
  | "<>" {NEQ}
133
  | '<' {LT}
134
  | '>' {GT}
135
  | "!=" {NEQ}
136
  | '-' {MINUS}
137
  | '+' {PLUS}
138
  | '/' {DIV}
139
  | '*' {MULT}
140
  | '=' {EQ}
141
  | '(' {LPAR}
142
  | ')' {RPAR}
143
  | '[' {LBRACKET}
144
  | ']' {RBRACKET}
145
  | ';' {SCOL}
146
  | ':' {COL}
147
  | ',' {COMMA}
148
  | '=' {EQ}
149
  | '/' {DIV}
150
  | "&&" {AMPERAMPER}
151
  | "||" {BARBAR}
152
  | "::" {COLCOL}
153
  | "^" {POWER}
154
  | '"' { Buffer.clear str_buf; string_parse lexbuf }
155
  | eof { EOF }
156
  | _   { error lexbuf (Undefined_token (Lexing.lexeme lexbuf)) }
157

    
158
and comment_line n = parse
159
  | eof     { error lexbuf Unfinished_comment }
160
  | "(*"    { comment_line (n+1) lexbuf }
161
  | "*)"    { if n > 0 then comment_line (n-1) lexbuf else token lexbuf }
162
  | newline { newline (comment_line n) lexbuf }
163
  | _       { comment_line n lexbuf }
164

    
165
and string_parse = parse
166
  | eof         { error lexbuf Unfinished_string }
167
  | "\\\"" as s { Buffer.add_string str_buf s; string_parse lexbuf}
168
  | '"'         { STRING (Buffer.contents str_buf) }
169
  | _ as c      { Buffer.add_char str_buf c; string_parse lexbuf }
(2-2/9)