LCOV - code coverage report
Current view: top level - boolean_selector-2.1.0/lib/src - parser.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 20 36 55.6 %
Date: 2021-11-28 14:37:50 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
       2             : // for details. All rights reserved. Use of this source code is governed by a
       3             : // BSD-style license that can be found in the LICENSE file.
       4             : 
       5             : import 'package:source_span/source_span.dart';
       6             : 
       7             : import 'ast.dart';
       8             : import 'scanner.dart';
       9             : import 'token.dart';
      10             : 
      11             : /// A class for parsing a boolean selector.
      12             : ///
      13             : /// Boolean selectors use a stripped-down version of the Dart expression syntax
      14             : /// that only contains variables, parentheses, and boolean operators. Variables
      15             : /// may also contain dashes, contrary to Dart's syntax; this allows consistency
      16             : /// with command-line arguments.
      17             : class Parser {
      18             :   /// The scanner that tokenizes the selector.
      19             :   final Scanner _scanner;
      20             : 
      21          10 :   Parser(String selector) : _scanner = Scanner(selector);
      22             : 
      23             :   /// Parses the selector.
      24             :   ///
      25             :   /// This must only be called once per parser.
      26           5 :   Node parse() {
      27           5 :     var selector = _conditional();
      28             : 
      29          20 :     if (_scanner.peek().type != TokenType.endOfFile) {
      30           0 :       throw SourceSpanFormatException(
      31           0 :           'Expected end of input.', _scanner.peek().span);
      32             :     }
      33             : 
      34             :     return selector;
      35             :   }
      36             : 
      37             :   /// Parses a conditional:
      38             :   ///
      39             :   ///     conditionalExpression:
      40             :   ///       logicalOrExpression ("?" conditionalExpression ":"
      41             :   ///           conditionalExpression)?
      42           5 :   Node _conditional() {
      43           5 :     var condition = _or();
      44          10 :     if (!_scanner.scan(TokenType.questionMark)) return condition;
      45             : 
      46           0 :     var whenTrue = _conditional();
      47           0 :     if (!_scanner.scan(TokenType.colon)) {
      48           0 :       throw SourceSpanFormatException('Expected ":".', _scanner.peek().span);
      49             :     }
      50             : 
      51           0 :     var whenFalse = _conditional();
      52           0 :     return ConditionalNode(condition, whenTrue, whenFalse);
      53             :   }
      54             : 
      55             :   /// Parses a logical or:
      56             :   ///
      57             :   ///     logicalOrExpression:
      58             :   ///       logicalAndExpression ("||" logicalOrExpression)?
      59           5 :   Node _or() {
      60           5 :     var left = _and();
      61          10 :     if (!_scanner.scan(TokenType.or)) return left;
      62           0 :     return OrNode(left, _or());
      63             :   }
      64             : 
      65             :   /// Parses a logical and:
      66             :   ///
      67             :   ///     logicalAndExpression:
      68             :   ///       simpleExpression ("&&" logicalAndExpression)?
      69           5 :   Node _and() {
      70           5 :     var left = _simpleExpression();
      71          10 :     if (!_scanner.scan(TokenType.and)) return left;
      72           0 :     return AndNode(left, _and());
      73             :   }
      74             : 
      75             :   /// Parses a simple expression:
      76             :   ///
      77             :   ///     simpleExpression:
      78             :   ///       "!" simpleExpression |
      79             :   ///           "(" conditionalExpression ")" |
      80             :   ///           IDENTIFIER
      81           5 :   Node _simpleExpression() {
      82          10 :     var token = _scanner.next();
      83           5 :     switch (token.type) {
      84           5 :       case TokenType.not:
      85           0 :         var child = _simpleExpression();
      86           0 :         return NotNode(child, token.span.expand(child.span!));
      87             : 
      88           5 :       case TokenType.leftParen:
      89           0 :         var child = _conditional();
      90           0 :         if (!_scanner.scan(TokenType.rightParen)) {
      91           0 :           throw SourceSpanFormatException(
      92           0 :               'Expected ")".', _scanner.peek().span);
      93             :         }
      94             :         return child;
      95             : 
      96           5 :       case TokenType.identifier:
      97          15 :         return VariableNode((token as IdentifierToken).name, token.span);
      98             : 
      99             :       default:
     100           0 :         throw SourceSpanFormatException('Expected expression.', token.span);
     101             :     }
     102             :   }
     103             : }

Generated by: LCOV version 1.14