Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

lustrec / src / lexer_lustre.mll @ b38ffff3

History | View | Annotate | Download (4.93 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
  "and", AND;
57
  "or", OR;
58
  "xor", XOR;
59
  "mod", MOD;
60
  "pre", PRE;
61
  "div", DIV;
62
  "const", CONST;
63
  "assert", ASSERT;
64
  "lib", LIB;
65
  "prototype", PROTOTYPE;
66
]
67

    
68

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

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

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

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

    
90
rule token = parse
91
| "--@" { Buffer.clear buf;
92
	  spec_singleline lexbuf }
93
| "(*@" { Buffer.clear buf; 
94
	  spec_multiline 0 lexbuf }
95
| "--!" { Buffer.clear buf; 
96
	  annot_singleline lexbuf }
97
| "(*!" { Buffer.clear buf; 
98
	  annot_multiline 0 lexbuf }
99
| "(*"
100
    { comment 0 lexbuf }
101
| "--" [^ '!' '@'] notnewline* (newline|eof)
102
    { incr_line lexbuf;
103
      token lexbuf }
104
| newline
105
    { incr_line lexbuf;
106
      token lexbuf }
107
| blank +
108
    {token lexbuf}
109
| ['0'-'9'] ['0'-'9']* '.' ['0'-'9']*
110
    {FLOAT (float_of_string (Lexing.lexeme lexbuf))}
111
| ['0'-'9']+ 
112
    {INT (int_of_string (Lexing.lexeme lexbuf)) }
113
| ['0'-'9']+ '.' ['0'-'9']+ ('E'|'e') ('+'|'-') ['0'-'9'] ['0'-'9']* as s {REAL s}
114
| "tel." {TEL}
115
| "tel;" {TEL}
116
| "#open" { OPEN }
117
| ['_' 'a'-'z' 'A'-'Z'] [ '_' 'a'-'z' 'A'-'Z' '0'-'9']*
118
    {let s = Lexing.lexeme lexbuf in
119
    try
120
      Hashtbl.find keyword_table s
121
    with Not_found ->
122
      IDENT s}
123
| "->" {ARROW}
124
| "=>" {IMPL}
125
| "<=" {LTE}
126
| ">=" {GTE}
127
| "<>" {NEQ}
128
| '<' {LT}
129
| '>' {GT}
130
| "!=" {NEQ}
131
| '-' {MINUS}
132
| '+' {PLUS}
133
| '/' {DIV}
134
| '*' {MULT}
135
| '=' {EQ}
136
| '(' {LPAR}
137
| ')' {RPAR}
138
| '[' {LBRACKET}
139
| ']' {RBRACKET}
140
| '{' {LCUR}
141
| '}' {RCUR}
142
| ';' {SCOL}
143
| ':' {COL}
144
| ',' {COMMA}
145
| '=' {EQ}
146
| '/' {DIV}
147
| "&&" {AMPERAMPER}
148
| "||" {BARBAR}
149
| "::" {COLCOL}
150
| "^" {POWER}
151
| '"' {QUOTE}
152
| eof { EOF }
153
| _ { raise (Error (Location.curr lexbuf)) }
154

    
155
and comment n = parse
156
| eof
157
    { raise (Error (Location.curr lexbuf)) }
158
| "(*"
159
    { comment (n+1) lexbuf }
160
| "*)"
161
    { if n > 0 then comment (n-1) lexbuf else token lexbuf }
162
| newline
163
    { incr_line lexbuf;
164
      comment n lexbuf }
165
| _ { comment n lexbuf }
166

    
167
and annot_singleline = parse
168
  | newline { incr_line lexbuf; make_annot lexbuf (Buffer.contents buf) }
169
  | _ as c { Buffer.add_char buf c; annot_singleline lexbuf }
170

    
171
and annot_multiline n = parse
172
  | "*)" as s { 
173
    if n > 0 then 
174
      (Buffer.add_string buf s; annot_multiline (n-1) lexbuf) 
175
    else 
176
      make_annot lexbuf (Buffer.contents buf) }
177
  | "(*" as s { Buffer.add_string buf s; annot_multiline (n+1) lexbuf }
178
  | newline as s { incr_line lexbuf; Buffer.add_string buf s; annot_multiline n lexbuf }
179
  | _ as c { Buffer.add_char buf c; annot_multiline n lexbuf }
180

    
181
and spec_singleline = parse
182
  | newline { incr_line lexbuf; make_spec lexbuf (Buffer.contents buf) }
183
  | _ as c { Buffer.add_char buf c; spec_singleline lexbuf }
184

    
185
and spec_multiline n = parse
186
  | "*)" as s { if n > 0 then 
187
      (Buffer.add_string buf s; spec_multiline (n-1) lexbuf) 
188
    else 
189
      make_spec lexbuf (Buffer.contents buf) }
190
  | "(*" as s { Buffer.add_string buf s; spec_multiline (n+1) lexbuf }
191
  | newline as s { incr_line lexbuf; Buffer.add_string buf s; spec_multiline n lexbuf }
192
  | _ as c { Buffer.add_char buf c; spec_multiline n lexbuf }
193