-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcm.flex
More file actions
156 lines (133 loc) · 5.56 KB
/
Copy pathcm.flex
File metadata and controls
156 lines (133 loc) · 5.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
Created By: Fei Song
File Name: tiny.flex
To Build: jflex tiny.flex
and then after the parser is created
javac Lexer.java
*/
/* --------------------------Usercode Section------------------------ */
import java_cup.runtime.*;
%%
/* -----------------Options and Declarations Section----------------- */
/*
The name of the class JFlex will create will be Lexer.
Will write the code to the file Lexer.java.
*/
%class Lexer
%public
%{
private String fileName;
public boolean invalid_lex = false;
public Lexer(java.io.Reader in, String fileName) {
this(in);
this.fileName = fileName;
}
%}
%eofval{
return null;
%eofval};
/*
The current line number can be accessed with the variable yyline
and the current column number with the variable yycolumn.
*/
%line
%column
/*
Will switch to a CUP compatibility mode to interface with a CUP
generated parser.
*/
%cup
/*
Declarations
Code between %{ and %}, both of which must be at the beginning of a
line, will be copied letter to letter into the lexer class source.
Here you declare member variables and functions that are used inside
scanner actions.
*/
%{
/* To create a new java_cup.runtime.Symbol with information about
the current token, the token will have no value in this
case. */
private Symbol symbol(int type) {
// l=yyline
// r=yycolumn
return new Symbol(type, yyline, yycolumn);
}
/* Also creates a new java_cup.runtime.Symbol with information
about the current token, but this object has a value. */
private Symbol symbol(int type, Object value) {
// l=yyline
// r=yycolumn
return new Symbol(type, yyline, yycolumn, value);
}
%}
/*
Macro Declarations
These declarations are regular expressions that will be used latter
in the Lexical Rules Section.
*/
/* A line terminator is a \r (carriage return), \n (line feed), or
\r\n. */
LineTerminator = \r|\n|\r\n
/* White space is a line terminator, space, tab, or form feed. */
WhiteSpace = {LineTerminator} | [ \t\f]
mutliline_comment = "/\*""\*/"
/* A literal integer is is a number beginning with a number between
one and nine followed by zero or more numbers between zero and nine
or just a zero. */
digit = [0-9]
number = {digit}+
truth = "true" | "false"
/* A identifier integer is a word beginning a letter between A and
Z, a and z, or an underscore followed by zero or more letters
between A and Z, a and z, zero and nine, or an underscore. */
identifier = [_a-zA-Z][_a-zA-Z0-9]*
bad_identifier = [0-9][_a-zA-Z0-9]*
%%
/* ------------------------Lexical Rules Section---------------------- */
/*
This section contains regular expressions and actions, i.e. Java
code, that will be executed when the scanner matches the associated
regular expression. */
"bool" { return symbol(sym.BOOL); }
"if" { return symbol(sym.IF); }
"else" { return symbol(sym.ELSE); }
"int" { return symbol(sym.INT); }
"return" { return symbol(sym.RETURN); }
"void" { return symbol(sym.VOID); }
"while" { return symbol(sym.WHILE); }
{truth} { return symbol(sym.TRUTH, yytext().equals("true")); }
"+" { return symbol(sym.ADD); }
"-" { return symbol(sym.SUB); }
"*" { return symbol(sym.MULT); }
"/" { return symbol(sym.DIV); }
"<" { return symbol(sym.LT); }
">" { return symbol(sym.GT); }
"<=" { return symbol(sym.LTE); }
">=" { return symbol(sym.GTE); }
"==" { return symbol(sym.EQ); }
"!=" { return symbol(sym.NEQ); }
"~" { return symbol(sym.NOT); }
"&&" { return symbol(sym.AND); }
"||" { return symbol(sym.OR); }
"=" { return symbol(sym.ASSIGN); }
";" { return symbol(sym.SEMI); }
"(" { return symbol(sym.LPAREN); }
")" { return symbol(sym.RPAREN); }
"[" { return symbol(sym.LBRACKET); }
"]" { return symbol(sym.RBRACKET); }
"{" { return symbol(sym.LBRACE); }
"}" { return symbol(sym.RBRACE); }
"," { return symbol(sym.COMMA); }
{number} { return symbol(sym.NUM, Integer.parseInt(yytext())); }
{identifier} { return symbol(sym.ID, yytext()); }
{bad_identifier} { return symbol(sym.ERROR_TOKEN, yytext()); }
{WhiteSpace}+ { /* skip whitespace */ }
"//".* { /* Skip single-line comments */ }
"/*" !([^]* "*/" [^]*) "*/" { /* Skip multi-line comments */ }
"/*" !([^]* "*/" [^]*) { // Catch any other invalid character
invalid_lex = true;
System.err.println(this.fileName + ":" + (yyline + 1) + ":" + (yycolumn + 1) + ": Unterminated comment");}
[^] { // Catch any other invalid character
invalid_lex = true;
System.err.println(this.fileName + ":" + (yyline + 1) + ":" + (yycolumn + 1) + ": Invalid character '" + yytext() + "'");}