private void ProcessSyntaxNode(SyntaxNodeAnalysisContext context, SyntaxRule rule) { if (!_executor.QueryAll(context.Node, rule.Query).Any()) { return; } var diagnostic = Diagnostic.Create( _descriptors[rule.Severity], context.Node.GetLocation(), new[] { rule.Message } ); context.ReportDiagnostic(diagnostic); }
private static bool SyntaxEquals(SyntaxRule Left, SyntaxRule Right) { if (Left._Tag != Right._Tag) { return(false); } if (Left.OnLiteral) { return(SyntaxEquals(Left.Literal, Right.Literal)); } else if (Left.OnLeftBracket || Left.OnRightBracket || Left.OnLeftBrace || Left.OnRightBrace || Left.OnColon || Left.OnComma || Left.OnWhitespace) { return(true); } else if (Left.OnValue) { return(SyntaxEquals(Left.Value, Right.Value)); } else if (Left.OnObject) { return(SyntaxEquals(Left.Object, Right.Object)); } else if (Left.OnMembers) { return(SyntaxEquals(Left.Members, Right.Members)); } else if (Left.OnArray) { return(SyntaxEquals(Left.Array, Right.Array)); } else if (Left.OnElements) { return(SyntaxEquals(Left.Elements, Right.Elements)); } else { throw new InvalidOperationException(); } }
/// <summary> /// Defines a syntax rule for expression statements. /// </summary> /// <param name="rule">The syntax rule.</param> void ISyntaxBuilder.ExpressionStatement(SyntaxRule rule) { var syntax = this.GetOrAddSyntax(ExpressionStatement); syntax.StatementRule = rule; }
private readonly SyntaxRule programRule; // The main rule of the syntax /// <summary> /// Used for initialization of some variables. /// </summary> public SyntaxAnalyzer() { // All the tokens that can appear in the program // Keywords Token tAsm = new Token(TokenType.KEYWORD, "asm", new TokenPosition(0, 0)); Token tBreak = new Token(TokenType.KEYWORD, "break", new TokenPosition(0, 0)); Token tByte = new Token(TokenType.KEYWORD, "byte", new TokenPosition(0, 0)); Token tCode = new Token(TokenType.KEYWORD, "code", new TokenPosition(0, 0)); Token tConst = new Token(TokenType.KEYWORD, "const", new TokenPosition(0, 0)); Token tData = new Token(TokenType.KEYWORD, "data", new TokenPosition(0, 0)); Token tDo = new Token(TokenType.KEYWORD, "do", new TokenPosition(0, 0)); Token tElse = new Token(TokenType.KEYWORD, "else", new TokenPosition(0, 0)); Token tEnd = new Token(TokenType.KEYWORD, "end", new TokenPosition(0, 0)); Token tFor = new Token(TokenType.KEYWORD, "for", new TokenPosition(0, 0)); Token tFormat = new Token(TokenType.KEYWORD, "format", new TokenPosition(0, 0)); Token tFrom = new Token(TokenType.KEYWORD, "from", new TokenPosition(0, 0)); Token tGoto = new Token(TokenType.KEYWORD, "goto", new TokenPosition(0, 0)); Token tIf = new Token(TokenType.KEYWORD, "if", new TokenPosition(0, 0)); Token tInt = new Token(TokenType.KEYWORD, "int", new TokenPosition(0, 0)); Token tLoop = new Token(TokenType.KEYWORD, "loop", new TokenPosition(0, 0)); Token tModule = new Token(TokenType.KEYWORD, "module", new TokenPosition(0, 0)); Token tPragma = new Token(TokenType.KEYWORD, "pragma", new TokenPosition(0, 0)); Token tPrint = new Token(TokenType.KEYWORD, "print", new TokenPosition(0, 0)); Token tReturn = new Token(TokenType.KEYWORD, "return", new TokenPosition(0, 0)); Token tRoutine = new Token(TokenType.KEYWORD, "routine", new TokenPosition(0, 0)); Token tShort = new Token(TokenType.KEYWORD, "short", new TokenPosition(0, 0)); Token tSkip = new Token(TokenType.KEYWORD, "skip", new TokenPosition(0, 0)); Token tStep = new Token(TokenType.KEYWORD, "step", new TokenPosition(0, 0)); Token tStop = new Token(TokenType.KEYWORD, "stop", new TokenPosition(0, 0)); Token tStruct = new Token(TokenType.KEYWORD, "struct", new TokenPosition(0, 0)); Token tTo = new Token(TokenType.KEYWORD, "to", new TokenPosition(0, 0)); Token tWhile = new Token(TokenType.KEYWORD, "while", new TokenPosition(0, 0)); // Itentifiers / Literals / Registers Token tIdentifier = new Token(TokenType.IDENTIFIER, "SOME_IDENTIFIER", new TokenPosition(0, 0)); Token tLiteral = new Token(TokenType.NUMBER, "SOME_LITERAL", new TokenPosition(0, 0)); Token tRegister = new Token(TokenType.REGISTER, "SOME_REGISTER", new TokenPosition(0, 0)); Token tText = new Token(TokenType.TEXT, "SOME_TEXT", new TokenPosition(0, 0)); // Delimiters Token tAt = new Token(TokenType.DELIMITER, "@", new TokenPosition(0, 0)); Token tColon = new Token(TokenType.DELIMITER, ":", new TokenPosition(0, 0)); Token tComma = new Token(TokenType.DELIMITER, ",", new TokenPosition(0, 0)); Token tDot = new Token(TokenType.DELIMITER, ".", new TokenPosition(0, 0)); Token tLeftBracket = new Token(TokenType.DELIMITER, "[", new TokenPosition(0, 0)); Token tLeftParen = new Token(TokenType.DELIMITER, "(", new TokenPosition(0, 0)); Token tRightBracket = new Token(TokenType.DELIMITER, "]", new TokenPosition(0, 0)); Token tRightParen = new Token(TokenType.DELIMITER, ")", new TokenPosition(0, 0)); Token tSemicolon = new Token(TokenType.DELIMITER, ";", new TokenPosition(0, 0)); Token tQuote = new Token(TokenType.DELIMITER, "\\\"", new TokenPosition(0, 0)); // Operators Token tAnd = new Token(TokenType.OPERATOR, "&", new TokenPosition(0, 0)); Token tAndEquals = new Token(TokenType.OPERATOR, "&=", new TokenPosition(0, 0)); Token tAsr = new Token(TokenType.OPERATOR, ">>=", new TokenPosition(0, 0)); Token tAsl = new Token(TokenType.OPERATOR, "<<=", new TokenPosition(0, 0)); Token tAssign = new Token(TokenType.OPERATOR, ":=", new TokenPosition(0, 0)); Token tCnd = new Token(TokenType.OPERATOR, "?", new TokenPosition(0, 0)); Token tCndEquals = new Token(TokenType.OPERATOR, "?=", new TokenPosition(0, 0)); Token tEquals = new Token(TokenType.OPERATOR, "=", new TokenPosition(0, 0)); Token tGreater = new Token(TokenType.OPERATOR, ">", new TokenPosition(0, 0)); Token tLess = new Token(TokenType.OPERATOR, "<", new TokenPosition(0, 0)); Token tLsl = new Token(TokenType.OPERATOR, "<=", new TokenPosition(0, 0)); Token tLsr = new Token(TokenType.OPERATOR, ">=", new TokenPosition(0, 0)); Token tMinus = new Token(TokenType.OPERATOR, "-", new TokenPosition(0, 0)); Token tMinusEquals = new Token(TokenType.OPERATOR, "-=", new TokenPosition(0, 0)); Token tMult = new Token(TokenType.OPERATOR, "*", new TokenPosition(0, 0)); Token tNotEquals = new Token(TokenType.OPERATOR, "/=", new TokenPosition(0, 0)); Token tOr = new Token(TokenType.OPERATOR, "|", new TokenPosition(0, 0)); Token tOrEquals = new Token(TokenType.OPERATOR, "|=", new TokenPosition(0, 0)); Token tPlus = new Token(TokenType.OPERATOR, "+", new TokenPosition(0, 0)); Token tPlusEquals = new Token(TokenType.OPERATOR, "+=", new TokenPosition(0, 0)); Token tSwap = new Token(TokenType.OPERATOR, "<=>", new TokenPosition(0, 0)); Token tTakeAddr = new Token(TokenType.OPERATOR, "<-", new TokenPosition(0, 0)); Token tTakeVal = new Token(TokenType.OPERATOR, "->", new TokenPosition(0, 0)); Token tXor = new Token(TokenType.OPERATOR, "^", new TokenPosition(0, 0)); Token tXorEquals = new Token(TokenType.OPERATOR, "^=", new TokenPosition(0, 0)); // All terminal syntax rules of the language RuleTerminal kAsmRule = new RuleTerminal(tAsm); RuleTerminal kBreakRule = new RuleTerminal(tBreak); RuleTerminal kByteRule = new RuleTerminal(tByte); RuleTerminal kCodeRule = new RuleTerminal(tCode); RuleTerminal kConstRule = new RuleTerminal(tConst); RuleTerminal kDataRule = new RuleTerminal(tData); RuleTerminal kDoRule = new RuleTerminal(tDo); RuleTerminal kElseRule = new RuleTerminal(tElse); RuleTerminal kEndRule = new RuleTerminal(tEnd); RuleTerminal kForRule = new RuleTerminal(tFor); RuleTerminal kFormatRule = new RuleTerminal(tFormat); RuleTerminal kFromRule = new RuleTerminal(tFrom); RuleTerminal kGotoRule = new RuleTerminal(tGoto); RuleTerminal kIfRule = new RuleTerminal(tIf); RuleTerminal kIntRule = new RuleTerminal(tInt); RuleTerminal kLoopRule = new RuleTerminal(tLoop); RuleTerminal kModuleRule = new RuleTerminal(tModule); RuleTerminal kPragmaRule = new RuleTerminal(tPragma); RuleTerminal kPrintRule = new RuleTerminal(tPrint); RuleTerminal kReturnRule = new RuleTerminal(tReturn); RuleTerminal kRoutineRule = new RuleTerminal(tRoutine); RuleTerminal kShortRule = new RuleTerminal(tShort); RuleTerminal kSkipRule = new RuleTerminal(tSkip); RuleTerminal kStepRule = new RuleTerminal(tStep); RuleTerminal kStopRule = new RuleTerminal(tStop); RuleTerminal kStructRule = new RuleTerminal(tStruct); RuleTerminal kToRule = new RuleTerminal(tTo); RuleTerminal kWhileRule = new RuleTerminal(tWhile); RuleTerminal identifierRule = new RuleTerminal(tIdentifier); RuleTerminal numberRule = new RuleTerminal(tLiteral); RuleTerminal registerRule = new RuleTerminal(tRegister); RuleTerminal textRule = new RuleTerminal(tText); RuleTerminal atRule = new RuleTerminal(tAt); RuleTerminal colonRule = new RuleTerminal(tColon); RuleTerminal commaRule = new RuleTerminal(tComma); RuleTerminal dotRule = new RuleTerminal(tDot); RuleTerminal leftBracketRule = new RuleTerminal(tLeftBracket); RuleTerminal leftParenRule = new RuleTerminal(tLeftParen); RuleTerminal rightBracketRule = new RuleTerminal(tRightBracket); RuleTerminal rightParenRule = new RuleTerminal(tRightParen); RuleTerminal semicolonRule = new RuleTerminal(tSemicolon); RuleTerminal quoteRule = new RuleTerminal(tQuote); RuleTerminal opAndRule = new RuleTerminal(tAnd); RuleTerminal opAndEqualsRule = new RuleTerminal(tAndEquals); RuleTerminal opAslRule = new RuleTerminal(tAsl); RuleTerminal opAsrRule = new RuleTerminal(tAsr); RuleTerminal opAssignRule = new RuleTerminal(tAssign); RuleTerminal opCndRule = new RuleTerminal(tCnd); RuleTerminal opCndEqualsRule = new RuleTerminal(tCndEquals); RuleTerminal opEqualsRule = new RuleTerminal(tEquals); RuleTerminal opGreaterRule = new RuleTerminal(tGreater); RuleTerminal opLessRule = new RuleTerminal(tLess); RuleTerminal opLslRule = new RuleTerminal(tLsl); RuleTerminal opLsrRule = new RuleTerminal(tLsr); RuleTerminal opMinusRule = new RuleTerminal(tMinus); RuleTerminal opMinusEqualsRule = new RuleTerminal(tMinusEquals); RuleTerminal opMultRule = new RuleTerminal(tMult); RuleTerminal opNotEqualsRule = new RuleTerminal(tNotEquals); RuleTerminal opOrRule = new RuleTerminal(tOr); RuleTerminal opOrEqualsRule = new RuleTerminal(tOrEquals); RuleTerminal opPlusRule = new RuleTerminal(tPlus); RuleTerminal opPlusEqualsRule = new RuleTerminal(tPlusEquals); RuleTerminal opSwapRule = new RuleTerminal(tSwap); RuleTerminal opTakeAddrRule = new RuleTerminal(tTakeAddr); RuleTerminal opTakeValRule = new RuleTerminal(tTakeVal); RuleTerminal opXorRule = new RuleTerminal(tXor); RuleTerminal opXorEqualsRule = new RuleTerminal(tXorEquals); // All syntax rules of the language SyntaxRule literalRule = new SyntaxRule() .SetName("NUMBER") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule( new SyntaxRule() .SetName("[ - ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule(opMinusRule) ) .AddRule(numberRule); SyntaxRule operatorRule = new SyntaxRule() .SetName("Operator") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(opPlusRule) .AddRule(opMinusRule) .AddRule(opMultRule) .AddRule(opAndRule) .AddRule(opOrRule) .AddRule(opXorRule) .AddRule(opCndRule) .AddRule(opEqualsRule) .AddRule(opNotEqualsRule) .AddRule(opGreaterRule) .AddRule(opLessRule) .AddRule(opLslRule) .AddRule(opLsrRule); SyntaxRule primaryRule = new SyntaxRule() .SetName("Primary") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE); // other rules are added after 'Call args' rule SyntaxRule referenceRule = new SyntaxRule() .SetName("Reference") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(opTakeAddrRule) .AddRule(primaryRule); SyntaxRule dereferenceRule = new SyntaxRule() .SetName("Dereference") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(opTakeValRule) .AddRule(leftBracketRule); // other rules are added after 'Expression' rule SyntaxRule operandRule = new SyntaxRule() .SetName("Operand") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(primaryRule) .AddRule(dereferenceRule) .AddRule(referenceRule) .AddRule(registerRule) .AddRule(literalRule); // other rules are added after 'Expression' rule SyntaxRule expressionRule = new SyntaxRule() .SetName("Expression") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(operandRule) .AddRule( new SyntaxRule() .SetName("{ Operator Operand }") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(operatorRule) .AddRule(operandRule) ); dereferenceRule .AddRule(expressionRule) .AddRule(rightBracketRule); SyntaxRule arrayAccessRule = new SyntaxRule() .SetName("'[' Expression ']'") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(leftBracketRule) .AddRule(expressionRule) .AddRule(rightBracketRule); operandRule .AddRule( new SyntaxRule() .SetName("( Expression )") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(leftParenRule) .AddRule(expressionRule) .AddRule(rightParenRule) ); SyntaxRule typeRule = new SyntaxRule() .SetName("Type") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule( new SyntaxRule() .SetName("int | byte | short [ @ ]") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule( new SyntaxRule() .SetName("int | byte | short") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(kIntRule) .AddRule(kShortRule) .AddRule(kByteRule) ) .AddRule( new SyntaxRule() .SetName("[ @ ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule(atRule) ) ) .AddRule(identifierRule) ; SyntaxRule arrDefinitionRule = new SyntaxRule() .SetName("Array definition") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(identifierRule) .AddRule(leftBracketRule) .AddRule(expressionRule) .AddRule(rightBracketRule) ; SyntaxRule arrayRule = new SyntaxRule() .SetName("Array") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(leftBracketRule) .AddRule(rightBracketRule) .AddRule(arrDefinitionRule) .AddRule( new SyntaxRule() .SetName("{ , ArrDefinition }") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(commaRule) .AddRule(arrDefinitionRule) ) .AddRule(semicolonRule) ; SyntaxRule constDefinitionRule = new SyntaxRule() .SetName("Constant definition") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(identifierRule) .AddRule(opAssignRule) .AddRule(expressionRule) ; SyntaxRule constantRule = new SyntaxRule() .SetName("Constant") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kConstRule) .AddRule(constDefinitionRule) .AddRule( new SyntaxRule() .SetName("{ , ConstDefinition }") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(commaRule) .AddRule(constDefinitionRule) ) .AddRule(semicolonRule); SyntaxRule varDefinitionRule = new SyntaxRule() .SetName("Variable definition") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(identifierRule) .AddRule( new SyntaxRule() .SetName("[ := Expression ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule( new SyntaxRule() .SetName(":= Expression") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(opAssignRule) .AddRule(expressionRule) ) ); SyntaxRule variableRule = new SyntaxRule() .SetName("Variable") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(varDefinitionRule) .AddRule( new SyntaxRule() .SetName("{ , VarDefinition }") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(commaRule) .AddRule(varDefinitionRule) ) .AddRule(semicolonRule); SyntaxRule varDeclarationRule = new SyntaxRule() .SetName("Variable declaration") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(typeRule) .AddRule( new SyntaxRule() .SetName("Variable | Array | Constant") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(variableRule) .AddRule(arrayRule) .AddRule(constantRule) ) ; SyntaxRule assemblyStatementRule = new SyntaxRule() .SetName("Assembly statement") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(kSkipRule) .AddRule(kStopRule) .AddRule( new SyntaxRule() .SetName("format ( 8 | 16 | 32 )") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kFormatRule) .AddRule(literalRule) // The actual check of a number is done in the SemanticsAnalyzer ) .AddRule( new SyntaxRule() .SetName("< Identifier >") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(opLessRule) .AddRule(identifierRule) .AddRule(opGreaterRule) ) .AddRule( new SyntaxRule() .SetName("Register := Identifier") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opAssignRule) .AddRule(identifierRule) ) .AddRule( new SyntaxRule() .SetName("Register := Register + Expression") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opAssignRule) .AddRule(registerRule) .AddRule(opPlusRule) .AddRule(expressionRule) ) .AddRule( new SyntaxRule() .SetName("Register := -> [ Register ]") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opAssignRule) .AddRule(opTakeValRule) .AddRule(leftBracketRule) .AddRule(registerRule) .AddRule(rightBracketRule) ) .AddRule( new SyntaxRule() .SetName("-> [ Register ] := Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(opTakeValRule) .AddRule(leftBracketRule) .AddRule(registerRule) .AddRule(rightBracketRule) .AddRule(opAssignRule) .AddRule(registerRule) ) .AddRule( new SyntaxRule() .SetName("Register := Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opAssignRule) .AddRule(registerRule) ) .AddRule( new SyntaxRule() .SetName("Register := Expression") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opAssignRule) .AddRule(expressionRule) ).AddRule( new SyntaxRule() .SetName("Register += Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opPlusEqualsRule) .AddRule(registerRule) ).AddRule( new SyntaxRule() .SetName("Register -= Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opMinusEqualsRule) .AddRule(registerRule) ).AddRule( new SyntaxRule() .SetName("Register >>= Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opAsrRule) .AddRule(registerRule) ).AddRule( new SyntaxRule() .SetName("Register <<= Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opAslRule) .AddRule(registerRule) ).AddRule( new SyntaxRule() .SetName("Register |= Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opOrEqualsRule) .AddRule(registerRule) ).AddRule( new SyntaxRule() .SetName("Register &= Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opAndEqualsRule) .AddRule(registerRule) ).AddRule( new SyntaxRule() .SetName("Register ^= Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opXorEqualsRule) .AddRule(registerRule) ).AddRule( new SyntaxRule() .SetName("Register >= Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opLsrRule) .AddRule(registerRule) ).AddRule( new SyntaxRule() .SetName("Register <= Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opLslRule) .AddRule(registerRule) ).AddRule( new SyntaxRule() .SetName("Register ?= Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(registerRule) .AddRule(opCndEqualsRule) .AddRule(registerRule) ).AddRule( new SyntaxRule() .SetName("if Register goto Register") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kIfRule) .AddRule(registerRule) .AddRule(kGotoRule) .AddRule(registerRule) ); SyntaxRule assemblyBlockRule = new SyntaxRule() .SetName("Assembly block") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kAsmRule) .AddRule(assemblyStatementRule) .AddRule(semicolonRule) .AddRule( new SyntaxRule() .SetName("{ AssemblyStatement ; }") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(assemblyStatementRule) .AddRule(semicolonRule) ) .AddRule(kEndRule); SyntaxRule receiverRule = new SyntaxRule() .SetName("Receiver") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(primaryRule) .AddRule(dereferenceRule) .AddRule(registerRule); SyntaxRule assignmentRule = new SyntaxRule() .SetName("Assignment") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(receiverRule) .AddRule(opAssignRule) .AddRule(expressionRule) .AddRule(semicolonRule); SyntaxRule swapRule = new SyntaxRule() .SetName("Swap") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(receiverRule) .AddRule(opSwapRule) .AddRule(receiverRule) .AddRule(semicolonRule); SyntaxRule callArgsRule = new SyntaxRule() .SetName("Call arguments") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(leftParenRule) .AddRule( new SyntaxRule() .SetName("[ Expression { , Expression } ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule(expressionRule) .AddRule( new SyntaxRule() .SetName("{ , Expression }") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(commaRule) .AddRule(expressionRule) ) ) .AddRule(rightParenRule); SyntaxRule callRule = new SyntaxRule() .SetName("Call") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(identifierRule) .AddRule(callArgsRule); primaryRule .AddRule(identifierRule) .AddRule( new SyntaxRule() .SetName("{ '.' Identifier }") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(dotRule) .AddRule(identifierRule) ) .AddRule( new SyntaxRule() .SetName("[ ArrayAccess | CallArgs ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule( new SyntaxRule() .SetName("ArrayAccess | CallArgs") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(arrayAccessRule) .AddRule(callArgsRule) ) ); SyntaxRule blockBodyRule = new SyntaxRule() .SetName("Block body") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) ; // other rules added after 'Statement' rule SyntaxRule ifRule = new SyntaxRule() .SetName("If") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kIfRule) .AddRule(expressionRule) .AddRule(kDoRule) .AddRule(blockBodyRule) .AddRule( new SyntaxRule() .SetName("end | else BlockBody end") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(kEndRule) .AddRule( new SyntaxRule() .SetName("else BlockBody end") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kElseRule) .AddRule(blockBodyRule) .AddRule(kEndRule) ) ); SyntaxRule loopBodyRule = new SyntaxRule() .SetName("Loop body") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kLoopRule) .AddRule(blockBodyRule); SyntaxRule loopWhileRule = new SyntaxRule() .SetName("Loop While") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(loopBodyRule) .AddRule(kWhileRule) .AddRule(expressionRule) .AddRule(kEndRule); SyntaxRule whileRule = new SyntaxRule() .SetName("While") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kWhileRule) .AddRule(expressionRule) .AddRule(loopBodyRule) .AddRule(kEndRule); SyntaxRule forRule = new SyntaxRule() .SetName("For") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kForRule) .AddRule(identifierRule) .AddRule( new SyntaxRule() .SetName("[ from Expression ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule(kFromRule) .AddRule(expressionRule) ) .AddRule( new SyntaxRule() .SetName("[ to Expression ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule(kToRule) .AddRule(expressionRule) ) .AddRule( new SyntaxRule() .SetName("[ step Expression ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule(kStepRule) .AddRule(expressionRule) ) .AddRule(loopBodyRule) .AddRule(kEndRule); SyntaxRule loopRule = new SyntaxRule() .SetName("Loop") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(forRule) .AddRule(whileRule) .AddRule(loopWhileRule); SyntaxRule gotoRule = new SyntaxRule() .SetName("Goto") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kGotoRule) .AddRule(identifierRule) .AddRule(semicolonRule); SyntaxRule breakRule = new SyntaxRule() .SetName("Break") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kBreakRule) .AddRule(semicolonRule); SyntaxRule returnRule = new SyntaxRule() .SetName("Return") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kReturnRule) .AddRule( new SyntaxRule() .SetName("[ ( Expression | Call ) ] ; ") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule( new SyntaxRule() .SetName("[ Expression | Call ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule( new SyntaxRule() .SetName("Expression | Call") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(expressionRule) .AddRule(callRule) ) ) .AddRule(semicolonRule) ); SyntaxRule printRule = new SyntaxRule() .SetName("Print") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kPrintRule) .AddRule(expressionRule) .AddRule(semicolonRule); SyntaxRule extensionStatementRule = new SyntaxRule() .SetName("Extension statement") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(assignmentRule) .AddRule(swapRule) .AddRule( new SyntaxRule() .SetName("Call ;") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(callRule) .AddRule(semicolonRule) ) .AddRule(ifRule) .AddRule(loopRule) .AddRule(breakRule) .AddRule(gotoRule) .AddRule(returnRule) .AddRule(varDeclarationRule) .AddRule(printRule); SyntaxRule labelRule = new SyntaxRule() .SetName("Goto label") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(opLessRule) .AddRule(identifierRule) .AddRule(opGreaterRule); SyntaxRule statementRule = new SyntaxRule() .SetName("Statement") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule( new SyntaxRule() .SetName("[ Goto label ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule(labelRule) ) .AddRule( new SyntaxRule() .SetName("Assembly Block | Extension Statement") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(assemblyBlockRule) .AddRule(extensionStatementRule) ); blockBodyRule .AddRule(statementRule); SyntaxRule routineBodyRule = new SyntaxRule() .SetName("Routine body") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kDoRule) .AddRule( new SyntaxRule() .SetName("{ Statement }") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(statementRule) ) .AddRule(kEndRule); SyntaxRule parameterRule = new SyntaxRule() .SetName("Parameter") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(typeRule) .AddRule(identifierRule); SyntaxRule parametersRule = new SyntaxRule() .SetName("Parameters") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(parameterRule) .AddRule( new SyntaxRule() .SetName("{ , Parameter }") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(commaRule) .AddRule(parameterRule) ); SyntaxRule routineRule = new SyntaxRule() .SetName("Routine") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kRoutineRule) .AddRule(identifierRule) .AddRule(leftParenRule) .AddRule( new SyntaxRule() .SetName("[ Parameters ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule(parametersRule) ) .AddRule(rightParenRule) .AddRule( new SyntaxRule() .SetName("[ : Type ]") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule(colonRule) .AddRule(typeRule) ) .AddRule(routineBodyRule); SyntaxRule structureRule = new SyntaxRule() .SetName("Structure") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kStructRule) .AddRule(identifierRule) .AddRule( new SyntaxRule() .SetName("{ Variable declarations }") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(varDeclarationRule) ) .AddRule(kEndRule); SyntaxRule moduleRule = new SyntaxRule() .SetName("Module") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kModuleRule) .AddRule(identifierRule) .AddRule( new SyntaxRule() .SetName("Module statements") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule( new SyntaxRule() .SetName("Some module statement") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(varDeclarationRule) .AddRule(routineRule) .AddRule(structureRule) ) ) .AddRule(kEndRule); SyntaxRule dataRule = new SyntaxRule() .SetName("Data") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kDataRule) .AddRule(identifierRule) .AddRule(literalRule) .AddRule( new SyntaxRule() .SetName("Data literals") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(literalRule) ) .AddRule(kEndRule); SyntaxRule pragmaDeclRule = new SyntaxRule() .SetName("Pragma declaration") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(identifierRule) .AddRule(leftParenRule) .AddRule( new SyntaxRule() .SetName("Pragma parameter") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_ONE) .AddRule(quoteRule) .AddRule(textRule) .AddRule(quoteRule) ) .AddRule(rightParenRule); SyntaxRule annotationsRule = new SyntaxRule() .SetName("Annotations") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kPragmaRule) .AddRule(pragmaDeclRule) .AddRule( new SyntaxRule() .SetName("Pragma declarations") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(pragmaDeclRule) ) .AddRule(kEndRule); SyntaxRule codeRule = new SyntaxRule() .SetName("Code") .SetType(SyntaxRule.SyntaxRuleType.SEQUENCE) .AddRule(kCodeRule) .AddRule( new SyntaxRule() .SetName("{ Statement }") .SetType(SyntaxRule.SyntaxRuleType.ZERO_OR_MORE) .AddRule(statementRule) ) .AddRule(kEndRule); programRule = new SyntaxRule() .SetName("Program") .SetType(SyntaxRule.SyntaxRuleType.ONE_OR_MORE) .AddRule( new SyntaxRule() .SetName("Some unit") .SetType(SyntaxRule.SyntaxRuleType.OR) .AddRule(annotationsRule) .AddRule(dataRule) .AddRule(moduleRule) .AddRule(codeRule) .AddRule(structureRule) .AddRule(routineRule) ); }
/// <summary> /// Specifies a nonempty rule collection /// </summary> /// <param name="rule"></param> /// <returns></returns> public static ZeroOrMore zeroOrMore(SyntaxRule rule) => new ZeroOrMore(rule);
/// <summary> /// Specifies a nonempty rule collection /// </summary> /// <param name="rule"></param> /// <returns></returns> public static OneOrMore oneOrMore(SyntaxRule rule) => + rule;
public static void DoTest() { Assert(SyntaxEquals(TokenParse(@"""123abc\u0020\t\"""""), SyntaxRule.CreateLiteral(TokenLiteral.CreateStringValue("123abc \t\"")))); Assert(SyntaxEquals(TokenParse(@"0"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(0)))); Assert(SyntaxEquals(TokenParse(@"-1000"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(-1000)))); Assert(SyntaxEquals(TokenParse(@"0.0"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(0)))); Assert(SyntaxEquals(TokenParse(@"123.456"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(123.456)))); Assert(SyntaxEquals(TokenParse(@"-10.1"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(-10.1)))); Assert(SyntaxEquals(TokenParse(@"100.001e10"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(100.001e10)))); Assert(SyntaxEquals(TokenParse(@"-100.00e+10"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(-100.00e+10)))); Assert(SyntaxEquals(TokenParse(@"100.001e-10"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(100.001e-10)))); Assert(SyntaxEquals(TokenParse(@"1.23456789123456789123456789e10"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(1.23456789123456789123456789e10)))); Assert(SyntaxEquals(TokenParse(@"1.79769e+308"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(1.79769e+308)))); Assert(SyntaxEquals(TokenParse(@"-1.79769e+308"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(-1.79769e+308)))); Assert(SyntaxEquals(TokenParse(@"2.22507e-308"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(2.22507e-308)))); Assert(SyntaxEquals(TokenParse(@"-2.22507e-308"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNumberValue(-2.22507e-308)))); Assert(SyntaxEquals(TokenParse(@"null"), SyntaxRule.CreateLiteral(TokenLiteral.CreateNullValue()))); Assert(SyntaxEquals(TokenParse(@"false"), SyntaxRule.CreateLiteral(TokenLiteral.CreateBooleanValue(false)))); Assert(SyntaxEquals(TokenParse(@"true"), SyntaxRule.CreateLiteral(TokenLiteral.CreateBooleanValue(true)))); Assert(SyntaxEquals(TokenParse(@"{"), SyntaxRule.CreateLeftBrace())); Assert(SyntaxEquals(TokenParse(@"}"), SyntaxRule.CreateRightBrace())); Assert(SyntaxEquals(TokenParse(@"["), SyntaxRule.CreateLeftBracket())); Assert(SyntaxEquals(TokenParse(@"]"), SyntaxRule.CreateRightBracket())); Assert(SyntaxEquals(TokenParse(@":"), SyntaxRule.CreateColon())); Assert(SyntaxEquals(TokenParse(@","), SyntaxRule.CreateComma())); Assert(SyntaxEquals(TokenParse(" \t\r\n"), SyntaxRule.CreateWhitespace())); Assert(SyntaxEquals(SyntaxParse("null"), SyntaxValue.CreateLiteral(TokenLiteral.CreateNullValue()))); Assert(SyntaxEquals(SyntaxParse("false"), SyntaxValue.CreateLiteral(TokenLiteral.CreateBooleanValue(false)))); Assert(SyntaxEquals(SyntaxParse("true"), SyntaxValue.CreateLiteral(TokenLiteral.CreateBooleanValue(true)))); Assert(SyntaxEquals(SyntaxParse("123"), SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(123)))); Assert(SyntaxEquals(SyntaxParse("\"123\""), SyntaxValue.CreateLiteral(TokenLiteral.CreateStringValue("123")))); Assert(SyntaxEquals(SyntaxParse(" null "), SyntaxValue.CreateLiteral(TokenLiteral.CreateNullValue()))); Assert(SyntaxEquals(SyntaxParse(" false "), SyntaxValue.CreateLiteral(TokenLiteral.CreateBooleanValue(false)))); Assert(SyntaxEquals(SyntaxParse(" true "), SyntaxValue.CreateLiteral(TokenLiteral.CreateBooleanValue(true)))); Assert(SyntaxEquals(SyntaxParse(" 123 "), SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(123)))); Assert(SyntaxEquals(SyntaxParse(" \"123\" "), SyntaxValue.CreateLiteral(TokenLiteral.CreateStringValue("123")))); Assert(SyntaxEquals(SyntaxParse("{}"), SyntaxValue.CreateObject(new SyntaxObject { Members = Optional <SyntaxMembers> .Empty }))); Assert(SyntaxEquals(SyntaxParse("[]"), SyntaxValue.CreateArray(new SyntaxArray { Elements = Optional <SyntaxElements> .Empty }))); Assert(SyntaxEquals(SyntaxParse("{ }"), SyntaxValue.CreateObject(new SyntaxObject { Members = Optional <SyntaxMembers> .Empty }))); Assert(SyntaxEquals(SyntaxParse("[ ]"), SyntaxValue.CreateArray(new SyntaxArray { Elements = Optional <SyntaxElements> .Empty }))); Assert(SyntaxEquals(SyntaxParse(" { }"), SyntaxValue.CreateObject(new SyntaxObject { Members = Optional <SyntaxMembers> .Empty }))); Assert(SyntaxEquals(SyntaxParse(" [ ]"), SyntaxValue.CreateArray(new SyntaxArray { Elements = Optional <SyntaxElements> .Empty }))); Assert(SyntaxEquals(SyntaxParse(" { } "), SyntaxValue.CreateObject(new SyntaxObject { Members = Optional <SyntaxMembers> .Empty }))); Assert(SyntaxEquals(SyntaxParse(" [ ] "), SyntaxValue.CreateArray(new SyntaxArray { Elements = Optional <SyntaxElements> .Empty }))); Assert(SyntaxEquals(SyntaxParse("{\"key\":1}"), SyntaxValue.CreateObject(new SyntaxObject { Members = SyntaxMembers.CreateSingle(new Tuple <TokenLiteral, SyntaxValue>(TokenLiteral.CreateStringValue("key"), SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(1)))) }))); Assert(SyntaxEquals(SyntaxParse("[1]"), SyntaxValue.CreateArray(new SyntaxArray { Elements = SyntaxElements.CreateSingle(SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(1))) }))); Assert(SyntaxEquals(SyntaxParse("{ \"key\" : 1 }"), SyntaxValue.CreateObject(new SyntaxObject { Members = SyntaxMembers.CreateSingle(new Tuple <TokenLiteral, SyntaxValue>(TokenLiteral.CreateStringValue("key"), SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(1)))) }))); Assert(SyntaxEquals(SyntaxParse("[ 1 ]"), SyntaxValue.CreateArray(new SyntaxArray { Elements = SyntaxElements.CreateSingle(SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(1))) }))); Assert(SyntaxEquals(SyntaxParse("{\"key\":1,\"value\":2}"), SyntaxValue.CreateObject(new SyntaxObject { Members = SyntaxMembers.CreateMultiple(new Tuple <SyntaxMembers, TokenLiteral, SyntaxValue>(SyntaxMembers.CreateSingle(new Tuple <TokenLiteral, SyntaxValue>(TokenLiteral.CreateStringValue("key"), SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(1)))), TokenLiteral.CreateStringValue("value"), SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(2)))) }))); Assert(SyntaxEquals(SyntaxParse("[1,2]"), SyntaxValue.CreateArray(new SyntaxArray { Elements = SyntaxElements.CreateMultiple(new Tuple <SyntaxElements, SyntaxValue>(SyntaxElements.CreateSingle(SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(1))), SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(2)))) }))); Assert(SyntaxEquals(SyntaxParse("{ \"key\" : 1, \"value\" : 2 }"), SyntaxValue.CreateObject(new SyntaxObject { Members = SyntaxMembers.CreateMultiple(new Tuple <SyntaxMembers, TokenLiteral, SyntaxValue>(SyntaxMembers.CreateSingle(new Tuple <TokenLiteral, SyntaxValue>(TokenLiteral.CreateStringValue("key"), SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(1)))), TokenLiteral.CreateStringValue("value"), SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(2)))) }))); Assert(SyntaxEquals(SyntaxParse("[ 1, 2 ]"), SyntaxValue.CreateArray(new SyntaxArray { Elements = SyntaxElements.CreateMultiple(new Tuple <SyntaxElements, SyntaxValue>(SyntaxElements.CreateSingle(SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(1))), SyntaxValue.CreateLiteral(TokenLiteral.CreateNumberValue(2)))) }))); }