Skip to content

Commit

Permalink
Merge f0fc8a5 into 5dd2a11
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnychhsu committed Mar 8, 2019
2 parents 5dd2a11 + f0fc8a5 commit 73631a4
Showing 1 changed file with 390 additions and 0 deletions.
390 changes: 390 additions & 0 deletions languages/zh-tw/thingtalk.genie
Original file line number Diff line number Diff line change
@@ -0,0 +1,390 @@
// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*-
//
// This file is part of ThingTalk
//
// Copyright 2017-2018 The Board of Trustees of the Leland Stanford Junior University
//
// Author: Giovanni Campagna <gcampagn@cs.stanford.edu>
//
// See COPYING for details

{
const assert = require('assert');

const ThingTalk = require('thingtalk');
const Ast = ThingTalk.Ast;
const Type = ThingTalk.Type;

// import the combinator library
const C = require('../../lib/sentence-generator/ast_manip');

}

import './constants';
import './timers';
import './filters';
import './parameters';
import './aggregation';

complete_table = {
thingpedia_query if complete;
table_join_replace_placeholder if complete;
}
complete_get_command = {
thingpedia_get_command if complete;
}
if_filtered_table = {
complete_table;
one_filter_table;
!turking two_filter_table;
}

one_filter_table = {
table:complete_table '其中' filter:atom_filter => {
if (!C.checkFilter(table, filter))
return null;
return C.addFilter(table, filter, $options);
};
}
two_filter_table = {
table:one_filter_table '而且' filter:atom_filter => {
if (!C.checkFilter(table, filter))
return null;
return C.addFilter(table, filter, $options);
};
}

// FIXME delete all with_filtered table in this file
with_filtered_table = {

}

edge_stream = {
!turking ('當' | '如果' | '等') p:projection_Any ('變成' | '變為' | '是' | '為') x:constant_Any => C.makeEdgeFilterStream(p, '==', x, $options);
('當' | '如果' | '等') 'the' p:projection_Numeric ('變得' | '變成') '比' x:constant_Numeric ('大' | '多') => C.makeEdgeFilterStream(p, '>=', x, $options);
('當' | '如果' | '等') 'the' p:projection_Numeric ('變得' | '變成') '比' x:constant_Numeric ('小' | '少') => C.makeEdgeFilterStream(p, '<=', x, $options);
}

stream = {
thingpedia_stream if complete;

!turking {
'當' proj:projection_Any ('改變' | '變化') ('時' | '的 時候') => {
if (proj.args[0] === 'picture_url')
return null;
if (proj.table.isAggregation)
return null;
let outParams = Object.keys(proj.table.schema.out);
let stream;
if (outParams.length === 1 && $options.flags.turking)
return null;
if (outParams.length === 1)
stream = C.tableToStream(proj.table, null);
else
stream = C.tableToStream(proj.table, proj.args);
return stream;
};
('假如' | '如果') proj:projection_Any ('改變' | '變' | '不一樣') '了' => {
if (proj.args[0] === 'picture_url')
return null;
if (proj.table.isAggregation)
return null;
let outParams = Object.keys(proj.table.schema.out);
let stream;
if (outParams.length === 1 && $options.flags.turking)
return null;
if (outParams.length === 1)
stream = C.tableToStream(proj.table, null);
else
stream = C.tableToStream(proj.table, proj.args);
return stream;
};
('假如' | '如果') proj:projection_Any '變得' '不一樣 了' => {
if (proj.args[0] === 'picture_url')
return null;
if (proj.table.isAggregation)
return null;
let outParams = Object.keys(proj.table.schema.out);
let stream;
if (outParams.length === 1 && $options.flags.turking)
return null;
if (outParams.length === 1)
stream = C.tableToStream(proj.table, null);
else
stream = C.tableToStream(proj.table, proj.args);
return stream;
};
}
'當' table:complete_table ('變' | '改變' | '不一樣') '了' ('而且' | '且') filter:edge_filter ('時' | '的 時候') => {
if (!table.schema.is_monitorable || !C.checkFilter(table, filter) || table.schema.is_list)
return null;
table = C.addFilter(table, filter, $options);
if (!table)
return null;
return C.tableToStream(table, null);
};
'當' table:complete_table ('變' | '改變' | '不一樣') '了' ('而且' | '且') filter:atom_filter ('時' | '的 時候') => {
if (!table.schema.is_monitorable || !C.checkFilter(table, filter))
return null;
if ($options.flags.turking && table.schema.is_list)
return null;
table = C.addFilter(table, filter, $options);
if (!table)
return null;
return C.tableToStream(table, null);
};
edge_stream;
timer;
}

// FIXME add more...

forward_get_do_command = {
('給我' | '拿' | '取得') table:if_filtered_table ('然後' | '接著') action:thingpedia_action if !complete => new Ast.Statement.Command(table, [action]);
table:complete_get_command ',' ('然後' | '接著') action:thingpedia_action if !complete => new Ast.Statement.Command(table, [action]);
table:complete_get_command ('然後' | '接著') action:thingpedia_action if !complete => new Ast.Statement.Command(table, [action]);
table:complete_get_command ',' action:thingpedia_action if !complete => new Ast.Statement.Command(table, [action]);
}

complete_forward_get_do_command = {
forward_get_do_command if complete;
}

backward_get_do_command = {
action:thingpedia_action '當' ('拿到' | '取得' | '得到') table:complete_get_command ('時' | '的 時候') if !complete => new Ast.Statement.Command(table, [action]);
}

complete_get_do_command = {
complete_forward_get_do_command;
!turking backward_get_do_command if complete;
action_replace_param_with_table if complete;
}

forward_when_do_rule = {
// pp from when to do (optional)
stream:stream action:thingpedia_action => new Ast.Statement.Rule(stream, [action]);

('如果' | '假如') ('有' | '出現') ('新' | '新的') table:complete_table ('' | ',' | '就') action:thingpedia_action if !complete => {
if (!table.schema.is_monitorable)
return null;
return new Ast.Statement.Rule(new Ast.Stream.Monitor(table, null, table.schema), [action]);
};
}

complete_forward_when_do_rule = {
forward_when_do_rule if complete;
}

backward_when_do_rule = {
action:thingpedia_action stream:stream => new Ast.Statement.Rule(stream, [action]);

action:thingpedia_action ('如果' | '假如') ('有' | '出現') ('新' | '新的') table:complete_table if !complete => {
if (!table.schema.is_monitorable)
return null;
return new Ast.Statement.Rule(new Ast.Stream.Monitor(table, null, table.schema), [action]);
};
}
complete_when_do_rule = {
complete_forward_when_do_rule;
backward_when_do_rule if complete;
}

when_get_stream = {
// pp from when to get (optional)
// NOTE: the schema is not quite right but it's ok because the stream is complete
// and the table is what we care about
stream:stream table:thingpedia_get_command => C.checkNotSelfJoinStream(new Ast.Stream.Join(stream, table, [], table.schema));
stream:stream ('給我' | '取得' | '下載' | '傳給 我') table:thingpedia_query => C.checkNotSelfJoinStream(new Ast.Stream.Join(stream, table, [], table.schema));
stream:stream ('給我' | '取得' | '下載' | '傳給 我') proj:projection_Any => {
if (proj.args[0] === 'picture_url')
return null;
let outParams = Object.keys(proj.table.schema.out);
if (outParams.length === 1 && $options.flags.turking && !proj.table.isAggregation)
return null;

return C.checkNotSelfJoinStream(new Ast.Stream.Join(stream, proj.table, [], proj.table.schema));
};
}
complete_when_get_stream = {
when_get_stream if complete;
}

when_get_do_rule = {
stream:stream command:complete_get_do_command => C.combineStreamCommand(stream, command);
}

$root = {
// when => notify
stream:stream ('通知 我' | '告知 我' | '讓 我 知道' | '提醒 我' | '跟 我 說') => C.makeProgram(new Ast.Statement.Rule(stream, [stream.isTimer || stream.isAtTimer ? C.builtinSayAction($options) : C.notifyAction()]));
stream:timer ('通知 我' | '告知 我' | '讓 我 知道' | '提醒 我' | '跟 我 說') => C.makeProgram(new Ast.Statement.Rule(stream, [C.builtinSayAction($options)]));
stream:timer ('傳' | '送' | '傳送') constant:constant_String ('' | '給 我') => C.makeProgram(new Ast.Statement.Rule(stream, [C.builtinSayAction($options, constant)]));

'當' table:if_filtered_table ('變' | '改變' | '不一樣') '了' ('時' | '的 時候' | '') (',' | '') ('通知 我' | '告知 我' | '讓 我 知道' | '提醒 我' | '跟 我 說') => {
let stream = C.tableToStream(table, null);
if (!stream)
return null;
return C.makeProgram(new Ast.Statement.Rule(stream, [C.notifyAction()]));
};

table:if_filtered_table ('有變化' | '改變' | '不一樣') ('時' | '的 時候' | '') (',' | '') ('通知 我' | '告知 我' | '讓 我 知道' | '提醒 我' | '跟 我 說') => {
let stream = C.tableToStream(table, null);
if (!stream)
return null;
return C.makeProgram(new Ast.Statement.Rule(stream, [C.notifyAction()]));
};

!turking '當' proj:projection_Any ('變' | '改變' | '不一樣') '了' ('時' | '的 時候' | '') (',' | '') ('通知 我' | '告知 我' | '讓 我 知道' | '提醒 我' | '跟 我 說')=> {
if (!proj.schema.is_monitorable)
return null;
if (proj.table.isAggregation)
return null;
let outParams = Object.keys(proj.table.schema.out);
if (outParams.length === 1 && $options.flags.turking)
return null;
// note that we intentionally don't use tableToStream here, because we don't want to introduce edge filters
return C.makeProgram(new Ast.Statement.Rule(new Ast.Stream.Monitor(proj.table, null, proj.table.schema), [C.notifyAction()]));
};

!turking proj:projection_Any ('有變化' | '改變' | '不一樣') ('時' | '的 時候' | '') (',' | '') ('通知 我' | '告知 我' | '讓 我 知道' | '提醒 我' | '跟 我 說')=> {
if (!proj.schema.is_monitorable)
return null;
if (proj.table.isAggregation)
return null;
let outParams = Object.keys(proj.table.schema.out);
if (outParams.length === 1 && $options.flags.turking)
return null;
// note that we intentionally don't use tableToStream here, because we don't want to introduce edge filters
return C.makeProgram(new Ast.Statement.Rule(new Ast.Stream.Monitor(proj.table, null, proj.table.schema), [C.notifyAction()]));
};

('當' | '') table:complete_table filter:atom_filter ('時' | '的 時候') ('通知 我' | '告知 我' | '讓 我 知道' | '提醒 我' | '跟 我 說') => {
if (C.hasGetPredicate(filter))
return null;
if (!table.schema.is_monitorable || !C.checkFilter(table, filter))
return null;
if ($options.flags.turking && table.schema.is_list)
return null;
table = C.addFilter(table, filter, $options);
if (!table)
return null;
let stream = C.tableToStream(table, null);
if (!stream)
return null;
return C.makeProgram(new Ast.Statement.Rule(stream, [C.notifyAction()]));
};
('當' | '') table:complete_table filter:edge_filter ('時' | '的 時候') ('通知 我' | '告知 我' | '讓 我 知道' | '提醒 我' | '跟 我 說') => {
if (C.hasGetPredicate(filter))
return null;
if (!table.schema.is_monitorable || table.schema.is_list || !C.checkFilter(table, filter))
return null;
table = C.addFilter(table, filter, $options);
if (!table)
return null;
let stream = C.tableToStream(table, null);
if (!stream)
return null;
return C.makeProgram(new Ast.Statement.Rule(stream, [C.notifyAction()]));
};

// now => get => notify
(
table:complete_get_command
| ('給我' | '取得' | '下載' | '傳給 我') table:complete_table
| ('嗨 Almond' | '哈囉 Almond' | '') ('給我' | '我要' | '我 需要' | ''傳給 '') table:with_filtered_table
) => C.makeProgram(new Ast.Statement.Command(table, [C.notifyAction()]));
// now => get => say(...)
// don't merge these, the output sizes are too small
(
('嗨 Almond' | '哈囉 Almond' | '') ('給我' | '我要' | '我 需要' | ''傳給 '') proj:projection_Any
| (' Almond' | '哈囉 Almond' | '') proj:projection_Any ('是 什麼 ?' | '?')
| ('告訴 我' | '跟 我 說') '什麼是' proj:projection_Any
| '誰 是' proj:projection_Entity__tt__username ('' | '?')
| proj:projection_Entity__tt__username ' ' ('' | '?')
| '誰 的 信箱 是' proj:projection_Entity__tt__email_address ('' | '?')
| proj:projection_Entity__tt__email_address ' 信箱' ('' | '?')
| proj:projection_Any
) => C.sayProjectionProgram($options, proj);

// now => do
(
action:thingpedia_action
| ('請' | '請你') action:thingpedia_action
| ('我要' | '我 想 要') action:thingpedia_action
| ('嗨 Almond' | '哈囉 Almond') ('請' | '請你' | '') action:thingpedia_action
) if complete => C.makeProgram(new Ast.Statement.Command(null, [action]));

// now => get => do
command:complete_get_do_command => C.makeProgram(command);

// when join get => notify/say(...)
stream:complete_when_get_stream => {
assert(stream.isJoin, `unexpected stream in when_get, found ${stream}`);
if (stream.table.isProjection)
return C.makeProgram(new Ast.Statement.Rule(new Ast.Stream.Join(stream.stream, stream.table.table, stream.in_params, stream.schema), [C.notifyAction()]));
else
return C.makeProgram(new Ast.Statement.Rule(stream, [C.notifyAction()]));
};

// when => do
rule:complete_when_do_rule => C.makeProgram(rule);

// when => get => do
rule:when_get_do_rule => C.makeProgram(rule);

// setup commands
('叫' | '請' | '要') principal:constant_Entity__tt__username ('去' | '') action:thingpedia_action if complete => C.makeProgram(new Ast.Statement.Command(null, [action]), principal);
(
('叫' | '請' | '要') principal:constant_Entity__tt__username '把' table:complete_table ('傳給 我' | '給我' | '寄給 我')
| ('叫' | '請' | '要') principal:constant_Entity__tt__username ('傳給 我' | '給我' | '寄給 我') table:complete_table
| ('給我' | '我要') principal:constant_Entity__tt__username ('他' | ') '' table:complete_table
| ('給我' | '我要') principal:constant_Entity__tt__username '' table:complete_table
) => C.makeProgram(new Ast.Statement.Command(table, [C.notifyAction('return')]), principal);
('' | '' | '') principal:constant_Entity__tt__username stream:stream ('通知 ' | '告知 我' | '讓 我 知道' | '提醒 我' | '跟 我 說') => C.makeProgram(new Ast.Statement.Rule(stream, [C.notifyAction('return')]), principal);
stream:stream ('叫' | '請' | '要') principal:constant_Entity__tt__username ('通知 我' | '告知 我' | '讓 我 知道' | '提醒 我' | '跟 我 說') => C.makeProgram(new Ast.Statement.Rule(stream, [C.notifyAction('return')]), principal);

// policies
('每 個 人' | '所有人' | '全部 的 人' | '任何 人') '都 可以' action:thingpedia_action if complete => C.makePolicy(null, null, action);
('允許' | '授權' | '讓') ('每 個 人' | '所有人' | '全部 的 人' | '任何 人') '都 可以' action:thingpedia_action if complete => C.makePolicy(null, null, action);
('每個' | '所有' | '全部 的' | '任何') filter:atom_filter '的 人' '都 可以' action:thingpedia_action if complete => {
if (!filter.isExternal)
return null;
let policy = C.makePolicy(null, null, action);
if (!policy)
return null;
policy.action.filter = Ast.BooleanExpression.And([policy.action.filter, filter]);
return policy;
};
('允許' | '授權' | '讓') ('每個' | '所有' | '全部 的' | '任何') filter:atom_filter '的 人' '都 可以' action:thingpedia_action if complete => {
if (!filter.isExternal)
return null;
let policy = C.makePolicy(null, null, action);
if (!policy)
return null;
policy.action.filter = Ast.BooleanExpression.And([policy.action.filter, filter]);
return policy;
};
('每 個 人' | '所有人' | '全部 的 人' | '任何 人') '都 可以' ('看' | '查看' | '存取' | '取得' | '讀取' | '讀' | '拿') table:if_filtered_table => C.makePolicy(null, table, null);
source:constant_Entity__tt__username '可以' action:thingpedia_action if complete => C.makePolicy(source, null, action);
('允許' | '授權' | '讓') source:constant_Entity__tt__username ('可以' | '') action:thingpedia_action if complete => C.makePolicy(source, null, action);
('允許' | '授權' | '讓') source:constant_Entity__tt__username ('可以' | '') action:thingpedia_action '如果' filter:atom_filter if complete => {
if (!filter.isExternal)
return null;
let policy = C.makePolicy(source, null, action);
if (!policy)
return null;
policy.action.filter = Ast.BooleanExpression.And([policy.action.filter, filter]);
return policy;
};
'如果' filter:atom_filter ('允許' | '授權' | '讓') source:constant_Entity__tt__username ('可以' | '') action:thingpedia_action if complete => {
if (!filter.isExternal)
return null;
let policy = C.makePolicy(source, null, action);
if (!policy)
return null;
policy.action.filter = Ast.BooleanExpression.And([policy.action.filter, filter]);
return policy;
};
('允許' | '授權' | '讓') source:constant_Entity__tt__username ('可以' | '') ('看' | '查看' | '存取' | '取得' | '讀取' | '讀' | '拿') table:if_filtered_table => C.makePolicy(source, table, null);
}

0 comments on commit 73631a4

Please sign in to comment.