Skip to content

Commit d571c76

Browse files
committed
fix EvilBeaver#1654: список параметров только через запятую +тесты
1 parent 7a99161 commit d571c76

File tree

2 files changed

+122
-97
lines changed

2 files changed

+122
-97
lines changed

src/OneScript.Language/SyntaxAnalysis/DefaultBslParser.cs

Lines changed: 102 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ private void BuildVariableSection()
194194
{
195195
PopContext();
196196
}
197+
197198
}
198199

199200
private void BuildVariableDefinition()
@@ -413,49 +414,55 @@ private void BuildMethodParameters(MethodSignatureNode signature)
413414

414415
NextLexem(); // (
415416

416-
var expectParameter = false;
417-
while (_lastExtractedLexem.Token != Token.ClosePar)
418-
{
419-
BuildAnnotations();
420-
var param = new MethodParameterNode();
421-
paramList.AddChild(param);
422-
ApplyAnnotations(param);
423-
// [Знач] Identifier [= Literal],...
424-
if (_lastExtractedLexem.Token == Token.ByValParam)
425-
{
426-
CreateChild(param, NodeKind.ByValModifier, _lastExtractedLexem);
427-
NextLexem();
428-
}
429-
430-
if (!IsUserSymbol(_lastExtractedLexem))
431-
{
432-
AddError(LocalizedErrors.IdentifierExpected());
433-
return;
434-
}
435-
CreateChild(param, NodeKind.Identifier, _lastExtractedLexem);
436-
NextLexem();
437-
if (_lastExtractedLexem.Token == Token.Equal)
438-
{
439-
NextLexem();
440-
if(!BuildDefaultParameterValue(param, NodeKind.ParameterDefaultValue))
441-
return;
442-
}
443-
444-
expectParameter = false;
445-
if (_lastExtractedLexem.Token == Token.Comma)
446-
{
447-
NextLexem();
448-
expectParameter = true;
449-
}
450-
}
451-
452-
if (expectParameter)
453-
{
454-
AddError(LocalizedErrors.IdentifierExpected(), false);
455-
}
456-
417+
if (_lastExtractedLexem.Token != Token.ClosePar)
418+
while (true)
419+
{
420+
BuildMethodParameter(paramList);
421+
422+
if (_lastExtractedLexem.Token == Token.ClosePar)
423+
{
424+
break;
425+
}
426+
427+
if (_lastExtractedLexem.Token == Token.Comma)
428+
{
429+
NextLexem();
430+
}
431+
else
432+
{
433+
AddError(LocalizedErrors.TokenExpected(Token.ClosePar));
434+
return;
435+
}
436+
}
437+
457438
NextLexem(); // )
439+
}
458440

441+
private void BuildMethodParameter(NonTerminalNode paramList)
442+
{
443+
BuildAnnotations();
444+
var param = new MethodParameterNode();
445+
paramList.AddChild(param);
446+
ApplyAnnotations(param);
447+
// [Знач] Identifier [= Literal],...
448+
if (_lastExtractedLexem.Token == Token.ByValParam)
449+
{
450+
CreateChild(param, NodeKind.ByValModifier, _lastExtractedLexem);
451+
NextLexem();
452+
}
453+
454+
if (!IsUserSymbol(_lastExtractedLexem))
455+
{
456+
AddError(LocalizedErrors.IdentifierExpected());
457+
return;
458+
}
459+
CreateChild(param, NodeKind.Identifier, _lastExtractedLexem);
460+
NextLexem();
461+
if (_lastExtractedLexem.Token == Token.Equal)
462+
{
463+
NextLexem();
464+
BuildDefaultParameterValue(param, NodeKind.ParameterDefaultValue);
465+
}
459466
}
460467

461468
private bool BuildDefaultParameterValue(NonTerminalNode param, NodeKind nodeKind)
@@ -526,6 +533,7 @@ private void BuildAnnotations()
526533
_annotations.Add(node);
527534
}
528535
}
536+
529537
private AnnotationNode BuildAnnotationDefinition() {
530538
var node = new AnnotationNode(NodeKind.Annotation, _lastExtractedLexem);
531539
NextLexem();
@@ -540,23 +548,31 @@ private void BuildAnnotationParameters(AnnotationNode annotation)
540548
return;
541549

542550
NextLexem();
543-
544-
while (_lastExtractedLexem.Token != Token.EndOfText)
551+
552+
if (_lastExtractedLexem.Token != Token.ClosePar)
553+
while (true)
545554
{
546-
if (_lastExtractedLexem.Token == Token.ClosePar)
547-
{
548-
NextLexem();
549-
break;
550-
}
551-
552-
BuildAnnotationParameter(annotation);
555+
BuildAnnotationParameter(annotation);
556+
557+
if (_lastExtractedLexem.Token == Token.ClosePar)
558+
{
559+
break;
560+
}
561+
553562
if (_lastExtractedLexem.Token == Token.Comma)
554563
{
555564
NextLexem();
556565
}
557-
}
558-
}
559-
566+
else
567+
{
568+
AddError(LocalizedErrors.TokenExpected(Token.ClosePar), false);
569+
return;
570+
}
571+
}
572+
573+
NextLexem(); // )
574+
}
575+
560576
private void BuildAnnotationParameter(AnnotationNode annotation)
561577
{
562578
bool success = true;
@@ -1146,59 +1162,48 @@ private void BuildCallParameters(NonTerminalNode callNode)
11461162
try
11471163
{
11481164
NextLexem(); // съели открывающую скобку
1149-
WalkCallArguments(node);
1165+
BuildCallArguments(node);
11501166
NextLexem(); // съели закрывающую скобку
11511167
}
11521168
finally
11531169
{
11541170
PopStructureToken();
11551171
}
1156-
}
1157-
1158-
private int WalkCallArguments(NonTerminalNode node)
1159-
{
1160-
int argCount = 0;
1161-
while (_lastExtractedLexem.Token != Token.ClosePar)
1162-
{
1163-
BuildCallArgument(node);
1164-
argCount++;
1165-
}
1166-
1167-
if (_lastExtractedLexem.Token != Token.ClosePar)
1168-
{
1169-
AddError(LocalizedErrors.TokenExpected(Token.ClosePar));
1170-
argCount = -1;
1171-
}
1172-
1173-
return argCount;
1174-
}
1175-
1176-
private void BuildCallArgument(NonTerminalNode argsList)
1177-
{
1178-
if (_lastExtractedLexem.Token == Token.Comma)
1179-
{
1180-
argsList.AddChild(new NonTerminalNode(NodeKind.CallArgument, _lastExtractedLexem));
1172+
}
11811173

1182-
BuildLastDefaultArg(argsList);
1183-
}
1184-
else if (_lastExtractedLexem.Token != Token.ClosePar)
1185-
{
1186-
var node = argsList.AddNode(new NonTerminalNode(NodeKind.CallArgument, _lastExtractedLexem));
1187-
BuildOptionalExpression(node, Token.Comma);
1188-
if (_lastExtractedLexem.Token == Token.Comma)
1189-
{
1190-
BuildLastDefaultArg(argsList);
1191-
}
1192-
}
1174+
private void BuildCallArguments(NonTerminalNode node)
1175+
{
1176+
if (_lastExtractedLexem.Token != Token.ClosePar)
1177+
while (true)
1178+
{
1179+
BuildOptionalCallArgument(node);
1180+
1181+
if (_lastExtractedLexem.Token == Token.ClosePar)
1182+
{
1183+
break;
1184+
}
1185+
1186+
if (_lastExtractedLexem.Token == Token.Comma)
1187+
{
1188+
NextLexem();
1189+
}
1190+
else
1191+
{
1192+
AddError(LocalizedErrors.TokenExpected(Token.ClosePar));
1193+
}
1194+
}
11931195
}
11941196

1195-
private void BuildLastDefaultArg(NonTerminalNode argsList)
1196-
{
1197-
NextLexem();
1198-
if (_lastExtractedLexem.Token == Token.ClosePar)
1197+
private void BuildOptionalCallArgument(NonTerminalNode argsList)
1198+
{
1199+
var arg = argsList.AddNode(new NonTerminalNode(NodeKind.CallArgument, _lastExtractedLexem));
1200+
if (_lastExtractedLexem.Token == Token.Comma
1201+
|| _lastExtractedLexem.Token == Token.ClosePar)
11991202
{
1200-
argsList.AddChild(new NonTerminalNode(NodeKind.CallArgument, _lastExtractedLexem));
1201-
}
1203+
return;
1204+
}
1205+
1206+
arg.AddNode( BuildExpression(0) );
12021207
}
12031208

12041209
#endregion
@@ -1480,7 +1485,7 @@ private void NewObjectDynamicConstructor(NonTerminalNode node)
14801485
// есть аргументы после имени
14811486
NextLexem();
14821487
}
1483-
WalkCallArguments(callArgs);
1488+
BuildCallArguments(callArgs);
14841489
node.AddChild(callArgs);
14851490
NextLexem();
14861491
}

src/Tests/OneScript.Language.Tests/ParserTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,9 +1251,29 @@ public void Check_Question_Operator_Delimiters()
12511251
{
12521252
var code = @"Ф = ?(Истина? 1 ; 2);";
12531253

1254+
CatchParsingError(code);
1255+
}
1256+
1257+
[Fact]
1258+
public void Check_Method_Definition_Delimiters()
1259+
{
1260+
var code = @"Процедура Проц1(арг1 арг2)
1261+
КонецПроцедуры";
1262+
12541263
CatchParsingError(code);
12551264
}
12561265

1266+
[Fact]
1267+
public void Check_Method_Call_Delimiters()
1268+
{
1269+
var code = @"Процедура Проц1(арг1, арг2)
1270+
КонецПроцедуры
1271+
Проц1(""1"" 2)";
1272+
1273+
CatchParsingError(code);
1274+
}
1275+
1276+
12571277

12581278
[Fact]
12591279
public void TestLocalExportVar()

0 commit comments

Comments
 (0)