Ejemplo n.º 1
0
        /// <summary>
        /// Parses a SimpleCircuit statement.
        /// </summary>
        /// <param name="lexer">The lexer.</param>
        /// <param name="context">The parsing context.</param>
        /// <returns>Returns <c>true</c> if the statement was parsed successfully; otherwise, <c>false</c>.</returns>
        private static bool ParseStatement(SimpleCircuitLexer lexer, ParsingContext context)
        {
            switch (lexer.Type)
            {
            case TokenType.Word:
                return(ParseComponentChainStatement(lexer, context, (IPin pinToWire, WireInfo wireInfo, IPin wireToPin) => StringWiresTogether(pinToWire, wireInfo, wireToPin, context)));

            case TokenType.Dot:
                lexer.Next();
                return(ParseControlStatement(lexer, context));

            case TokenType.OpenParenthesis:
                return(ParseVirtualChainStatement(lexer, context));

            case TokenType.Dash:
                return(ParsePropertyAssignmentStatement(lexer, context));

            case TokenType.Newline:
                lexer.Next();
                return(true);

            case TokenType.EndOfContent:
                return(true);

            default:
                context.Diagnostics?.Post(new TokenDiagnosticMessage(lexer.Token, SeverityLevel.Error, "PE001", $"Unrecognized {lexer.Content}"));
                lexer.Next();
                return(false);
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Parses SimpleCircuit code.
 /// </summary>
 /// <param name="lexer">The lexer.</param>
 /// <param name="context">The context.</param>
 public static void Parse(SimpleCircuitLexer lexer, ParsingContext context)
 {
     // Read until the end
     while (lexer.Type != TokenType.EndOfContent)
     {
         if (!ParseStatement(lexer, context))
         {
             lexer.Skip(~TokenType.Newline);
         }
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Parses a chain of components.
        /// </summary>
        /// <param name="lexer">The lexer.</param>
        /// <param name="context">The parsing context.</param>
        /// <param name="stringTogether">The action that is executed when wires should be </param>
        /// <returns>Returns <c>true</c> if the statement was parsed successfully; otherwise, <c>false</c>.</returns>
        private static bool ParseComponentChainStatement(SimpleCircuitLexer lexer, ParsingContext context, Action <IPin, WireInfo, IPin> stringTogether)
        {
            // component[pin] '<' wires '>' [pin]component[pin] '<' wires '>' ... '>' [pin]component
            var component = ParseComponent(lexer, context);

            if (component == null)
            {
                return(false);
            }
            Token pinName;

            // Parse wires
            while (lexer.Check(TokenType.OpenIndex | TokenType.OpenBeak))
            {
                IPin pinToWire = null;

                // Read a pin
                if (lexer.Check(TokenType.OpenIndex))
                {
                    pinName = ParsePin(lexer, context);
                    if (pinName.Content.Length == 0)
                    {
                        return(false);
                    }
                    if (!component.Pins.TryGetValue(pinName.Content.ToString().Trim(), out pinToWire))
                    {
                        if (context.Diagnostics?.Post(pinName, ErrorCodes.CannotFindPin, pinName.Content.ToString(), component.Name) == SeverityLevel.Error)
                        {
                            return(false);
                        }
                    }
                }
                else if (component.Pins.Count == 0)
                {
                    if (context.Diagnostics?.Post(lexer.StartToken, ErrorCodes.DoesNotHavePins, component.Name) == SeverityLevel.Error)
                    {
                        return(false);
                    }
                }
                else
                {
                    // Select the last pin
                    pinToWire = component.Pins[^ 1];