private void readLine() { Contract.Requires(!hasReadToEnd); // 次の行のテキストを得る ++lineNumber; string line = reader.ReadLine(); if (line == null) { hasReadToEnd = true; return; } // トークンの種類ごとに判別してtokensに追加 foreach (Match match in regex.Matches(line)) { Contract.Assume(match != null); Contract.Assume(match.Groups["integer"] != null); Contract.Assume(match.Groups["identifier"] != null); Contract.Assume(match.Groups["operator"] != null); Contract.Assume(match.Groups["string"] != null); Token token = null; if (match.Groups["integer"].Success) { token = new IntegerToken(lineNumber, Convert.ToInt32(match.Groups["integer"].Value, 10)); } else if (match.Groups["identifier"].Success) { Contract.Assume(match.Groups["identifier"].Value.Length != 0); token = new IdentifierToken(lineNumber, match.Groups["identifier"].Value); } else if (match.Groups["operator"].Success) { string key = match.Groups["operator"].Value; Contract.Assume(operatorTypes.ContainsKey(key)); token = new OperatorToken(lineNumber, operatorTypes[key]); } else if (match.Groups["string"].Success) { token = new StringToken(lineNumber, match.Groups["string"].Value); } else { throw new NotImplementedException(); } Contract.Assert(token != null); tokens.AddLast(token); } }
/* * statement : varStatement | ifStatement | forStatement | whileStatement | funcStatement | block | simple * varStatement : varExpression ";" * varExpression : "var" IDENTIFIER [ "=" expression ] * ifStatement : "if" "(" expression ")" statement [ "else" statement ] * forStatement : "for" "(" [ varExpression | expression ] ";" [ expression ] ";" [expression] ")" statement * whileStatement : "while" "(" expression ")" statement * funcStatement : "function" IDENTIFIER "(" [ arguments ] ")" block * arguments : IDENTIFIER { "," IDENTIFIER } * simple : ";" | expression ";" * block : "{" { statement } "}" * expression : literal { binary_op literal } * literal : void | true | false | STRING | ["+"|"-"] NUMBER | factor * factor : ( IDENTIFIER | "(" expression ")" ) [ funcCall ] * funcCall : "(" [parameters] ")" * parameters : expression { "," expression } * binary_op : "==" | "!=" | "&&" | "||" | "<=" | ">=" | "=" | "+" | "-" | "*" | "/" | "%" | "<" | ">" */ private INode statement() { Contract.Ensures(Contract.Result <INode>() != null); Token token = lexer.Peek(0); if (token.Type == TokenType.Operator) { OperatorToken operatorToken = (OperatorToken)token; if (operatorToken.Value != OperatorType.LeftBrace) { throw new SyntaxException(lexer.LineNumber); } return(block()); } else if (token.Type == TokenType.Identifier) { var identifierToken = (IdentifierToken)token; if (identifierToken.Value == "var") { return(varStatement()); } if (identifierToken.Value == "if") { return(ifStatement()); } if (identifierToken.Value == "for") { return(forStatement()); } if (identifierToken.Value == "while") { return(whileStatement()); } if (identifierToken.Value == "function") { return(funcStatement()); } } return(simple()); }