equal
deleted
inserted
replaced
58 case class CharParser(c: Char) extends Parser[String, Char] { |
58 case class CharParser(c: Char) extends Parser[String, Char] { |
59 def parse(in: String) = |
59 def parse(in: String) = |
60 if (in != "" && in.head == c) Set((c, in.tail)) else Set() |
60 if (in != "" && in.head == c) Set((c, in.tail)) else Set() |
61 } |
61 } |
62 |
62 |
|
63 |
|
64 |
63 val ap = CharParser('a') |
65 val ap = CharParser('a') |
64 val bp = CharParser('b') |
66 val bp = CharParser('b') |
65 |
67 |
|
68 print(ap.parse("aade")) |
|
69 |
66 val abp = SeqParser(ap, bp) |
70 val abp = SeqParser(ap, bp) |
|
71 print(abp.parse("abade")) |
|
72 |
|
73 val abp = AltParser(ap, bp) |
|
74 print(abp.parse("abc")) |
|
75 |
67 MapParser(abp, ab => s"$ab").parse("abc") |
76 MapParser(abp, ab => s"$ab").parse("abc") |
68 |
77 |
69 // an atomic parser for parsing strings according to a regex |
78 // an atomic parser for parsing strings according to a regex |
70 import scala.util.matching.Regex |
79 import scala.util.matching.Regex |
71 |
80 |
76 } |
85 } |
77 } |
86 } |
78 |
87 |
79 // atomic parsers for numbers and "verbatim" strings |
88 // atomic parsers for numbers and "verbatim" strings |
80 val NumParser = RegexParser("[0-9]+".r) |
89 val NumParser = RegexParser("[0-9]+".r) |
|
90 NumParser.parse("123abc345") |
|
91 |
81 def StrParser(s: String) = RegexParser(Regex.quote(s).r) |
92 def StrParser(s: String) = RegexParser(Regex.quote(s).r) |
82 |
93 |
83 NumParser.parse("123a123bc") |
94 NumParser.parse("123a123bc") |
84 StrParser("else").parse("elsethen") |
95 StrParser("else").parse("elsethen") |
85 |
96 |
92 |
103 |
93 // the following string interpolation allows us to write |
104 // the following string interpolation allows us to write |
94 // StrParser(_some_string_) more conveniently as |
105 // StrParser(_some_string_) more conveniently as |
95 // |
106 // |
96 // p"<_some_string_>" |
107 // p"<_some_string_>" |
|
108 |
|
109 |
97 |
110 |
98 extension (sc: StringContext) |
111 extension (sc: StringContext) |
99 def p(args: Any*) = StrParser(sc.s(args*)) |
112 def p(args: Any*) = StrParser(sc.s(args*)) |
100 |
113 |
101 |
114 |
122 // with this NumParserInt can now be written more conveniently |
135 // with this NumParserInt can now be written more conveniently |
123 // as: |
136 // as: |
124 |
137 |
125 val NumParserInt2 = NumParser.map(_.toInt) |
138 val NumParserInt2 = NumParser.map(_.toInt) |
126 |
139 |
127 val x = 1 + 3 |
140 |
128 |
141 |
129 // A parser for palindromes (just returns them as string) |
142 // A parser for palindromes (just returns them as string) |
130 // since the parser is recursive it needs to be lazy |
143 // since the parser is recursive it needs to be lazy |
131 lazy val Pal : Parser[String, String] = { |
144 lazy val Pal : Parser[String, String] = { |
132 (p"a" ~ Pal ~ p"a").map{ case ((x, y), z) => s"$x$y$z" } || |
145 (p"a" ~ Pal ~ p"a").map{ case ((x, y), z) => s"$x$y$z" } || |
133 (p"b" ~ Pal ~ p"b").map{ case ((x, y), z) => s"$x$y$z" } || |
146 (p"b" ~ Pal ~ p"b").map{ case ((x, y), z) => s"$x$y$z" } || |
134 p"a" || p"b" || p"" |
147 p"a" || p"b" || p"" |
135 } |
148 } |
136 |
149 |
137 // examples |
150 // examples |
138 Pal.parse_all("abacaba") |
151 Pal.parse("abaaba") |
139 Pal.parse("abacaaba") |
152 Pal.parse("abacaaba") |
140 |
153 |
141 println("Palindrome: " + Pal.parse_all("abaaaba")) |
154 println("Palindrome: " + Pal.parse_all("abaaaba")) |
142 |
155 |
143 // A parser for wellnested parentheses |
156 // A parser for wellnested parentheses |
154 println(P.parse_all("(((()()))()))")) |
167 println(P.parse_all("(((()()))()))")) |
155 println(P.parse_all(")(")) |
168 println(P.parse_all(")(")) |
156 println(P.parse_all("()")) |
169 println(P.parse_all("()")) |
157 |
170 |
158 // A parser for arithmetic expressions (Terms and Factors) |
171 // A parser for arithmetic expressions (Terms and Factors) |
|
172 |
159 |
173 |
160 lazy val E: Parser[String, Int] = { |
174 lazy val E: Parser[String, Int] = { |
161 (T ~ p"+" ~ E).map{ case ((x, _), z) => x + z } || |
175 (T ~ p"+" ~ E).map{ case ((x, _), z) => x + z } || |
162 (T ~ p"-" ~ E).map{ case ((x, _), z) => x - z } || T } |
176 (T ~ p"-" ~ E).map{ case ((x, _), z) => x - z } || T } |
163 lazy val T: Parser[String, Int] = { |
177 lazy val T: Parser[String, Int] = { |
176 println(E.parse_all("(1+2)+3")) |
190 println(E.parse_all("(1+2)+3")) |
177 println(E.parse_all("1+2+3")) |
191 println(E.parse_all("1+2+3")) |
178 |
192 |
179 |
193 |
180 // with parser combinators (and many other parsing algorithms) |
194 // with parser combinators (and many other parsing algorithms) |
181 // no left-recursion is allowed, otherwise the will loop; |
195 // no left-recursion is allowed, otherwise they will loop; |
182 // newer versions of Scala (3.5) will actually give a warning |
196 // newer versions of Scala (3.5+) will actually give a warning |
183 // about this |
197 // about this |
184 |
198 |
185 /* |
199 /* |
186 lazy val EL: Parser[String, Int] = |
200 lazy val EL: Parser[String, Int] = |
187 ((EL ~ p"+" ~ EL).map{ case ((x, y), z) => x + z} || |
201 ((EL ~ p"+" ~ EL).map{ case ((x, y), z) => x + z} || |