ibelieve / krunch Goto Github PK
View Code? Open in Web Editor NEWKotlin parser/combinator framework
License: Apache License 2.0
Kotlin parser/combinator framework
License: Apache License 2.0
The Title Says It All.
Hello!
I'm trying to implement a simple calculator-like grammar with variables. It's supposed to parse arbitrary expressions and variable assignments like:
a = 1 + 2
10 + a
So the code I came up with, looking at the provided calculator grammar sample, is as follows (only + operator supported for the sake of brevity):
object SampleParser: RegexParsers<Expr>() {
val number = literal("[0-9]+".toRegex())
val identifier = literal("[a-z]+".toRegex())
val variable = identifier map { Var(it) }
val value = number map { Value(it.toInt()) }
val atom = oneOf(variable, value)
val expr = atom and some(literal("+") and atom) map {
it.second.fold(it.first) { left, (_, right) -> Add(left, right) }
}
val assign = identifier and literal("=") and expr map { Assign(it.first.first, it.second) }
val stmt = oneOf(assign, expr)
override val goal = stmt
}
So my issue is that the parser cannot distinguish expr
and assign
. Only the first rule in oneOf
gets parsed correctly, the second one is not even attempted due to the first one failing:
> a = 2
result = 2
> a + 2
Failed to parse expression!
ERROR: Expected: '=' (1:3)
a + 2
^
After coming across +
in the second example, I expect it to backtrack from assign
and try the next one in oneOf
, which is expr
- but that does not happen. What am I doing wrong?
The Expr
nodes are implemented along the lines of:
sealed class Expr {
abstract fun evaluate(ctx: CalcContext): Int
}
class Value(private val value: Int): Expr() {
override fun evaluate(ctx: CalcContext)= value
}
class Var(private val varName: String): Expr() {
override fun evaluate(ctx: CalcContext)= ctx.getValue(varName)
}
class Add(private val left: Expr, private val right: Expr): Expr() {
override fun evaluate(ctx: CalcContext) = left.evaluate(ctx) + right.evaluate(ctx)
}
class Assign(private val varName: String, private val expr: Expr): Expr() {
override fun evaluate(ctx: CalcContext): Int {
val value = expr.evaluate(ctx);
ctx.setValue(varName, value)
return value
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.