-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
最新动态 #1
Comments
另外我认为可以使用松的解析器方案: 使用 PEG.js 作为解析器生成器, 目标是生成序列化 JSON,需要使用的时候让解释器反序列化得到 AST 完美解决了解析问题 |
上面的: PEG.js 其实不需要额外的 scanner, 所以就不要 JFlex 了 |
duangsuse 来制定一下重写添加的特性:
下一次为 Lite 设计一个虚拟机,并添加编译器,允许在一个 Interpreter 上下文中同时使用 AST 解释器和字节码解释器 下下一次做一个 Lite2Java 编译器, 或许不能实现什么动态特性但可以看作 |
(综上我总觉得不支持基于缩进的语义是一场遗憾....) 对比(这里是直接在 Ruby 上修改作为参考): # The Greeter class
class Greeter
def initialize(name)
@name = name.capitalize
def salute
puts "Hello #{@name}!"
# Create a new object
g = Greeter.new("world")
# Output "Hello World!"
g.salute # The Greeter class
class Greeter
def initialize(name)
@name = name.capitalize
end
def salute
puts "Hello #{@name}!"
end
end
# Create a new object
g = Greeter.new("world")
# Output "Hello World!"
g.salute |
这些是现在 Lite 的语法,准备根据新特性修改一下,然后创建一个 JSON AST 描述,就可以开始补齐 PEG 需要的信息,然后就可以开始制定 PEG.js 语法规则了,在那之前我得看看 MIT 许可的 javascript parser example, 从中有不少可以用的代码片段 这个版本的语法使用 end 标识块结束,所以比之前用缩进的更「普通」一些,使用 parserc 很好解决
|
关于 case 语句: case "foo bar"
when contains "foo" { }
when equals nil
puts :nil
end
when "bar foo" { exit() }
when toString "emm" {}
end
case Token(0, TokenType::EOF, '')
when isNewline {}
when is TokenType::REQUIRE
return
end
when nil {}
end 具体来说是 when 后的词条若是 identifier (+ expression) (直到 {), 就是特殊的 when 如果有且只有一个参数参数并且返回值是 Boolean/boolean, 意为使用后面的 expression 值调用方法, 作为结果 否则就是 identifier 表达式(如果有 expression, 无法识别即抛出异常) case a 后我还是觉得这样优雅一些 foo = String()
foo = 1 if Math.random > 0.5
when foo
class String # getClass() == String
puts foo
class Double
puts "${foo}D"
is 1
exit()
is 0 or 2 or 3
puts()
|
上面的表述还不够清晰, 以后会对整体语义在 wiki 里给出严谨简明的解释 |
刚才是想依然手写 parser... 算了
(Lite 的部分特殊语法需要特殊变换,比如给缩进语义加 end, "l${expression}r" 脱糖 "l" + expression + "r") (还是打算使用缩进语义, 不然不好看) 之前打算放在 parser 包里的类可以直接放在 root 下面 (添加 end 的 Deflator, 和序列化/反序列化 AST 的 JsonAst) |
作为生成器也是可以的,它比 Jison 和 PEG.js 都更加积极的在维护,而且工具很齐全 |
关于 def 语法的问题def 的特殊标识符(就是使用 '.' 语法的标识符)(对于一个 identifier 来说没有什么特殊的,但 Lite 目前不能解析带 '.' 的 identifier(和那个 '.' 操作符冲突了)
a = { self: nil }
def a.new(obj)
a->self { obj: obj }
a->print { print self.obj }
aa = a.new 1 + 1
aa.print()
# 如果是 @a 就直接用
# @a->new do |obj| 吧
关于 named scope 支持突然脑洞想到可以有一种新的模块化设计支持 # file a
import android.widget
scope android
def @LinearLayout.add(v)
self.addView(v)
# file b
scope android
lay << Button(ctx) ... 不知道有没有价值,不过我看可能对模块化设计比较有用,不如加上试试 |
既然新特性都设定好了,接下来开始定义词法和语法等: Lite 词法Lite 语法语义Lite 最有用的 Java APIInterpreterLexerDeflatorAstJsonBlock |
追加一个语法特性: String 字面量支持更多 escape 参考 https://github.com/lice-lang/lice/blob/master/src/main/kotlin/org/lice/parse/Lexer.kt#L189 参考 http://ice1000.org/2018/02/18/SyntaxDesign/ 里的尴尬情况, 如果转义不对,Lite 的 Lexer 要失败报错(同时现在 Lexer 的错误检查也太弱了,得增强一下) 对于 0x 0b 0o 这种数字字面量变换语法,也要支持(不是在分词器里,因为那里只认为数字是 [0-9] 到 一个空白字符结束) 但 012345 这种令人费解的 8 进制语法不可以支持,不得不说这么设计的确很纸张.... ^ 以上,我突然觉得这很没意思,我想支持这种语法的目的是需要这类字面量的(比如处理二进制)的脚本可以更方便的让解析器帮你换算进位,但是后来又发现其实这库函数也可能帮你做 于是我决定不支持这类特殊的 numeric literal, 抱歉
如果可能的话,Lexer 和 Parser 这种机械化的东西我会使用 JFlex/PEG.js|OHM.js 自动生成 |
NOTE: 解析方案依然是那个解析方案, 不过改用修改 JavaScript.pegjs |
最后的 parsing 商议结果: 基于 JavaScript 定义两套词法,一套支持语法糖一套不支持 定义两套语法,一套使用 end 一套使用缩进 然后交给可能的 PEG.js 生成的解析器使用,这个解析器在 JavaScript parser 基础上修修补补实现 |
最最后的: 还是先不过分美化语法吧,以后彻底手写了再作打算
|
最终还是决定暂时重写了(简单重写)
去除重复无用代码和支持更多语法以及小特性
不去除 end
决定是使用 JFlex + PEG.js 解决解析问题, Java 能复用的代码依然复用
为了体积(和我对其它 JVM 语言不熟悉,而且大都比较复杂)依然使用 Java 编写
The text was updated successfully, but these errors were encountered: