public static PropExpression Parse(string source) { var lexer = new PropLogicLexer(source); lexer.NextToken(); PropExpression result = MatchExpression(lexer); ExpectToken(lexer, LexerTokenType.End); return(result); }
private static PropExpression MatchUnary(PropLogicLexer lexer) { if (lexer.CurrentTokenType == LexerTokenType.Not) { lexer.NextToken(); PropExpression result = MatchAtom(lexer); return(new PropNegation(result)); } return(MatchAtom(lexer)); }
private static PropExpression MatchAndTerm(PropLogicLexer lexer) { PropExpression result = MatchUnary(lexer); while (lexer.CurrentTokenType == LexerTokenType.And) { lexer.NextToken(); PropExpression right = MatchUnary(lexer); result = new PropConjunction(result, right); } return(result); }
private static PropExpression MatchAtom(PropLogicLexer lexer) { ExpectToken(lexer, LexerTokenType.Identifier, LexerTokenType.OpenParen); PropExpression result; if (lexer.CurrentTokenType == LexerTokenType.Identifier) { result = new PropIdentifier(lexer.CurrentTokenValue); lexer.NextToken(); } else { lexer.NextToken(); result = MatchExpression(lexer); ExpectToken(lexer, LexerTokenType.CloseParen); lexer.NextToken(); } return(result); }
private static void ExpectToken(PropLogicLexer lexer, params LexerTokenType[] tokens) { foreach (LexerTokenType token in tokens) { if (lexer.CurrentTokenType == token) { return; } } var sb = new StringBuilder(); foreach (LexerTokenType token in tokens) { if (sb.Length > 0) { sb.Append(", "); } sb.Append(TokenTypeToString(token)); throw new ArgumentException(string.Format("Unexpected token in expression, got {0}, expecting one of {1}", TokenTypeToString(lexer.CurrentTokenType), sb)); } }
// BNF(ish) for the language this parses // Expression ::== OrTerm // OrTerm ::== AndTerm ( '||' AndTerm)* // AndTerm ::== Unary ( '&&' Unary)* // Unary ::= '!' Atom | Atom // Atom ::= IDENTIFIER | '(' Expression ')' // IDENTIFIER ::= [A-Za-z_][A-Za-z0-9_]* private static PropExpression MatchExpression(PropLogicLexer lexer) { PropExpression result = MatchOrTerm(lexer); return(result); }