@@ -389,8 +389,8 @@ private void BuildMethodBody()
389389 finally
390390 {
391391 PopContext ( ) ;
392- }
393-
392+ }
393+
394394 CreateChild ( CurrentParent , NodeKind . BlockEnd , _lastExtractedLexem ) ;
395395 NextLexem ( ) ;
396396 }
@@ -1237,130 +1237,68 @@ private BslSyntaxNode BuildExpression(NonTerminalNode parent, Token stopToken)
12371237 return default ;
12381238 }
12391239
1240- var op = BuildOrExpression ( ) ;
1240+ var op = BuildExpression ( 0 ) ;
12411241 parent . AddChild ( op ) ;
12421242 return op ;
12431243 }
1244-
1245- private BslSyntaxNode BuildOrExpression ( )
1246- {
1247- var firstArg = BuildAndExpression ( ) ;
1248- while ( _lastExtractedLexem . Token == Token . Or )
1249- {
1250- var operationLexem = _lastExtractedLexem ;
1251- NextLexem ( ) ;
1252- var secondArg = BuildAndExpression ( ) ;
1253- firstArg = MakeBinaryOperationNode ( firstArg , secondArg , operationLexem ) ;
1254- }
12551244
1256- return firstArg ;
1257- }
1258-
1259- private BslSyntaxNode BuildAndExpression ( )
1245+ private BslSyntaxNode BuildExpression ( int prio )
12601246 {
1261- var firstArg = BuildNotExpression ( ) ;
1262- while ( _lastExtractedLexem . Token == Token . And )
1247+ var firstArg = BuildPrimaryExpression ( ) ;
1248+ while ( LanguageDef . GetBinaryPriority ( _lastExtractedLexem . Token ) > prio )
12631249 {
12641250 var operationLexem = _lastExtractedLexem ;
12651251 NextLexem ( ) ;
1266- var secondArg = BuildNotExpression ( ) ;
1267- firstArg = MakeBinaryOperationNode ( firstArg , secondArg , operationLexem ) ;
1268- }
1252+ var secondArg = BuildExpression ( LanguageDef . GetBinaryPriority ( operationLexem . Token ) ) ;
12691253
1270- return firstArg ;
1271- }
1272-
1273- private BslSyntaxNode BuildNotExpression ( )
1274- {
1275- if ( _lastExtractedLexem . Token == Token . Not )
1276- {
1277- var operation = _lastExtractedLexem ;
1278- NextLexem ( ) ;
1279- var op = new UnaryOperationNode ( operation ) ;
1280- var argument = BuildLogicalComparison ( ) ;
1281- op . AddChild ( argument ) ;
1282- return op ;
1283- }
1284-
1285- return BuildLogicalComparison ( ) ;
1286- }
1287-
1288- private BslSyntaxNode BuildLogicalComparison ( )
1289- {
1290- var firstArg = BuildAdditionExpression ( ) ;
1291- while ( _lastExtractedLexem . Token == Token . Equal ||
1292- _lastExtractedLexem . Token == Token . MoreThan ||
1293- _lastExtractedLexem . Token == Token . LessThan ||
1294- _lastExtractedLexem . Token == Token . MoreOrEqual ||
1295- _lastExtractedLexem . Token == Token . LessOrEqual ||
1296- _lastExtractedLexem . Token == Token . NotEqual )
1297- {
1298- var operationLexem = _lastExtractedLexem ;
1299- NextLexem ( ) ;
1300- var secondArg = BuildAdditionExpression ( ) ;
13011254 firstArg = MakeBinaryOperationNode ( firstArg , secondArg , operationLexem ) ;
13021255 }
13031256
13041257 return firstArg ;
1305- }
1306-
1307- private BslSyntaxNode BuildAdditionExpression ( )
1258+ }
1259+
1260+ private BslSyntaxNode BuildPrimaryExpression ( )
13081261 {
1309- var firstArg = BuildMultiplyExpression ( ) ;
1310- while ( _lastExtractedLexem . Token == Token . Plus ||
1311- _lastExtractedLexem . Token == Token . Minus )
1312- {
1313- var operationLexem = _lastExtractedLexem ;
1314- NextLexem ( ) ;
1315- var secondArg = BuildMultiplyExpression ( ) ;
1316- firstArg = MakeBinaryOperationNode ( firstArg , secondArg , operationLexem ) ;
1317- }
1318-
1319- return firstArg ;
1320- }
1321-
1322- private BslSyntaxNode BuildMultiplyExpression ( )
1323- {
1324- var firstArg = BuildUnaryMathExpression ( ) ;
1325- while ( _lastExtractedLexem . Token == Token . Multiply ||
1326- _lastExtractedLexem . Token == Token . Division ||
1327- _lastExtractedLexem . Token == Token . Modulo )
1328- {
1329- var operationLexem = _lastExtractedLexem ;
1330- NextLexem ( ) ;
1331- var secondArg = BuildUnaryMathExpression ( ) ;
1332- firstArg = MakeBinaryOperationNode ( firstArg , secondArg , operationLexem ) ;
1333- }
1334-
1335- return firstArg ;
1336- }
1337-
1338- private BslSyntaxNode BuildUnaryMathExpression ( )
1339- {
1340- if ( _lastExtractedLexem . Token == Token . Plus )
1341- _lastExtractedLexem . Token = Token . UnaryPlus ;
1342- else if ( _lastExtractedLexem . Token == Token . Minus )
1343- _lastExtractedLexem . Token = Token . UnaryMinus ;
1344- else
1345- return BuildParenthesis ( ) ;
1346-
1347- // Можно оптимизировать численный литерал до константы
1348- var operation = _lastExtractedLexem ;
1349- NextLexem ( ) ;
1350- if ( _lastExtractedLexem . Type == LexemType . NumberLiteral )
1351- {
1352- if ( operation . Token == Token . UnaryMinus )
1353- _lastExtractedLexem . Content = '-' + _lastExtractedLexem . Content ;
1354-
1355- return TerminalNode ( ) ;
1356- }
1357-
1358- var op = new UnaryOperationNode ( operation ) ;
1359- var argument = BuildParenthesis ( ) ;
1360- op . AddChild ( argument ) ;
1361- return op ;
1362- }
1363-
1262+ if ( _lastExtractedLexem . Token == Token . OpenPar )
1263+ {
1264+ return BuildParenthesis ( ) ;
1265+ }
1266+
1267+ var operation = _lastExtractedLexem ;
1268+ var prio = LanguageDef . GetUnaryPriority ( operation . Token ) ;
1269+
1270+ if ( prio == LanguageDef . MAX_OPERATION_PRIORITY )
1271+ {
1272+ return TerminalNode ( ) ;
1273+ }
1274+
1275+ NextLexem ( ) ;
1276+
1277+ if ( operation . Token == Token . Plus )
1278+ operation . Token = Token . UnaryPlus ;
1279+ else if ( operation . Token == Token . Minus )
1280+ {
1281+ operation . Token = Token . UnaryMinus ;
1282+ if ( _lastExtractedLexem . Type == LexemType . NumberLiteral ) //TODO:move it to lexer
1283+ {
1284+ _lastExtractedLexem . Content = '-' + _lastExtractedLexem . Content ;
1285+ return TerminalNode ( ) ;
1286+ }
1287+ }
1288+
1289+ if ( LanguageDef . GetUnaryPriority ( _lastExtractedLexem . Token ) <= prio )
1290+ {
1291+ AddError ( LocalizedErrors . ExpressionSyntax ( ) ) ;
1292+ return default ;
1293+ }
1294+
1295+ var arg = BuildExpression ( prio ) ;
1296+ var op = new UnaryOperationNode ( operation ) ;
1297+ op . AddChild ( arg ) ;
1298+ return op ;
1299+ }
1300+
1301+
13641302 private BslSyntaxNode BuildExpressionUpTo ( NonTerminalNode parent , Token stopToken )
13651303 {
13661304 var node = BuildExpression ( parent , stopToken ) ;
@@ -1392,36 +1330,31 @@ private void BuildOptionalExpression(NonTerminalNode parent, Token stopToken)
13921330 return ;
13931331 }
13941332
1395- var op = BuildOrExpression ( ) ;
1333+ var op = BuildExpression ( 0 ) ;
13961334 parent . AddChild ( op ) ;
13971335 }
13981336
13991337 #region Operators
14001338
1401- private static BslSyntaxNode MakeBinaryOperationNode ( BslSyntaxNode firstArg , BslSyntaxNode secondArg , in Lexem lexem )
1339+ private static BinaryOperationNode MakeBinaryOperationNode ( BslSyntaxNode firstArg , BslSyntaxNode secondArg , in Lexem lexem )
14021340 {
14031341 var node = new BinaryOperationNode ( lexem ) ;
14041342 node . AddChild ( firstArg ) ;
14051343 node . AddChild ( secondArg ) ;
14061344 return node ;
1407- }
1408-
1345+ }
1346+
14091347 private BslSyntaxNode BuildParenthesis ( )
1410- {
1411- if ( _lastExtractedLexem . Token == Token . OpenPar )
1412- {
1413- NextLexem ( ) ;
1414- var expr = BuildOrExpression ( ) ;
1415- if ( _lastExtractedLexem . Token != Token . ClosePar )
1416- {
1417- AddError ( LocalizedErrors . TokenExpected ( Token . ClosePar ) ) ;
1418- }
1419- NextLexem ( ) ;
1420-
1421- return BuildDereference ( expr ) ;
1422- }
1423-
1424- return TerminalNode ( ) ;
1348+ {
1349+ NextLexem ( ) ;
1350+ var expr = BuildExpression ( 0 ) ;
1351+ if ( _lastExtractedLexem . Token != Token . ClosePar )
1352+ {
1353+ AddError ( LocalizedErrors . TokenExpected ( Token . ClosePar ) ) ;
1354+ }
1355+ NextLexem ( ) ;
1356+
1357+ return BuildDereference ( expr ) ;
14251358 }
14261359
14271360 #endregion
@@ -1676,7 +1609,7 @@ private Token[] PopStructureToken()
16761609 return tok ;
16771610 }
16781611
1679- private BslSyntaxNode CreateChild ( NonTerminalNode parent , NodeKind kind , in Lexem lex )
1612+ private static BslSyntaxNode CreateChild ( NonTerminalNode parent , NodeKind kind , in Lexem lex )
16801613 {
16811614 var child = NodeBuilder . CreateNode ( kind , lex ) ;
16821615 parent . AddChild ( child ) ;
0 commit comments