лексер

  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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
$EXTERN Add, Sub, Put, Get, Open, Exit, Arg, Prout, Symb, Append;
$ENTRY Lexer {
:eArg = <DoLexer : <GetSymbol 0 1 : <LoadFile :eArg>>>;
}
$ENTRY FnLexer {
:eArg = <Lexer :eArg>;
}
Inc {
tArg = <Add 1 tArg>;
}
Dec {
tArg = <Sub tArg 1>;
}
DoLexer {
(tSpace Space tLine tCol) :eTail = <DoLexer :eTail>;
(';' Other tLine tCol):eTail = ((Semicolon (tLine tCol) ';') : <DoLexer :eTail>);
(':' Other tLine tCol):eTail = ((Colon (tLine tCol) ':') : <DoLexer :eTail>);
('<' Other tLine tCol):eTail = ((OpenCall (tLine tCol) '<') : <DoLexer :eTail>);
('>' Other tLine tCol):eTail = ((CloseCall (tLine tCol) '>') : <DoLexer :eTail>);
('(' Other tLine tCol):eTail = ((OpenBracket (tLine tCol) '(') : <DoLexer :eTail>);
(')' Other tLine tCol):eTail = ((CloseBracket (tLine tCol) ')') : <DoLexer :eTail>);
('{' Other tLine tCol):eTail = ((OpenBlock (tLine tCol) '{') : <DoLexer :eTail>);
('}' Other tLine tCol):eTail = ((CloseBlock (tLine tCol) '}') : <DoLexer :eTail>);
('=' Other tLine tCol):eTail = ((Assign (tLine tCol) '=') : <DoLexer :eTail>);
('&' Other tLine tCol):eTail = ((Ref (tLine tCol) '&') : <DoLexer :eTail>);
(',' Other tLine tCol) :eTail = ((Comma (tLine tCol) ',') : <DoLexer :eTail>);
(0 EOF tLine tCol):eTail = ((EOF (tLine tCol) '!'));
/*Переменные без индексов*/
(tChar LoLetter tLine tCol) :eTail =
<ReadSimpleVariable tLine tCol (tChar) :eTail>;
('$' Other tLine tCol) :eTail =
<ReadDirective tLine tCol ('$') :eTail>;
(tChar Digit tLine tCol):eTail =
<ReadNumber tLine tCol (tChar) :eTail>;
(tChar UpLetter tLine tCol) :eTail =
<ReadName tLine tCol (tChar) :eTail>;
('/' Other tLine tCol) ('*' Other tLine tCol2) :eTail =
<SkipComment :eTail>;
('\'' Other tLine tCol) :eTail = <ReadChars :eTail>;
}
ReadSimpleVariable {
tStartVarLine tStartVarCol eName (tLetter UpLetter tLine tCol) :eTail =
<ReadSimpleVariable tStartVarLine tStartVarCol (<PushBack eName tLetter>) :eTail>;
tStartVarLine tStartVarCol eName (tLetter LoLetter tLine tCol) :eTail =
<ReadSimpleVariable tStartVarLine tStartVarCol (<PushBack eName tLetter>) :eTail>;
tStartVarLine tStartVarCol eName (tLetter Digit tLine tCol) :eTail =
<ReadSimpleVariable tStartVarLine tStartVarCol (<PushBack eName tLetter>) :eTail>;
tStartVarLine tStartVarCol eName :eTail =
((Variable (tStartVarLine tStartVarCol) 't'eName) : <DoLexer :eTail>);
}
ReadName {
tStartVarLine tStartVarCol eName (tLetter UpLetter tLine tCol) :eTail =
<ReadName tStartVarLine tStartVarCol (<PushBack eName tLetter>) :eTail>;
tStartVarLine tStartVarCol eName (tLetter LoLetter tLine tCol) :eTail =
<ReadName tStartVarLine tStartVarCol (<PushBack eName tLetter>) :eTail>;
tStartVarLine tStartVarCol eName (tLetter Digit tLine tCol) :eTail =
<ReadName tStartVarLine tStartVarCol (<PushBack eName tLetter>) :eTail>;
tStartVarLine tStartVarCol eName ('-' Other tLine tCol) :eTail =
<ReadName tStartVarLine tStartVarCol (<PushBack eName '_'>) :eTail>;
tStartVarLine tStartVarCol eName ('_' Other tLine tCol) :eTail =
<ReadName tStartVarLine tStartVarCol (<PushBack eName '_'>) :eTail>;
tStartVarLine tStartVarCol eName :eTail =
((Name (tStartVarLine tStartVarCol) :eName) : <DoLexer :eTail>);
}
ReadDirective {
tStartVarLine tStartVarCol eName (tLetter UpLetter tLine tCol) :eTail =
<ReadDirective tStartVarLine tStartVarCol (<PushBack eName tLetter>) :eTail>;
tStartVarLine tStartVarCol eName :eTail =
((Directive (tStartVarLine tStartVarCol) :eName) : <DoLexer :eTail>);
}
ReadNumber {
tStartVarLine tStartVarCol eName (tLetter Digit tLine tCol) :eTail =
<ReadNumber tStartVarLine tStartVarCol (<PushBack eName tLetter>) :eTail>;
tStartVarLine tStartVarCol eName (tLetter tType tLine tCol) :eTail =
((Number (tStartVarLine tStartVarCol) :eName) : <DoLexer (tLetter tType tLine tCol) :eTail>);
}
SkipComment {
('*' Other tLine tCol) ('/' Other tLine tCol2) :eTail = <DoLexer :eTail>;
(0 EOF tLine tCol) = (Error (tLine tCol) 'Unclosed comment') (EOF (tLine tCol));
tOtherChar :eTail = <SkipComment :eTail>;
}
PushBack {
eName tLetter = :eName tLetter;
}
ReadChars {
('\'' Other tLine tCol) :eTail = <DoLexer :eTail>;
(0 EOF tLine tCol) :eTail =
((Error (tLine tCol) 'Unclosed quote at end of file') (EOF (tLine tCol)));
('\\' Other tLine tCol) :eTail = <ReadChars-HandleEscape :eTail>;
('\n' Space tLine tCol) :eTail =
((Error (tLine tCol) 'Unclosed quote at end of line') : <DoLexer :eTail>);
(tChar tClass tLine tCol) :eTail =
((Char (tLine tCol) tChar) : <ReadChars :eTail>);
}
ReadChars-HandleEscape {
('n' LoLetter tLine tCol) :eTail = ((Char (tLine tCol) '\n') : <ReadChars :eTail>);
('t' LoLetter tLine tCol) :eTail = ((Char (tLine tCol) '\t') : <ReadChars :eTail>);
('\\' Other tLine tCol) :eTail = ((Char (tLine tCol) '\\') : <ReadChars :eTail>);
('\'' Other tLine tCol) :eTail = ((Char (tLine tCol) '\'') : <ReadChars :eTail>);
/* ('x' LoLetter tLine tCol) :eTail = <ReadChars-HandleEscape-HexCode :eTail>; */
('\n' Space tLine tCol) :eTail = <ReadChars :eTail>;
(tOther tClass tLine tCol) :eTail =
((Error (tLine tCol) 'Bad symbol in escape') :
<ReadChars (tOther tClass tLine tCol) :eTail>);
}
LoadFile {
/* пусто */ = <Prout 'Expected file name'><Exit 1>;
:eFileName =
<Open 'r' 1 :eFileName>
<DoLoadFile>;
}
$EXTERN Concat;
DoLoadFile {
:eChars 0 = <Concat eChars ('\n' 0)>;
:eChars = <Concat eChars ('\n' : <DoLoadFile <Get 1>>)>;
}
Class {
tChar =
<DoClass
tChar
(UpLetter 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
(LoLetter 'abcdefghijklmnopqrstuvwxyz')
(Digit '1234567890')
(Space ' \t\n')
(EOF 0)
>;
}
DoClass {
tChar (tClass tChar :eTail) :eClasses = tClass;
tChar (tClass tOtherChar :eTail) :eClasses = <DoClass tChar (tClass :eTail) :eClasses>;
tChar (tClass) :eClasses = <DoClass tChar :eClasses>;
tChar = Other;
}
GetSymbol {
tLine tCol 0 :eText =
((0 EOF tLine tCol));
tLine tCol '\n' :eText =
(('\n' Space tLine tCol) : <GetSymbol <Inc tLine> 1 :eText>);
tLine tCol tChar :eText =
((tChar <Class tChar> tLine tCol) : <GetSymbol tLine tCol :eText>);
}