OLD | NEW |
| (Empty) |
1 part of petitparser.smalltalk; | |
2 | |
3 /// Smalltalk grammar. | |
4 class SmalltalkGrammar extends GrammarParser { | |
5 SmalltalkGrammar() : super(new SmalltalkGrammarDefinition()); | |
6 } | |
7 | |
8 /// Smalltalk grammar definition. | |
9 class SmalltalkGrammarDefinition extends GrammarDefinition { | |
10 | |
11 // the original implementation used a handwritten parser to | |
12 // build special token objects | |
13 token(input) { | |
14 if (input is String) { | |
15 input = input.length == 1 ? char(input) : string(input); | |
16 } | |
17 return input.token().trim(ref(spacer)); | |
18 } | |
19 | |
20 // the original implementation uses a handwritten parser to | |
21 // efficiently consume whitespace and comments | |
22 spacer() => whitespace() | |
23 .or(ref(comment)); | |
24 comment() => char('"') | |
25 .seq(char('"').neg().star()) | |
26 .seq(char('"')); | |
27 | |
28 // the original implementation uses the hand written number | |
29 // parser of the system, this is the spec of the ANSI standard | |
30 number() => char('-').optional() | |
31 .seq(ref(positiveNumber)); | |
32 positiveNumber() => ref(scaledDecimal) | |
33 .or(ref(float)) | |
34 .or(ref(integer)); | |
35 | |
36 integer() => ref(radixInteger) | |
37 .or(ref(decimalInteger)); | |
38 decimalInteger() => ref(digits); | |
39 digits() => digit().plus(); | |
40 radixInteger() => ref(radixSpecifier) | |
41 .seq(char('r')) | |
42 .seq(ref(radixDigits)); | |
43 radixSpecifier() => ref(digits); | |
44 radixDigits() => pattern('0-9A-Z').plus(); | |
45 | |
46 float() => ref(mantissa) | |
47 .seq(ref(exponentLetter) | |
48 .seq(ref(exponent)) | |
49 .optional()); | |
50 mantissa() => ref(digits) | |
51 .seq(char('.')) | |
52 .seq(ref(digits)); | |
53 exponent() => char('-') | |
54 .seq(ref(decimalInteger)); | |
55 exponentLetter() => pattern('edq'); | |
56 | |
57 scaledDecimal() => ref(scaledMantissa) | |
58 .seq(char('s')) | |
59 .seq(ref(fractionalDigits).optional()); | |
60 scaledMantissa() => ref(decimalInteger) | |
61 .or(ref(mantissa)); | |
62 fractionalDigits() => ref(decimalInteger); | |
63 | |
64 // the original smalltalk grammar | |
65 array() => ref(token, '{') | |
66 .seq(ref(expression).separatedBy(ref(periodToken)) | |
67 .seq(ref(periodToken).optional()).optional()) | |
68 .seq(ref(token, '}')); | |
69 arrayItem() => ref(literal) | |
70 .or(ref(symbolLiteralArray)) | |
71 .or(ref(arrayLiteralArray)) | |
72 .or(ref(byteLiteralArray)); | |
73 arrayLiteral() => ref(token, '#(') | |
74 .seq(ref(arrayItem).star()) | |
75 .seq(ref(token, ')')); | |
76 arrayLiteralArray() => ref(token, '(') | |
77 .seq(ref(arrayItem).star()) | |
78 .seq(ref(token, ')')); | |
79 assignment() => ref(variable) | |
80 .seq(ref(assignmentToken)); | |
81 assignmentToken() => ref(token, ':='); | |
82 binary() => pattern('!%&*+,-/<=>?@\\|~').plus(); | |
83 binaryExpression() => ref(unaryExpression) | |
84 .seq(ref(binaryMessage).star()); | |
85 binaryMessage() => ref(binaryToken) | |
86 .seq(ref(unaryExpression)); | |
87 binaryMethod() => ref(binaryToken) | |
88 .seq(ref(variable)); | |
89 binaryPragma() => ref(binaryToken) | |
90 .seq(ref(arrayItem)); | |
91 binaryToken() => ref(token, ref(binary)); | |
92 block() => ref(token, '[') | |
93 .seq(ref(blockBody)) | |
94 .seq(ref(token, ']')); | |
95 blockArgument() => ref(token, ':') | |
96 .seq(ref(variable)); | |
97 blockArguments() => ref(blockArgumentsWith) | |
98 .or(ref(blockArgumentsWithout)); | |
99 blockArgumentsWith() => ref(blockArgument).plus() | |
100 .seq(ref(token, '|').or(ref(token, ']').and())); | |
101 blockArgumentsWithout() => epsilon(); | |
102 blockBody() => ref(blockArguments) | |
103 .seq(ref(sequence)); | |
104 byteLiteral() => ref(token, '#[') | |
105 .seq(ref(numberLiteral).star()) | |
106 .seq(ref(token, ']')); | |
107 byteLiteralArray() => ref(token, '[') | |
108 .seq(ref(numberLiteral).star()) | |
109 .seq(ref(token, ']')); | |
110 cascadeExpression() => ref(keywordExpression) | |
111 .seq(ref(cascadeMessage).star()); | |
112 cascadeMessage() => ref(token, ';') | |
113 .seq(ref(message)); | |
114 character() => char('\$').seq(any()); | |
115 characterLiteral() => ref(characterToken); | |
116 characterToken() => ref(token, ref(character)); | |
117 expression() => ref(assignment).star() | |
118 .seq(ref(cascadeExpression)); | |
119 falseLiteral() => ref(falseToken); | |
120 falseToken() => ref(token, 'false') | |
121 .seq(word().not()); | |
122 identifier() => pattern('a-zA-Z_') | |
123 .seq(word().star()); | |
124 identifierToken() => ref(token, ref(identifier)); | |
125 keyword() => ref(identifier) | |
126 .seq(char(':')); | |
127 keywordExpression() => ref(binaryExpression) | |
128 .seq(ref(keywordMessage).optional()); | |
129 keywordMessage() => ref(keywordToken) | |
130 .seq(ref(binaryExpression)).plus(); | |
131 keywordMethod() => ref(keywordToken) | |
132 .seq(ref(variable)).plus(); | |
133 keywordPragma() => ref(keywordToken) | |
134 .seq(ref(arrayItem)).plus(); | |
135 keywordToken() => ref(token, ref(keyword)); | |
136 literal() => ref(numberLiteral) | |
137 .or(ref(stringLiteral)) | |
138 .or(ref(characterLiteral)) | |
139 .or(ref(arrayLiteral)) | |
140 .or(ref(byteLiteral)) | |
141 .or(ref(symbolLiteral)) | |
142 .or(ref(nilLiteral)) | |
143 .or(ref(trueLiteral)) | |
144 .or(ref(falseLiteral)); | |
145 message() => ref(keywordMessage) | |
146 .or(ref(binaryMessage)) | |
147 .or(ref(unaryMessage)); | |
148 method() => ref(methodDeclaration) | |
149 .seq(ref(methodSequence)); | |
150 methodDeclaration() => ref(keywordMethod) | |
151 .or(ref(unaryMethod)) | |
152 .or(ref(binaryMethod)); | |
153 methodSequence() => ref(periodToken).star() | |
154 .seq(ref(pragmas)) | |
155 .seq(ref(periodToken).star()) | |
156 .seq(ref(temporaries)) | |
157 .seq(ref(periodToken).star()) | |
158 .seq(ref(pragmas)) | |
159 .seq(ref(periodToken).star()) | |
160 .seq(ref(statements)); | |
161 multiword() => ref(keyword).plus(); | |
162 nilLiteral() => ref(nilToken); | |
163 nilToken() => ref(token, 'nil') | |
164 .seq(word().not()); | |
165 numberLiteral() => ref(numberToken); | |
166 numberToken() => ref(token, ref(number)); | |
167 parens() => ref(token, '(') | |
168 .seq(ref(expression)) | |
169 .seq(ref(token, ')')); | |
170 period() => char('.'); | |
171 periodToken() => ref(token, ref(period)); | |
172 pragma() => ref(token, '<') | |
173 .seq(ref(pragmaMessage)) | |
174 .seq(ref(token, '>')); | |
175 pragmaMessage() => ref(keywordPragma) | |
176 .or(ref(unaryPragma)) | |
177 .or(ref(binaryPragma)); | |
178 pragmas() => ref(pragma).star(); | |
179 primary() => ref(literal) | |
180 .or(ref(variable)) | |
181 .or(ref(block)) | |
182 .or(ref(parens)) | |
183 .or(ref(array)); | |
184 answer() => ref(token, '^') | |
185 .seq(ref(expression)); | |
186 sequence() => ref(temporaries) | |
187 .seq(ref(periodToken).star()) | |
188 .seq(ref(statements)); | |
189 start() => ref(startMethod); | |
190 startMethod() => ref(method).end(); | |
191 statements() => ref(expression) | |
192 .seq(ref(periodToken).plus().seq(ref(statements)) | |
193 .or(ref(periodToken).star())) | |
194 .or(ref(answer).seq(ref(periodToken).star())) | |
195 .or(ref(periodToken).star()); | |
196 string_() => char('\'') | |
197 .seq(string('\'\'').or(pattern('^\'')).star()) | |
198 .seq(char('\'')); | |
199 stringLiteral() => ref(stringToken); | |
200 stringToken() => ref(token, ref(string_)); | |
201 symbol() => ref(unary) | |
202 .or(ref(binary)) | |
203 .or(ref(multiword)) | |
204 .or(ref(string_)); | |
205 symbolLiteral() => ref(token, '#').plus() | |
206 .seq(ref(token, ref(symbol))); | |
207 symbolLiteralArray() => ref(token, ref(symbol)); | |
208 temporaries() => ref(token, '|') | |
209 .seq(ref(variable).star()) | |
210 .seq(ref(token, '|')) | |
211 .optional(); | |
212 trueLiteral() => ref(trueToken); | |
213 trueToken() => ref(token, 'true') | |
214 .seq(word().not()); | |
215 unary() => ref(identifier) | |
216 .seq(char(':').not()); | |
217 unaryExpression() => ref(primary) | |
218 .seq(ref(unaryMessage).star()); | |
219 unaryMessage() => ref(unaryToken); | |
220 unaryMethod() => ref(identifierToken); | |
221 unaryPragma() => ref(identifierToken); | |
222 unaryToken() => ref(token, ref(unary)); | |
223 variable() => ref(identifierToken); | |
224 | |
225 } | |
OLD | NEW |