Skip to content

Commit

Permalink
${} instead of @{} as bounding syntax. (#1717)
Browse files Browse the repository at this point in the history
* port refactor Structure LG and Analyzer

* fix lexer and parser

* fix bugs

* fix extractor

* remove comments

* parity test cases and fix bugs

* init

* undo comments in ActivityFactoryTest

* retrigger

* retrigger

Co-authored-by: Shuai Wang <[email protected]>
  • Loading branch information
Danieladu and cosmicshuai authored Feb 17, 2020
1 parent 8b2941b commit 02bc402
Show file tree
Hide file tree
Showing 61 changed files with 612 additions and 612 deletions.
18 changes: 9 additions & 9 deletions libraries/botbuilder-lg/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Language generation is achieved through:

```markdown
# greetingTemplate
- Hello @{user.name}, how are you?
- Good morning @{user.name}. It's nice to see you again.
- Good day @{user.name}. What can I do for you today?
- Hello ${user.name}, how are you?
- Good morning ${user.name}. It's nice to see you again.
- Good day ${user.name}. What can I do for you today?
```

You can use language generation to:
Expand All @@ -33,15 +33,15 @@ Example here:
```markdown
# HeroCardTemplate(buttonsCollection)
[Herocard
title=@{TitleText())}
subtitle=@{SubText())}
text=@{DescriptionText())}
images=@{CardImages())}
buttons=@{buttonsCollection}
title=${TitleText())}
subtitle=${SubText())}
text=${DescriptionText())}
images=${CardImages())}
buttons=${buttonsCollection}
]

# TitleText
- Here are some @{TitleSuffix()}
- Here are some ${TitleSuffix()}

# TitleSuffix
- cool photos
Expand Down
6 changes: 3 additions & 3 deletions libraries/botbuilder-lg/src/LGFileLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ fragment EMPTY_OBJECT: '{' WHITESPACE* '}';

fragment STRING_LITERAL : ('\'' (~['\r\n])* '\'') | ('"' (~["\r\n])* '"');
fragment EXPRESSION_FRAGMENT : '@' '{' (STRING_LITERAL| ~[\r\n{}'"] | EMPTY_OBJECT )*? '}';
fragment EXPRESSION_FRAGMENT : '$' '{' (STRING_LITERAL| ~[\r\n{}'"] | EMPTY_OBJECT )*? '}';
fragment ESCAPE_CHARACTER_FRAGMENT : '\\' ~[\r\n]?;
// top level elements
COMMENTS
: ('>'|'$') ~('\r'|'\n')+ -> skip
: '>' ~('\r'|'\n')+ -> skip
;
WS
Expand Down Expand Up @@ -205,7 +205,7 @@ TEXT_IN_STRUCTURE_NAME
mode STRUCTURE_BODY_MODE;
STRUCTURED_COMMENTS
: ('>'|'$') ~[\r\n]* '\r'?'\n' { !this.inStructuredValue && this.beginOfStructureProperty}? -> skip
: '>' ~[\r\n]* '\r'?'\n' { !this.inStructuredValue && this.beginOfStructureProperty}? -> skip
;
WS_IN_STRUCTURE_BODY
Expand Down
2 changes: 1 addition & 1 deletion libraries/botbuilder-lg/src/analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ export class Analyzer extends AbstractParseTreeVisitor<AnalyzerResult> implement

private analyzeExpression(exp: string): AnalyzerResult {
const result: AnalyzerResult = new AnalyzerResult();
exp = exp.replace(/(^@*)/g, '')
exp = exp.replace(/(^\$*)/g, '')
.replace(/(^{*)/g, '')
.replace(/(}*$)/g, '');
const parsed: Expression = this._expressionParser.parse(exp);
Expand Down
6 changes: 3 additions & 3 deletions libraries/botbuilder-lg/src/evaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class Evaluator extends AbstractParseTreeVisitor<any> implements LGFilePa

// to support broswer, use look-ahead replace look-behind
// original:/(?<!\\)@\{((\'[^\'\r\n]*\')|(\"[^\"\r\n]*\")|[^\r\n\{\}\'\"])*?\}/g;
public static readonly expressionRecognizeReverseRegex: RegExp = new RegExp(/\}((\'[^\'\r\n]*\')|(\"[^\"\r\n]*\")|([^\r\n\{\}\'\"]))*?\{@(?!\\)/g);
public static readonly expressionRecognizeReverseRegex: RegExp = new RegExp(/\}((\'[^\'\r\n]*\')|(\"[^\"\r\n]*\")|([^\r\n\{\}\'\"]))*?\{\$(?!\\)/g);

public static readonly LGType = 'lgType';
public static readonly activityAttachmentFunctionName = 'ActivityAttachment';
Expand Down Expand Up @@ -311,7 +311,7 @@ export class Evaluator extends AbstractParseTreeVisitor<any> implements LGFilePa

private evalExpressionInCondition(exp: string): boolean {
try {
exp = exp.replace(/(^@*)/g, '')
exp = exp.replace(/(^\$*)/g, '')
.replace(/(^{*)/g, '')
.replace(/(}*$)/g, '');

Expand All @@ -330,7 +330,7 @@ export class Evaluator extends AbstractParseTreeVisitor<any> implements LGFilePa
}

private evalExpression(exp: string): any {
exp = exp.replace(/(^@*)/g, '')
exp = exp.replace(/(^\$*)/g, '')
.replace(/(^{*)/g, '')
.replace(/(}*$)/g, '');

Expand Down
4 changes: 2 additions & 2 deletions libraries/botbuilder-lg/src/expander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ export class Expander extends AbstractParseTreeVisitor<string[]> implements LGFi

private evalExpressionInCondition(exp: string): boolean {
try {
exp = exp.replace(/(^@*)/g, '')
exp = exp.replace(/(^\$*)/g, '')
.replace(/(^{*)/g, '')
.replace(/(}*$)/g, '');

Expand All @@ -326,7 +326,7 @@ export class Expander extends AbstractParseTreeVisitor<string[]> implements LGFi
}

private evalExpression(exp: string): string[] {
exp = exp.replace(/(^@*)/g, '')
exp = exp.replace(/(^\$*)/g, '')
.replace(/(^{*)/g, '')
.replace(/(}*$)/g, '');

Expand Down
450 changes: 225 additions & 225 deletions libraries/botbuilder-lg/src/generated/LGFileLexer.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion libraries/botbuilder-lg/src/generated/LGFileParser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated from LGFileParser.g4 by ANTLR 4.6-SNAPSHOT
// Generated from ../LGFileParser.g4 by ANTLR 4.6-SNAPSHOT


import { ATN } from "antlr4ts/atn/ATN";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated from LGFileParser.g4 by ANTLR 4.6-SNAPSHOT
// Generated from ../LGFileParser.g4 by ANTLR 4.6-SNAPSHOT


import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated from LGFileParser.g4 by ANTLR 4.6-SNAPSHOT
// Generated from ../LGFileParser.g4 by ANTLR 4.6-SNAPSHOT


import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor";
Expand Down
2 changes: 1 addition & 1 deletion libraries/botbuilder-lg/src/staticChecker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ class StaticCheckerInner extends AbstractParseTreeVisitor<Diagnostic[]> implemen

private checkExpression(exp: string, context: ParserRuleContext): Diagnostic[] {
const result: Diagnostic[] = [];
exp = exp.replace(/(^@*)/g, '')
exp = exp.replace(/(^\$*)/g, '')
.replace(/(^{*)/g, '')
.replace(/(}*$)/g, '')
.trim();
Expand Down
14 changes: 7 additions & 7 deletions libraries/botbuilder-lg/tests/lg.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,12 @@ describe('LG', function() {
assert.strictEqual(emptyEngine.evaluate('Hi'), 'Hi', emptyEngine.evaluate('Hi'));
assert.strictEqual(emptyEngine.evaluate('Hi', ''), 'Hi', emptyEngine.evaluate('Hi', ''));

assert.strictEqual(emptyEngine.evaluate('Hi @{name}', { name: 'DL' }), 'Hi DL');
assert.strictEqual(emptyEngine.evaluate('Hi ${name}', { name: 'DL' }), 'Hi DL');

assert.strictEqual(emptyEngine.evaluate('Hi @{name.FirstName}@{name.LastName}', { name: { FirstName: 'D', LastName: 'L' } }), 'Hi DL');
assert.strictEqual(emptyEngine.evaluate('Hi ${name.FirstName}${name.LastName}', { name: { FirstName: 'D', LastName: 'L' } }), 'Hi DL');
assert.strictEqual(emptyEngine.evaluate('Hi \n Hello', ''), 'Hi \n Hello');
assert.strictEqual(emptyEngine.evaluate('Hi \r\n Hello', ''), 'Hi \r\n Hello');
assert.strictEqual(emptyEngine.evaluate('Hi \r\n @{name}', { name: 'DL' }), 'Hi \r\n DL');
assert.strictEqual(emptyEngine.evaluate('Hi \r\n ${name}', { name: 'DL' }), 'Hi \r\n DL');
assert.strictEqual(new TemplateEngine().evaluate('Hi', ''), 'Hi');
});

Expand All @@ -165,11 +165,11 @@ describe('LG', function() {
assert.strictEqual(emptyEngine.evaluate('Hi'), 'Hi', emptyEngine.evaluate('Hi'));
assert.strictEqual(emptyEngine.evaluate('Hi', ''), 'Hi', emptyEngine.evaluate('Hi', ''));

assert.strictEqual(emptyEngine.evaluate('Hi @{name}', { name: 'DL' }), 'Hi DL', emptyEngine.evaluate('Hi @{name}', { name: 'DL' }));
assert.strictEqual(emptyEngine.evaluate('Hi ${name}', { name: 'DL' }), 'Hi DL', emptyEngine.evaluate('Hi ${name}', { name: 'DL' }));

assert.strictEqual(emptyEngine.evaluate('Hi @{name.FirstName}@{name.LastName} @{RecentTasks()}', { name: { FirstName: 'D', LastName: 'L' } }), 'Hi DL You don\'t have any tasks.', emptyEngine.evaluate('Hi @{name.FirstName}@{name.LastName} @{RecentTasks()}', { name: { FirstName: 'D', LastName: 'L' } }));
assert.strictEqual(emptyEngine.evaluate('Hi ${name.FirstName}${name.LastName} ${RecentTasks()}', { name: { FirstName: 'D', LastName: 'L' } }), 'Hi DL You don\'t have any tasks.', emptyEngine.evaluate('Hi ${name.FirstName}${name.LastName} ${RecentTasks()}', { name: { FirstName: 'D', LastName: 'L' } }));

assert.strictEqual(emptyEngine.evaluate('Hi @{name.FirstName}@{name.LastName} @{RecentTasks()}', { name: { FirstName: 'D', LastName: 'L' }, recentTasks: ['task1'] }), 'Hi DL Your most recent task is task1. You can let me know if you want to add or complete a task.', emptyEngine.evaluate('Hi @{name.FirstName}@{name.LastName} @{RecentTasks()}', { name: { FirstName: 'D', LastName: 'L' }, recentTasks: ['task1'] }));
assert.strictEqual(emptyEngine.evaluate('Hi ${name.FirstName}${name.LastName} ${RecentTasks()}', { name: { FirstName: 'D', LastName: 'L' }, recentTasks: ['task1'] }), 'Hi DL Your most recent task is task1. You can let me know if you want to add or complete a task.', emptyEngine.evaluate('Hi ${name.FirstName}${name.LastName} ${RecentTasks()}', { name: { FirstName: 'D', LastName: 'L' }, recentTasks: ['task1'] }));

});

Expand Down Expand Up @@ -646,7 +646,7 @@ describe('LG', function() {
}

evaled = engine.evaluateTemplate('AskForAge.prompt3');
assert.deepStrictEqual(evaled, JSON.parse('{"lgType":"Activity","text":"@{GetAge()}","suggestions":["10 | cards","20 | cards"]}'));
assert.deepStrictEqual(evaled, JSON.parse('{"lgType":"Activity","text":"${GetAge()}","suggestions":["10 | cards","20 | cards"]}'));

evaled = engine.evaluateTemplate('T1');
assert.deepStrictEqual(evaled, JSON.parse('{"lgType":"Activity","text":"This is awesome","speak":"foo bar I can also speak!"}'));
Expand Down
2 changes: 1 addition & 1 deletion libraries/botbuilder-lg/tests/testData/adaptiveCard.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"body": [
{
"type": "TextBlock",
"text": "@{adaptiveCardTitle}",
"text": "${adaptiveCardTitle}",
"weight": "bolder",
"size": "medium"
},
Expand Down
4 changes: 2 additions & 2 deletions libraries/botbuilder-lg/tests/testData/examples/3.lg
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
> Using a template in another template
> Sometimes the bot will say 'Hi' and other times it will say 'Hi :)'
# welcome-user()
- @{wPhrase()}
- @{wPhrase()} :)
- ${wPhrase()}
- ${wPhrase()} :)

8 changes: 4 additions & 4 deletions libraries/botbuilder-lg/tests/testData/examples/4.lg
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
> Using a template in another template
> Sometimes the bot will say 'Hi' and other times it will say 'Hi :)'
# welcome
- @{wPhrase()}
- @{wPhrase()} :)
- ${wPhrase()}
- ${wPhrase()} :)

> Using entity references. Unless explicitly specified, entities default to string. Valid types are String, Int, Long, Float, Double, Bool, DateTime
# welcome-user
- @{wPhrase()} @{userName}
- @{wPhrase()} @{userName} :)
- ${wPhrase()} ${userName}
- ${wPhrase()} ${userName} :)
18 changes: 9 additions & 9 deletions libraries/botbuilder-lg/tests/testData/examples/5.lg
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@
> Using a template in another template
> Sometimes the bot will say 'Hi' and other times it will say 'Hi :)'
# welcome-user
- @{wPhrase()}
- @{wPhrase()} :)
- ${wPhrase()}
- ${wPhrase()} :)

> Using entity references
# welcome-user2
- @{wPhrase()}
- @{wPhrase()} @{userName}
- @{wPhrase()} @{userName} :)
- ${wPhrase()}
- ${wPhrase()} ${userName}
- ${wPhrase()} ${userName} :)

> Conditional response template
> Outer list is condition expression; L2 list is one-of collection
# time-of-day-readout
- IF: @{timeOfDay == 'morning'}
- IF: ${timeOfDay == 'morning'}
- Good morning
- Morning!
- ELSE:
Expand All @@ -30,16 +30,16 @@
> Conditional response template
> Outer list is condition expression; L2 list is one-of collection
# time-of-day-readout-without-default
- IF: @{timeOfDay == 'morning'}
- IF: ${timeOfDay == 'morning'}
- Good morning
- Morning!
- ELSEIF: @{timeOfDay != 'morning'}
- ELSEIF: ${timeOfDay != 'morning'}
- Good evening
- Evening!

> Conditional response template
> Outer list is condition expression; L2 list is one-of collection
# time-of-day-readout-without-default2
- IF: @{timeOfDay == 'morning'}
- IF: ${timeOfDay == 'morning'}
- Good morning
- Morning!
34 changes: 17 additions & 17 deletions libraries/botbuilder-lg/tests/testData/examples/6.lg
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,40 @@
> Using a template in another template
> Sometimes the bot will say 'Hi' and other times it will say 'Hi :)'
# welcome-user(userName)
- @{wPhrase()} @{userName} :)
- ${wPhrase()} ${userName} :)

> Using entity references
# welcome
- IF: @{userName}
- @{welcome-user(userName)}
- IF: ${userName}
- ${welcome-user(userName)}
- ELSE:
- @{welcome-user('DongLei')}
- ${welcome-user('DongLei')}



# ShowAlarm(alarm)
- @{alarm.time} at @{alarm.date}
- ${alarm.time} at ${alarm.date}

# ShowAlarmsWithForeach
- IF: @{count(alarms) == 1}
- You have one alarm @{ShowAlarm(alarms[0])}
- ELSEIF: @{count(alarms) == 2}
- You have @{count(alarms)} alarms, @{join(foreach(alarms, x, ShowAlarm(x)), ', ', ' and ')}
- IF: ${count(alarms) == 1}
- You have one alarm ${ShowAlarm(alarms[0])}
- ELSEIF: ${count(alarms) == 2}
- You have ${count(alarms)} alarms, ${join(foreach(alarms, x, ShowAlarm(x)), ', ', ' and ')}
- ELSE:
- You don't have any alarms

# ShowAlarmsWithLgTemplate
- IF: @{count(alarms) == 1}
- You have one alarm @{ShowAlarm(alarms[0])}
- ELSEIF: @{count(alarms) == 2}
- You have @{count(alarms)} alarms, @{join(foreach(alarms, x, template('ShowAlarm', x)), ', ', ' and ')}
- IF: ${count(alarms) == 1}
- You have one alarm ${ShowAlarm(alarms[0])}
- ELSEIF: ${count(alarms) == 2}
- You have ${count(alarms)} alarms, ${join(foreach(alarms, x, template('ShowAlarm', x)), ', ', ' and ')}
- ELSE:
- You don't have any alarms

# ShowAlarmsWithDynamicLgTemplate(templateName)
- IF: @{count(alarms) == 1}
- You have one alarm @{ShowAlarm(alarms[0])}
- ELSEIF: @{count(alarms) == 2}
- You have @{count(alarms)} alarms, @{join(foreach(alarms, x, template(templateName, x)), ', ', ' and ')}
- IF: ${count(alarms) == 1}
- You have one alarm ${ShowAlarm(alarms[0])}
- ELSEIF: ${count(alarms) == 2}
- You have ${count(alarms)} alarms, ${join(foreach(alarms, x, template(templateName, x)), ', ', ' and ')}
- ELSE:
- You don't have any alarms
14 changes: 7 additions & 7 deletions libraries/botbuilder-lg/tests/testData/examples/8.lg
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# RecentTasks
- IF: @{count(recentTasks) == 1}
- Your most recent task is @{recentTasks[0]}. You can let me know if you want to add or complete a task.
- ELSEIF: @{count(recentTasks) == 2}
- Your most recent tasks are @{join(recentTasks, ',', 'and')}. You can let me know if you want to add or complete a task.
- ELSEIF: @{count(recentTasks) > 2}
- Your most recent @{count(recentTasks)} tasks are @{join(recentTasks, ',', 'and')}. You can let me know if you want to add or complete a task.
- IF: ${count(recentTasks) == 1}
- Your most recent task is ${recentTasks[0]}. You can let me know if you want to add or complete a task.
- ELSEIF: ${count(recentTasks) == 2}
- Your most recent tasks are ${join(recentTasks, ',', 'and')}. You can let me know if you want to add or complete a task.
- ELSEIF: ${count(recentTasks) > 2}
- Your most recent ${count(recentTasks)} tasks are ${join(recentTasks, ',', 'and')}. You can let me know if you want to add or complete a task.
- ELSE:
- You don't have any tasks.

# ShowTasks
- @{RecentTasks()}
- ${RecentTasks()}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"body": [
{
"type": "TextBlock",
"text": "@{adaptiveCardTitle}",
"text": "${adaptiveCardTitle}",
"weight": "bolder",
"size": "medium"
},
Expand Down
Loading

0 comments on commit 02bc402

Please sign in to comment.