You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The `map` function can convert the result upon successful parsing. Its parameters include the parser itself and a transformation function. At the end of line 3, we use the question mark operator `?`. If parsing succeeds and the value is non-empty, the operator allows us to directly access the tuple containing the value and remaining string; otherwise, it returns the empty value in advance. After obtaining the value, we apply the transformation function. Utilizing this, we can map the characters corresponding to arithmetic operators and parentheses into their corresponding enum values.
87
+
The `map` function can convert the result upon successful parsing. Its parameters include the parser itself and a transformation function. After obtaining the value, we apply the transformation function. Utilizing this, we can map the characters corresponding to arithmetic operators and parentheses into their corresponding enum values.
// Non-empty value v is in Some(v), empty value None is directly returned
93
-
let (value, rest) = self.parse(input)?
93
+
let (value, rest) = match self.parse(input) {
94
+
Some(v) => v
95
+
None => return None
96
+
}
94
97
Some((f(value), rest))
95
98
},) }
96
99
@@ -109,13 +112,19 @@ let symbol : Lexer[Token] = pchar(
109
112
},)
110
113
```
111
114
112
-
Let's look at other combinators. We've seen other pattern matching rules like matching `a` followed by `b`, `a` or `b`, zero or more occurrences of `a`, etc. Each combinator is simple to implement, and let's do it one by one. For matching `a` and then `b`, we first use `self` for parsing, as shown in line 3. After obtaining the value and the remaining string with the question mark operator `?`, we use another parser to parse the remaining string, as shown in line 4. The two outputs are returned as a tuple. Then, for matching `a` or `b`, we will pattern match the result of parsing using `self`. If empty, we use the result of another parser; otherwise, we return the current result.
115
+
Let's look at other combinators. We've seen other pattern matching rules like matching `a` followed by `b`, `a` or `b`, zero or more occurrences of `a`, etc. Each combinator is simple to implement, and let's do it one by one. For matching `a` and then `b`, we first use `self` for parsing, as shown in line 3. After obtaining the value and the remaining string, we use another parser to parse the remaining string, as shown in line 7. The two outputs are returned as a tuple. Then, for matching `a` or `b`, we will pattern match the result of parsing using `self`. If empty, we use the result of another parser; otherwise, we return the current result.
let (token_list, rest_string) = tokens.parse(str)?
316
-
let (expr, rest_token) : (E, @immut/list.T[Token]) = recursive_parser().parse(token_list)?
324
+
let (token_list, rest_string) = match tokens.parse(str) {
325
+
Some(v) => v
326
+
None => return None
327
+
}
328
+
let (expr, rest_token) : (E, @immut/list.T[Token]) = match recursive_parser().parse(token_list) {
329
+
Some(v) => v
330
+
None => return None
331
+
}
317
332
Some(expr, rest_string, rest_token)
318
333
}
319
334
```
320
335
321
-
Thus, we only need to define different implementations and specify which one to use in MoonBit. The former involves defining different methods for the data structure to meet the requirements of the interface, such as the `number` method in lines 4 and 5. The latter specifies the return type of functions to indicate the specific type parameter, as shown in lines 8 and 10. In line 8, we will obtain the expression tree constructed from enums, while in line 10 we can directly obtain the result. You can also add other interpretations, like converting an expression into a formatted string by removing extra parentheses and whitespaces.
336
+
Thus, we only need to define different implementations and specify which one to use in MoonBit. The former involves defining different methods for the data structure to meet the requirements of the interface, such as the `number` method in lines 4 and 5. The latter specifies the return type of functions to indicate the specific type parameter, as shown in lines 8 and 12. In line 8, we will obtain the expression tree constructed from enums, while in line 12 we can directly obtain the result. You can also add other interpretations, like converting an expression into a formatted string by removing extra parentheses and whitespaces.
322
337
323
338
```moonbit no-check
324
339
enum Expression { ... } derive(Show) // Implementation of syntax tree
0 commit comments