Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

lustrec / src / lexer_lustre.mll @ 53206908

History | View | Annotate | Download (5.35 KB)

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
open Parser_lustre
14
open Utils
15

    
16
exception Error of Location.t
17

    
18
(* As advised by Caml documentation. This way a single lexer rule is
19
   used to handle all the possible keywords. *)
20
let keyword_table =
21
  create_hashtable 20 [
22
  "function", FUNCTION;
23
  "struct", STRUCT;
24
  "enum", ENUM;
25
  "automaton", AUTOMATON;
26
  "state", STATE;
27
  "until", UNTIL;
28
  "unless", UNLESS;
29
  "last", LAST;
30
  "resume", RESUME;
31
  "restart", RESTART;
32
  "if", IF;
33
  "then", THEN;
34
  "else", ELSE;
35
  "merge", MERGE;
36
  "arrow", ARROW;
37
  "fby", FBY;
38
  "when", WHEN;
39
  "whenot", WHENNOT;
40
  "every", EVERY;
41
  "node", NODE;
42
  "let", LET;
43
  "tel", TEL;
44
  "returns", RETURNS;
45
  "var", VAR;
46
  "imported", IMPORTED;
47
  "wcet", WCET;
48
  "type", TYPE;
49
  "int", TINT;
50
  "bool", TBOOL;
51
  (* "float", TFLOAT; *)
52
  "real", TREAL;
53
  "clock", TCLOCK;
54
  "not", NOT;
55
  "tail", TAIL;
56
  "true", TRUE;
57
  "false", FALSE;
58
  "and", AND;
59
  "or", OR;
60
  "xor", XOR;
61
  "mod", MOD;
62
  "pre", PRE;
63
  "div", DIV;
64
  "const", CONST;
65
  "assert", ASSERT;
66
  "lib", LIB;
67
  "prototype", PROTOTYPE;
68
]
69

    
70

    
71
(* Buffer for parsing specification/annotation *)
72
let buf = Buffer.create 1024
73

    
74
let make_annot lexbuf s = 
75
  try
76
    let ann = LexerLustreSpec.annot s in
77
    ANNOT ann
78
  with _ -> (Format.eprintf "Impossible to parse the following annotation:@.%s@.@?" s; exit 1)
79

    
80
let make_spec lexbuf s = 
81
  try
82
    let ns = LexerLustreSpec.spec s in
83
    NODESPEC ns
84
  with _ -> (Format.eprintf "Impossible to parse the following node specification:@.%s@.@?" s; exit 1)
85
   
86
}
87

    
88
let newline = ('\010' | '\013' | "\013\010")
89
let notnewline = [^ '\010' '\013']
90
let blank = [' ' '\009' '\012']
91

    
92
  rule token = parse
93
  | "--@" { Buffer.clear buf;
94
	    spec_singleline lexbuf }
95
  | "(*@" { Buffer.clear buf; 
96
	    spec_multiline 0 lexbuf }
97
  | "--!" { Buffer.clear buf; 
98
	    annot_singleline lexbuf }
99
  | "(*!" { Buffer.clear buf; 
100
	    annot_multiline 0 lexbuf }
101
  | "(*"
102
      { comment 0 lexbuf }
103
  | "--" [^ '!' '@'] notnewline* (newline|eof)
104
      { incr_line lexbuf;
105
	token lexbuf }
106
  | newline
107
      { incr_line lexbuf;
108
	token lexbuf }
109
  | blank +
110
      {token lexbuf}
111

    
112
  | ((['0'-'9']+ as l)  '.' (['0'-'9']* as r) ('E'|'e') (('+'|'-')? ['0'-'9']+ as exp)) as s
113
      {REAL (Num.num_of_string (l^r), String.length r + -1 * int_of_string exp , s)}
114
  | ((['0'-'9']+ as l) '.' (['0'-'9']* as r)) as s
115
      {REAL (Num.num_of_string (l^r), String.length r, s)}
116
  | ['0'-'9']+ 
117
      {INT (int_of_string (Lexing.lexeme lexbuf)) }
118
  | "tel." {TEL}
119
  | "tel;" {TEL}
120
  | "#open" { OPEN }
121
  | ['_' 'a'-'z'] [ '_' 'a'-'z' 'A'-'Z' '0'-'9']*
122
      {let s = Lexing.lexeme lexbuf in
123
       try
124
	 Hashtbl.find keyword_table s
125
       with Not_found ->
126
	 IDENT s}
127
  | ['A'-'Z'] [ '_' 'a'-'z' 'A'-'Z' '0'-'9']*
128
      {let s = Lexing.lexeme lexbuf in
129
       try
130
	 Hashtbl.find keyword_table s
131
       with Not_found ->
132
	 UIDENT s}
133
  | "->" {ARROW}
134
  | "=>" {IMPL}
135
  | "<=" {LTE}
136
  | ">=" {GTE}
137
  | "<>" {NEQ}
138
  | '<' {LT}
139
  | '>' {GT}
140
  | "!=" {NEQ}
141
  | '-' {MINUS}
142
  | '+' {PLUS}
143
  | '/' {DIV}
144
  | '*' {MULT}
145
  | '=' {EQ}
146
  | '(' {LPAR}
147
  | ')' {RPAR}
148
  | '[' {LBRACKET}
149
  | ']' {RBRACKET}
150
  | '{' {LCUR}
151
  | '}' {RCUR}
152
  | ';' {SCOL}
153
  | ':' {COL}
154
  | ',' {COMMA}
155
  | '=' {EQ}
156
  | '/' {DIV}
157
  | "&&" {AMPERAMPER}
158
  | "||" {BARBAR}
159
  | "::" {COLCOL}
160
  | "^" {POWER}
161
  | '"' {QUOTE}
162
  | eof { EOF }
163
  | _ { raise (Error (Location.curr lexbuf)) }
164

    
165
and comment n = parse
166
    | eof
167
	{ raise (Error (Location.curr lexbuf)) }
168
    | "(*"
169
	{ comment (n+1) lexbuf }
170
    | "*)"
171
	{ if n > 0 then comment (n-1) lexbuf else token lexbuf }
172
    | newline
173
	{ incr_line lexbuf;
174
	  comment n lexbuf }
175
    | _ { comment n lexbuf }
176

    
177
and annot_singleline = parse
178
    | newline { incr_line lexbuf; make_annot lexbuf (Buffer.contents buf) }
179
    | _ as c { Buffer.add_char buf c; annot_singleline lexbuf }
180

    
181
and annot_multiline n = parse
182
    | "*)" as s { 
183
      if n > 0 then 
184
	(Buffer.add_string buf s; annot_multiline (n-1) lexbuf) 
185
      else 
186
	make_annot lexbuf (Buffer.contents buf) }
187
    | "(*" as s { Buffer.add_string buf s; annot_multiline (n+1) lexbuf }
188
    | newline as s { incr_line lexbuf; Buffer.add_string buf s; annot_multiline n lexbuf }
189
    | _ as c { Buffer.add_char buf c; annot_multiline n lexbuf }
190

    
191
and spec_singleline = parse
192
    | newline { incr_line lexbuf; make_spec lexbuf (Buffer.contents buf) }
193
    | _ as c { Buffer.add_char buf c; spec_singleline lexbuf }
194

    
195
and spec_multiline n = parse
196
    | "*)" as s { if n > 0 then 
197
	(Buffer.add_string buf s; spec_multiline (n-1) lexbuf) 
198
      else 
199
	make_spec lexbuf (Buffer.contents buf) }
200
    | "(*" as s { Buffer.add_string buf s; spec_multiline (n+1) lexbuf }
201
    | newline as s { incr_line lexbuf; Buffer.add_string buf s; spec_multiline n lexbuf }
202
    | _ as c { Buffer.add_char buf c; spec_multiline n lexbuf }
203