package cangjie_tpc::prism4cj.prism
abstract class PrismToString {
static func toString(grammar: Grammar): String {
let builder: StringBuilder = StringBuilder()
toString(builder, CacheImpl(), grammar)
return builder.toString()
}
static func toString(token: Token): String {
let builder: StringBuilder = StringBuilder()
toString(builder, CacheImpl(), token)
return builder.toString()
}
static func toString(pattern: Pattern): String {
let builder: StringBuilder = StringBuilder()
toString(builder, CacheImpl(), pattern)
return builder.toString()
}
private static func toString(builder: StringBuilder, cache: Cache, grammar: Grammar): Unit {
builder.append("Grammar{id=0x")
builder.append(grammar.hashCode())
builder.append(",name=\"")
builder.append(grammar.name())
builder.append('\"')
if (cache.visitedGrammar(grammar)) {
builder.append(",[...]")
} else {
cache.markVisitedGrammar(grammar)
builder.append(",tokens=[")
var first: Bool = true
for (i in 0..grammar.tokens().size) {
if (first) {
first = false
} else {
builder.append(',')
}
toString(builder, cache, grammar.tokens()[i])
}
builder.append(']')
}
builder.append('}')
}
private static func toString(builder: StringBuilder, cache: Cache, token: Token) {
builder.append("Token{id=0x")
builder.append(token.hashCode())
builder.append(",name=\"")
builder.append(token.name())
builder.append('\"')
if (cache.visitedToken(token)) {
builder.append(",[...]")
} else {
cache.markVisitedToken(token)
builder.append(",patterns=[")
var first: Bool = true
for (i in 0..token.patterns().size) {
if (first) {
first = false
} else {
builder.append(',')
}
toString(builder, cache, token.patterns()[i])
}
builder.append(']')
}
builder.append('}')
}
private static func toString(builder: StringBuilder, cache: Cache, pattern: Pattern) {
builder.append("Pattern{id=0x")
builder.append(pattern.hashCode())
if (cache.visitedPattern(pattern)) {
builder.append(",[...]")
} else {
cache.markVisitedPattern(pattern)
builder.append(",regex=\"")
builder.append(pattern.regex().string())
builder.append('\"')
if (pattern.lookbehind()) {
builder.append(",lookbehind=true")
}
if (pattern.greedy()) {
builder.append(",greedy=true")
}
match (pattern.alias()) {
case Some(v) =>
builder.append(",alias=\"")
builder.append(v)
builder.append('\"')
case None =>
builder.append(",alias=\"")
builder.append("None")
builder.append('\"')
}
let inside: ?Grammar = pattern.inside()
if (let Some(v) <- inside) {
builder.append(",inside=")
toString(builder, cache, v)
}
}
builder.append('}')
}
}
interface Cache {
func visitedGrammar(grammar: Grammar): Bool
func markVisitedGrammar(grammar: Grammar): Unit
func visitedToken(token: Token): Bool
func markVisitedToken(token: Token): Unit
func visitedPattern(pattern: Pattern): Bool
func markVisitedPattern(pattern: Pattern): Unit
}
class CacheImpl <: Cache {
var cache: CacheProp = CacheProp()
public override func visitedGrammar(grammar: Grammar): Bool {
if (cache.grammar.isSome() && cache.grammar == grammar) {
return true
}
return false
}
public override func markVisitedGrammar(grammar: Grammar): Unit {
cache.grammar = grammar
}
public override func visitedToken(token: Token): Bool {
if (cache.token.isSome() && cache.token == token) {
return true
}
return false
}
public override func markVisitedToken(token: Token): Unit {
cache.token = token
}
public override func visitedPattern(pattern: Pattern): Bool {
if (cache.pattern.isSome() && cache.pattern == pattern) {
return true
}
return false
}
public override func markVisitedPattern(pattern: Pattern): Unit {
cache.pattern = pattern
}
}
class CacheProp {
var _grammar: ?Grammar = None
public mut prop grammar: ?Grammar {
get() {
_grammar
}
set(v) {
this._grammar = v
}
}
var _token: ?Token = None
public mut prop token: ?Token {
get() {
_token
}
set(v) {
this._token = v
}
}
var _pattern: ?Pattern = None
public mut prop pattern: ?Pattern {
get() {
_pattern
}
set(v) {
this._pattern = v
}
}
}