gsl-shell.git - gsl-shell

index : gsl-shell.git
gsl-shell
summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat
-rw-r--r--mini-parser.lua 53
1 files changed, 45 insertions, 8 deletions
diff --git a/mini-parser.lua b/mini-parser.lua
index b2d7f944..610d2d67 100644
--- a/mini-parser.lua
+++ b/mini-parser.lua
@@ -7,6 +7,7 @@ local mini_lexer_mt = {
__index = mini_lexer,
}
+local literal_chars = {['('] = 1, [')'] = 1, ['~'] = 1, [','] = 1}
local oper_table = {['+'] = 0, ['-'] = 0, ['*'] = 1, ['/'] = 1, ['^'] = 2}
local function new_lexer(src)
@@ -56,7 +57,7 @@ function mini_lexer.next_token(lexer)
lexer:incr()
return {type= 'operator', symbol= c, priority = prio}
end
- if c == '(' or c == ')' then
+ if literal_chars[c] then
lexer:incr()
return {type= c}
end
@@ -71,6 +72,11 @@ function mini_lexer.next_token(lexer)
end
return {type= 'number', value= tonumber(str)}
end
+ msg = { "syntax error in expression:",
+ string.format(' %s', lexer.src),
+ string.format(' %s^', string.rep(' ', lexer.n - 1)) }
+
+ error(table.concat(msg, '\n'))
end
function mini_lexer.next(lexer)
@@ -138,18 +144,37 @@ expr = function(lexer, actions, prio)
return a
end
+local function expr_list(lexer, actions)
+ local a = expr(lexer, actions, 0)
+ local els = actions.exprlist(a)
+ while accept(lexer, ',') > 0 do
+ local b = expr(lexer, actions, 0)
+ els = actions.exprlist(b, els)
+ end
+ return els
+end
+
+local function schema(lexer, actions)
+ local y = expr_list(lexer, actions)
+ expect(lexer, '~')
+ local x = expr_list(lexer, actions)
+ return actions.schema(x, y)
+end
+
local function parse_expr(lexer, actions)
return expr(lexer, actions, 0)
end
local AST_create = {
- infix = function(sym, a, b) return {operator= sym, a, b} end,
- ident = function(id) return {ident= id} end,
- prefix = function(sym, a) return {operator= sym, a} end,
- number = function(x) return {number= x} end,
+ infix = function(sym, a, b) return {operator= sym, a, b} end,
+ ident = function(id) return {ident= id} end,
+ prefix = function(sym, a) return {operator= sym, a} end,
+ number = function(x) return {number= x} end,
+ exprlist = function(a, ls) if ls then ls[#ls+1] = a else ls = {list= true, a} end; return ls end,
+ schema = function(x, y) return {schema= true, x= x, y= y} end,
}
-local format = string.format
+local format, concat = string.format, table.concat
local AST_print
local function is_ident_simple(s)
@@ -171,8 +196,20 @@ local function AST_print_op(e, prio)
end
end
+local function AST_print_exprlist(e)
+ local t = {}
+ for k = 1, #e do t[k] = AST_print(e[k]) end
+ return concat(t, ', ')
+end
+
AST_print = function(e)
- if e.ident then
+ if e.schema then
+ local ys = AST_print_exprlist(e.y)
+ local xs = AST_print_exprlist(e.x)
+ return format("%s ~ %s", ys, xs)
+ elseif e.list then
+ return AST_print_exprlist(e)
+ elseif e.ident then
local s = e.ident
if not is_ident_simple(s) then s = format('[%s]', s) end
return s, 3
@@ -185,4 +222,4 @@ AST_print = function(e)
end
end
-return {lexer = new_lexer, parse = parse_expr, AST= AST_create, print = AST_print}
+return {lexer = new_lexer, schema= schema, parse = parse_expr, AST= AST_create, print = AST_print}
generated by cgit v1.2.3 (git 2.39.1) at 2025年09月16日 20:03:15 +0000

AltStyle によって変換されたページ (->オリジナル) /