duangsuse::Echo
https://github.com/duangsuse/SuicideBot-Cpp 代码已经上传至 #GitHub #CPlusplus #project #Telegram
Tg bot :: Error! connect: Connection refused 🌚...我得找 Boost asio 写个支持 http_proxy 的 client... 欸
This media is not supported in your browser
VIEW IN TELEGRAM
/suicide @dSuicideBot
因为无效我就不继续折腾了... 我写个 JSON Parser 先吧... (汗)
那么我们来学学使用 #C CMake:
cmake_minimum_required(VERSION cmake_min_version)
project(project_name)
set(name value)
CMAKE_CXX_FLAGS
Boost_USE_MULTITHREADED
CMAKE_THREADS_LIBS_INIT
find_package(packageName [COMPONENTS {packageName}] [REQUIRED])
PKG_FOUND
PKG_INCLUDE_DIRS
PKG_LIBRARIES
include_directories(dirs)
add_definitions(defs)
if (case)
endif()
add_executable(targetName sources)
target_link_libraries(target libraries)
这就可以用来写简单的 CLI 程序了 🐱
那么我们来学学使用 #C CMake:
cmake_minimum_required(VERSION cmake_min_version)
project(project_name)
set(name value)
CMAKE_CXX_FLAGS
Boost_USE_MULTITHREADED
CMAKE_THREADS_LIBS_INIT
find_package(packageName [COMPONENTS {packageName}] [REQUIRED])
PKG_FOUND
PKG_INCLUDE_DIRS
PKG_LIBRARIES
include_directories(dirs)
add_definitions(defs)
if (case)
endif()
add_executable(targetName sources)
target_link_libraries(target libraries)
这就可以用来写简单的 CLI 程序了 🐱
停,现在是 DJson 的设计时间。今天暂时只来设计。 #Java
Json 是什么呢? json.org
Json 里可以有这些类型的『数据』
DJson 称之为『Type』,都可能为
java.io.DataInput
java.io.InputStream
java.io.File
java.lang.String
byte[]
java.net.URL
应该支持 UTF8 解码(或许利用 InputStreamReader),并且对于 InputStream、URL 支持顺带指定大小的 Buffer 快捷方式(利用 BufferedInputStream 机制)
—
它应该记录:
+ 输入流
+ 当前读取的文件名 fileName
+ 当前流位置 offset
+ 当前读取的行号 lineN
+ 当前读取的列号 columnN
+ 当前解析状态栈 stateStack
+ 当前解析标记栈 positionStack
它应该支持这些 combinator 方法(其实... 和 Haskell 的 ReadP 还是有很大区别的,但其实也能写 combinator style 的 parser...)
boolean eof()
int available()
void close()
char getChar()
char offset(int n)
void next()
void skip(int n)
StringBuilder lookAheadN(int n)
char lookAhead1()
boolean char(char x)
boolean containsIn(char... xs)
boolean containsIn(Set<Character> xs)
boolean lookAhead(String x)
boolean lookAhead(char x)
StringBuilder takeWhile(Consumer<Char> p)
StringBuilder takeUntil(Consumer<Char> p)
StringBuilder logWhile(Consumer<Char> p)
StringBuilder logUntil(Consumer<Char> p)
void dropWhile(Consumer<Char> p)
void dropUntil(Consumer<Char> p)
int tell()
void seek(int pos)
void begin(String state)
String readState()
void done()
void pushPosition()
int lastPosition()
void loadPosition()
void debug(String debugMessage)
void debug(String debugMessage, PrintStream output)
void fail(String message) throws TextCombinatorError
void asserts(boolean p, String message) throws TextCombinatorError
static Set<Character> range(char i1, char i2)
然后还有真正的 parser 的组合函数,要用到 Java 8 的
<T> T maybe(Parser<T>... parsers)
这样就可以这么匹配,不过只能
in.maybe(
charP("("),
satisfy((c) -> c == "A"),
some(element("1", "2", "3")),
many(elemnet(range("A", "Z"))))
这样,可以这么写一个 Json String Parser:
string
= " character* "
character
= ['0020' .. '10ffff'] - ["\]
| '\' escape
escape
= ["\/bnrt]
| u hex hex hex hex
hex
= digit
| [A-F] | [a-f]
digit = 0 | onenine
onenine = [1-9]
如果不能匹配就 reset 到之前的位置,两种 combinator style 都支持,一个作为后端(TextInputStream, TextReadStream)一个作为前面的封装(TextCombinator)... 🤔
Json 是什么呢? json.org
Json 里可以有这些类型的『数据』
DJson 称之为『Type』,都可能为
null(为了方便,和 JSON 定义相称)ObjectJ<Type>DJson 应该继承于一个 Text ParserCombinator 库,此库应该接受这些参数类型的 Constructor
ArrayJ<Type>
String
Number
Boolean
java.io.DataInput
java.io.InputStream
java.io.File
java.lang.String
byte[]
java.net.URL
应该支持 UTF8 解码(或许利用 InputStreamReader),并且对于 InputStream、URL 支持顺带指定大小的 Buffer 快捷方式(利用 BufferedInputStream 机制)
—
它应该记录:
+ 输入流
+ 当前读取的文件名 fileName
+ 当前流位置 offset
+ 当前读取的行号 lineN
+ 当前读取的列号 columnN
+ 当前解析状态栈 stateStack
+ 当前解析标记栈 positionStack
它应该支持这些 combinator 方法(其实... 和 Haskell 的 ReadP 还是有很大区别的,但其实也能写 combinator style 的 parser...)
boolean eof()
int available()
void close()
char getChar()
char offset(int n)
void next()
void skip(int n)
StringBuilder lookAheadN(int n)
char lookAhead1()
boolean char(char x)
boolean containsIn(char... xs)
boolean containsIn(Set<Character> xs)
boolean lookAhead(String x)
boolean lookAhead(char x)
StringBuilder takeWhile(Consumer<Char> p)
StringBuilder takeUntil(Consumer<Char> p)
StringBuilder logWhile(Consumer<Char> p)
StringBuilder logUntil(Consumer<Char> p)
void dropWhile(Consumer<Char> p)
void dropUntil(Consumer<Char> p)
int tell()
void seek(int pos)
void begin(String state)
String readState()
void done()
void pushPosition()
int lastPosition()
void loadPosition()
void debug(String debugMessage)
void debug(String debugMessage, PrintStream output)
void fail(String message) throws TextCombinatorError
void asserts(boolean p, String message) throws TextCombinatorError
static Set<Character> range(char i1, char i2)
然后还有真正的 parser 的组合函数,要用到 Java 8 的
:: 语法<T> T maybe(Parser<T>... parsers)
这样就可以这么匹配,不过只能
in.maybe(
charP("("),
satisfy((c) -> c == "A"),
some(element("1", "2", "3")),
many(elemnet(range("A", "Z"))))
这样,可以这么写一个 Json String Parser:
string
= " character* "
character
= ['0020' .. '10ffff'] - ["\]
| '\' escape
escape
= ["\/bnrt]
| u hex hex hex hex
hex
= digit
| [A-F] | [a-f]
digit = 0 | onenine
onenine = [1-9]
如果不能匹配就 reset 到之前的位置,两种 combinator style 都支持,一个作为后端(TextInputStream, TextReadStream)一个作为前面的封装(TextCombinator)... 🤔
duangsuse::Echo
停,现在是 DJson 的设计时间。今天暂时只来设计。 #Java Json 是什么呢? json.org Json 里可以有这些类型的『数据』 DJson 称之为『Type』,都可能为 null(为了方便,和 JSON 定义相称) ObjectJ<Type> ArrayJ<Type> String Number Boolean DJson 应该继承于一个 Text ParserCombinator 库,此库应该接受这些参数类型的 Constructor java.io.DataInput j…
顺便一说,DJson 希望有泛型的
但是... 其实 Java 没有真泛型,是泛型擦除实现的泛型... 没有办法拿到
我开始是想
可是真的不可以啊... 泛型里无法拿到任何的类型参数信息呢,除非用 Kotlin
后来... 我觉得还是专门设立一个类似 hamcrest 的 pattern match 检查器好,多道 pass 也没什么的
这样可以
ObjectJ<T extends Type> 什么的其实是希望可以这样: 😫DJson然后假设这么干可以边解析边检查类型(
.fromString("{a:1}")
.into(new ObjectJ<Number>())
.doParse();
但是... 其实 Java 没有真泛型,是泛型擦除实现的泛型... 没有办法拿到
T 的 java.lang.Class<T> 实例...我开始是想
interface 里也能为类指定 static 方法限定的... 这样我用 T.getClass() 什么的就可以进行类型检查了可是真的不可以啊... 泛型里无法拿到任何的类型参数信息呢,除非用 Kotlin
reified Generics后来... 我觉得还是专门设立一个类似 hamcrest 的 pattern match 检查器好,多道 pass 也没什么的
这样可以
DJson或许好一点吧...
.fromString("{ary:[1]}")
.typed(new ObjectJ(new ArrayJ(new NumberJ())))
.doParse()
#pl #cs #plt #recommended https://tinyurl.com/y8xdlfug
冰封的简历... 人家 18 年去宾夕法尼亚州立大学学计算机科学现在有半年多了呃...
IDE 和 Parser、Compiler、Type system、静态分析什么的自然是编译器工程师必须要会的了... 可是冰封还有 Rust 和分布式计算、并行计算、计算机网络、图形前端开发、形式化验证、二进制级别理解等技能,真的是让人... 不可理喻啊 🤪
不过话说起来,复杂的都能解决了这些码农级别或者算法的东西也就不成问题了,何况曾经写过 #OI...
看份简历,居然顺便知道了到底啥是 (依赖类型术语) dependent product type (Pi type) 啥是 dependent pair type(Sigma type),还顺带了解了啥是 Sum type (Tagged Union) 啥是 Product type 啥是 case split... 果然是 🐮🍺 啊....
冰封的简历... 人家 18 年去宾夕法尼亚州立大学学计算机科学现在有半年多了呃...
IDE 和 Parser、Compiler、Type system、静态分析什么的自然是编译器工程师必须要会的了... 可是冰封还有 Rust 和分布式计算、并行计算、计算机网络、图形前端开发、形式化验证、二进制级别理解等技能,真的是让人... 不可理喻啊 🤪
不过话说起来,复杂的都能解决了这些码农级别或者算法的东西也就不成问题了,何况曾经写过 #OI...
看份简历,居然顺便知道了到底啥是 (依赖类型术语) dependent product type (Pi type) 啥是 dependent pair type(Sigma type),还顺带了解了啥是 Sum type (Tagged Union) 啥是 Product type 啥是 case split... 果然是 🐮🍺 啊....
https://github.com/duangsuse/AXMLEdit/issues/2
其实这玩意都快把我的眼睛看瞎了,这种代码... 不必要的复杂性... emmmm...
https://github.com/duangsuse/AXMLEdit/blob/master/src/main/java/cn/wjdiankong/axmledit/helper/AXmlEditor.java#L84
前面使用的算法大概是:
XmlPull 标签开始:
size tagName = makeStrPoolRef(parser.getName())
int count = parser.getAttrCount()
byte[count * 20] attrbytes
for (int i : count)
size uri= makeStrPoolRef(prefixStr)
int[] type = getAttrType(attrValue[i])
String[] attrName = attrName[i].split()
int aname = attrName[1]
int avalue = attrValue[i]
int atype = type[0]
int adata = type[1]
AttrData data(uri, aname, avalue, atype, adata)
attrbytes = bytecat(attrbytes, data.bytes, i * data.len)
为啥非得建立这么多
TagStart:
int tagName = axml.strPoolRef(parser.getName())
final int count = parser.getAttrCount()
for (int i : count)
String attr_name = attrName[i].split()
int[] attr_type = toAttrType(attrValue[i])
int aname = attr_name[1], avalue = attrValue[i], atype = type[0], adata = type[1];
new AttrData(uriRef, aname ,avalue, atype, adata).writes(axml)
如果有不能立刻写的数据,那就保存好晚点结束生成的时候再写,比如 string pool...
为什么要不断去手算偏移量... 能流式就不要不断去做乘除法
其实这玩意都快把我的眼睛看瞎了,这种代码... 不必要的复杂性... emmmm...
StartTagChunk startChunk = StartTagChunk.createChunk(name, attCount, -1, attribute);
// 构造一个新的 chunk 之后, 开始写入
if (isNotAppTag(tagName)) {
ChunkParser.xmlStruct.byteSrc = Utils.insertByte(ChunkParser.xmlStruct.byteSrc, subTagChunkOffsets, startChunk.getChunkBytes());
subTagChunkOffsets += startChunk.getChunkBytes().length;
} else {
ChunkParser.xmlStruct.byteSrc = Utils.insertByte(ChunkParser.xmlStruct.byteSrc, subAppTagChunkOffset, startChunk.getChunkBytes());
subAppTagChunkOffset += startChunk.getChunkBytes().length;
}
这都是啥辣鸡代码 #Javahttps://github.com/duangsuse/AXMLEdit/blob/master/src/main/java/cn/wjdiankong/axmledit/helper/AXmlEditor.java#L84
前面使用的算法大概是:
XmlPull 标签开始:
size tagName = makeStrPoolRef(parser.getName())
int count = parser.getAttrCount()
byte[count * 20] attrbytes
for (int i : count)
size uri= makeStrPoolRef(prefixStr)
int[] type = getAttrType(attrValue[i])
String[] attrName = attrName[i].split()
int aname = attrName[1]
int avalue = attrValue[i]
int atype = type[0]
int adata = type[1]
AttrData data(uri, aname, avalue, atype, adata)
attrbytes = bytecat(attrbytes, data.bytes, i * data.len)
为啥非得建立这么多
byte 数组?难道不能用 OutputStream 吗?TagStart:
int tagName = axml.strPoolRef(parser.getName())
final int count = parser.getAttrCount()
for (int i : count)
String attr_name = attrName[i].split()
int[] attr_type = toAttrType(attrValue[i])
int aname = attr_name[1], avalue = attrValue[i], atype = type[0], adata = type[1];
new AttrData(uriRef, aname ,avalue, atype, adata).writes(axml)
如果有不能立刻写的数据,那就保存好晚点结束生成的时候再写,比如 string pool...
为什么要不断去手算偏移量... 能流式就不要不断去做乘除法
GitHub
meta节点的插入有没有修复呀。 · Issue #2 · duangsuse/AXMLEdit
4哥的会导致无法安装。
duangsuse::Echo
停,现在是 DJson 的设计时间。今天暂时只来设计。 #Java Json 是什么呢? json.org Json 里可以有这些类型的『数据』 DJson 称之为『Type』,都可能为 null(为了方便,和 JSON 定义相称) ObjectJ<Type> ArrayJ<Type> String Number Boolean DJson 应该继承于一个 Text ParserCombinator 库,此库应该接受这些参数类型的 Constructor java.io.DataInput j…
Parser<String> stringP() {
return () -> { charP('"'); manyConcat(jsonCharP()); charP('"'); }
}
Parser<Character> jsonCharP() {
return () -> {
return maybe(sequence(charP('\\'), jsonEscapeP()),
all(notElement("\"\\"), element(range(0x0020, 0x10ffff))));
};
}
Parser<Character> jsonEscapeP() {
return () -> {
return maybe(element("\"/\\bnrt"), sequence(charP("u"), repeats(4, hexCharP())));
};
}
Parser<Character> hexCharP() {
return () -> {
return maybe(digitP(), element(range("a", "f")), element(range("A", "F")));
};
}
Parser<Character> digitP() {
return () -> {
return maybe(charP('0'), element(range('1', '9')));
};
}
return () -> { charP('"'); manyConcat(jsonCharP()); charP('"'); }
}
Parser<Character> jsonCharP() {
return () -> {
return maybe(sequence(charP('\\'), jsonEscapeP()),
all(notElement("\"\\"), element(range(0x0020, 0x10ffff))));
};
}
Parser<Character> jsonEscapeP() {
return () -> {
return maybe(element("\"/\\bnrt"), sequence(charP("u"), repeats(4, hexCharP())));
};
}
Parser<Character> hexCharP() {
return () -> {
return maybe(digitP(), element(range("a", "f")), element(range("A", "F")));
};
}
Parser<Character> digitP() {
return () -> {
return maybe(charP('0'), element(range('1', '9')));
};
}
duangsuse::Echo
Parser<String> stringP() { return () -> { charP('"'); manyConcat(jsonCharP()); charP('"'); } } Parser<Character> jsonCharP() { return () -> { return maybe(sequence(charP('\\'), jsonEscapeP()), all(notElement("\"\\"), element(range(0x0020, 0x10ffff))));…
This media is not supported in your browser
VIEW IN TELEGRAM
我得再去考虑一下 Parser 应该怎么抽象,然后 DJson 就可以使用这种 combinator 风格的 parser 库了
处理 EOF:
sequence 里默认一个一个 match,EOF 则直接不 match,使用 eofP 来匹配结束吧...(说说而已,我觉得应该专门使用一种方式)
比如一个简单的语法结构:
@FunctionalInterface
interface Parser<? extends R> {
@Nullable R match(TextReadStream reader);
}
🤔 charP 是什么呢? 一个 Parser<Character>, 就是说它的匹配结果是 Character
.... 不应该接受任何的额外参数,所以不如这么说:@FunctionalInterface
interface Parser<? extends R> {
@Nullable R match();
}
class MyParser extemds TextCombinator {
Parser<Character> charP(char x) {
return () -> { return getChar() == x ? getChar() : null; }
}
Parser<Void> helloP() {
return () -> {
sequence(charP("h"), charP("e"), charP("l"), charP("l"), charP("o"));
return null;
};
}
Parser<Integer> manyHelloP() {
return () -> {
ManyMatch hellos = many(helloP());
return hellos.length
};
}
}
这样就可以了MyParser parser = new MyParser(System.in);
System.out.println(parser.manyHelloP());
hellohellohellohello...处理 EOF:
sequence 里默认一个一个 match,EOF 则直接不 match,使用 eofP 来匹配结束吧...(说说而已,我觉得应该专门使用一种方式)
mustSequence 里可以提供一个函数来指示错误信息,Unexpected EOF比如一个简单的语法结构:
<def> <name> <(> { arg } <)> <=> <value>
就是:mustSequence(假设用户只输入了
keywordP(DEF), ws(),
nameP(), ws(),
parenLP(),
many(argP()),
parenRP(), ws(),
eqP(),
valueP()
).except((n) -> switch (n) {
case 0: return expect("def keyword");
case 2: return expect("variable name");
case 4: return expect("(");
case 6: return expect(")");
case 8: return expect("=");
case 9: return expect("variable value");
})
def a就 EOF 了,实际上最后一个状态是
ws(), 倒数第二个是 definitionP
这样,mustSequence 就可以给出错误信息:
duangsuse::Echo
我得再去考虑一下 Parser 应该怎么抽象,然后 DJson 就可以使用这种 combinator 风格的 parser 库了 @FunctionalInterface interface Parser<? extends R> { @Nullable R match(TextReadStream reader); } 🤔 charP 是什么呢? 一个 Parser<Character>, 就是说它的匹配结果是 Character .... 不应该接受任何的额外参数,所以不如这么说: @Fu…
@FunctionalInterface所以提供的 parser combinator 方法都有
interface Parser<R> {
@Nullable <? extends R> match();
}
@FunctionalInterface
interface Matcher<R> {
@Nullable boolean matches(<? super R> value);
}
Parser<R> satisfy(Matcher<Character> predicate);
charP
SequenceParser<R> maySequence(Parser<R> parsers...);
SequenceParser<R> sequence(Parser<R> parsers...);
all
maybe
sequenceFilterConcat
exclusiveOr
not
repeats
some
many
manyConcat
element
notElement
range
看看这道题
Regex 子集的
data RegExp
= Normal Char
-- ^ A character that is not in "()*|."
| Any
-- ^ Any character
| ZeroOrMore RegExp
-- ^ Zero or more occurances of the same regexp
| Or RegExp RegExp
-- ^ A choice between 2 regexps
| Str [RegExp]
-- ^ A sequence of regexps.
Normal 就是 charP
Any 没有默认定义,但是可以这么写Parser<Character> any() { return satisfy((x) -> true); }
ZeroOrMore 就是 many
Or 就是 maybe
Str 就是 sequence
这个 Parser 也可以用来解析 Regex 所能解析的东西:"ab*" ->
sequence(charP("a"), many(charP("b")))
"(ab)+" -> some(sequence(charP("a"), charP("b")))
"(a.*)|(bb)" ->maybe(
sequence(charP('a'), many(any())),
sequence(charP('b'), charP('b'))))Codewars
Regular expression parser
Codewars is where developers achieve code mastery through challenge. Train on kata in the dojo and reach your highest potential.
Forwarded from 永久封存 | Yuuta 台 | 😷 #Pray4Wuhan (YuutaW 鱼塔)
仔细观察了日志,发现日志从 28% 到结尾均有各种 Vertx Thread Blocked 异常,从 5s ~ 12s 不等。同时在 Arrays#copyOf、vertx-blocked-thread-checker 线程、OkHttp ConnectionPool 线程、vert.x-eventloop-thread-0 等地方均发生 OOM 异常。