예제 #1
0
        public override string WriteParseCode(TextWriter writer, ScriptParserGenerator generator)
        {
            IList <string>   firsts     = _innerExpression.GetFirstTerminals(generator);
            IList <string>   followings = this.GetFollowingTerminals(generator);
            HashSet <string> firstSet   = new HashSet <string>(firsts);

            foreach (string following in followings)
            {
                if (firstSet.Contains(following))
                {
                    string context = string.Format("'{0}' の定義", this.RootDefinition.DefinitionName);
                    string message = string.Format("省略可能な <{1}> の直後に <{0}> がありますが <{1}> の方が優先されます", following, this.ToString());
                    generator.Warn(context, message);
                }
            }

            ParameterSignature returnParam = this.GetReturnParameterSignature(generator);
            string             returnType  = returnParam.GetTypeName();
            string             returnVar;

            writer.WriteLine(generator.GetCodeOfDeclareDefault(returnType, out returnVar));
            string peekVar;

            writer.WriteLine(generator.GetCodeOfPeek(out peekVar));
            writer.WriteLine(generator.GetCodeOfIfOptionalLexisIn(peekVar, firsts));
            string innerVar = _innerExpression.WriteParseCode(writer, generator);

            writer.WriteLine(generator.GetCodeOfSubstitution(returnVar, innerVar));
            writer.WriteLine(generator.GetCodeOfCloseBlock());
            return(returnVar);
        }
예제 #2
0
 public override string WriteParseCode(TextWriter writer, ScriptParserGenerator generator)
 {
     Debug.Assert(_elements.Count >= 1);
     if (_elements.Count == 1)
     {
         return(_elements.First().WriteParseCode(writer, generator));
     }
     else
     {
         List <string> innerVars = new List <string>();
         foreach (ElementElement elem in _elements)
         {
             string var = elem.WriteParseCode(writer, generator);
             innerVars.Add(var);
         }
         ParameterSignature returnParam = this.GetReturnParameterSignature(generator);
         string             returnType  = returnParam.GetTypeName();
         string             returnVar;
         writer.WriteLine(generator.GetCodeOfDeclareNew(returnType, innerVars, out returnVar));
         return(returnVar);
     }
 }
예제 #3
0
        public override string WriteParseCode(TextWriter writer, ScriptParserGenerator generator)
        {
            IList <string>   firsts     = _innerExpression.GetFirstTerminals(generator);
            IList <string>   followings = this.GetFollowingTerminals(generator);
            HashSet <string> firstSet   = new HashSet <string>(firsts);

            foreach (string following in followings)
            {
                if (firstSet.Contains(following))
                {
                    string context = string.Format("'{0}' の定義", this.RootDefinition.DefinitionName);
                    string message = string.Format("<{1}> の直後の <{0}> は <{1}> によって隠されます", following, this.ToString());
                    generator.Warn(context, message);
                }
            }
            ParameterSignature returnParam   = this.GetReturnParameterSignature(generator);
            ParameterSignature innerParam    = _innerExpression.GetReturnParameterSignature(generator);
            string             innerType     = innerParam.GetTypeName();
            string             innerListType = string.Format("List<{0}>", innerType);
            string             innerListVar;

            writer.WriteLine(generator.GetCodeOfDeclareNew(innerListType, out innerListVar));
            string peek;

            writer.WriteLine(generator.GetCodeOfForPeekLexisIn(firsts, out peek));
            string innerVar = _innerExpression.WriteParseCode(writer, generator);

            writer.WriteLine(generator.GetCodeOfInvoke(innerListVar, "Add", innerVar));
            writer.WriteLine(generator.GetCodeOfCloseBlock());
            string returnType = returnParam.GetTypeName();
            string returnVar;

            writer.WriteLine(generator.GetCodeOfDeclare(returnType, out returnVar));
            writer.WriteLine(generator.GetCodeOfInvokeSubstitute(returnVar, innerListVar, "ToArray"));
            return(returnVar);
        }
예제 #4
0
        public override string WriteParseCode(TextWriter writer, ScriptParserGenerator generator)
        {
            if (false)
            {
                // 普通のコード
                Debug.Assert(_candidates.Count >= 1);
                if (_candidates.Count == 1)
                {
                    return(_candidates.First().WriteParseCode(writer, generator));
                }
                else
                {
                    IList <string> firsts = this.GetFirstTerminals(generator);
                    string         peekVar;
                    writer.WriteLine(generator.GetCodeOfPeekOrThrow(this.RootDefinition.DefinitionName, firsts, out peekVar));
                    bool oneClassType;
                    ParameterSignature returnParam = GetReturnParameterSignature(generator, out oneClassType);
                    string             returnType  = returnParam.GetTypeName();
                    string             returnVar;
                    writer.WriteLine(generator.GetCodeOfDeclareDefault(returnType, out returnVar));
                    Dictionary <string, string> usedFirsts = new Dictionary <string, string>();
                    foreach (ElementsElement elems in _candidates)
                    {
                        IList <string> innerFirsts = elems.GetFirstTerminals(generator);
                        foreach (string first in innerFirsts)
                        {
                            string usingPoint;
                            if (usedFirsts.TryGetValue(first, out usingPoint))
                            {
                                string context = string.Format("'{0}' の定義", this.RootDefinition.DefinitionName);
                                string message = string.Format("<{1}> 内の <{0}> は <{2}> によって隠されます", first, this.ToString(), usingPoint);
                                generator.Warn(context, message);
                            }
                            else
                            {
                                usedFirsts[first] = elems.ToString();
                            }
                        }
                        writer.WriteLine(generator.GetCodeOfIfLexisIn(peekVar, innerFirsts));
                        string candidateVar = elems.WriteParseCode(writer, generator);
                        if (oneClassType)
                        {
                            writer.WriteLine(generator.GetCodeOfSubstitution(returnVar, candidateVar));
                        }
                        else
                        {
                            string selectVar;
                            writer.WriteLine(generator.GetCodeOfDeclareNew(returnType, new[] { candidateVar }, out selectVar));

                            writer.WriteLine(generator.GetCodeOfSubstitution(returnVar, selectVar));
                        }
                        writer.Write(generator.GetCodeOfCloseBlock());
                        writer.Write(generator.GetCodeOfSingleElse());
                    }
                    writer.Write(generator.GetCodeOfOpenBlock());
                    writer.WriteLine(generator.GetCodeOfCloseBlock());
                    return(returnVar);
                }
            }
            else
            {
                // 前半部分が同じSelectionをツリー状に探索するようにするために
                // SelectionSubCandidateを作る
                List <SelectionSubCandidate> subCandidates = new List <SelectionSubCandidate>();
                foreach (ElementsElement candidate in _candidates)
                {
                    subCandidates.Add(new SelectionSubCandidate(candidate));
                }
                bool oneClassType;
                ParameterSignature returnParam = this.GetReturnParameterSignature(generator, out oneClassType);
                string             returnVariableName;
                writer.WriteLine(generator.GetCodeOfDeclareDefault(returnParam.GetTypeName(), out returnVariableName));

                SelectionSubCandidate.writeParseCodeAux(writer, generator, subCandidates, (candidateAtEmpty, writer2, generator2) => {
                    // 候補の要素が単一要素の場合はFixedListをnewしなくてよいので分ける
                    string resultVar;
                    if (candidateAtEmpty.OriginalElements.Elements.Count == 1)
                    {
                        resultVar = candidateAtEmpty.TemporaryVariables.First();
                    }
                    else
                    {
                        ParameterSignature returnParam2 = candidateAtEmpty.OriginalElements.GetReturnParameterSignature(generator2);
                        string typename = returnParam2.GetTypeName();
                        writer2.WriteLine(generator2.GetCodeOfDeclareNew(typename, candidateAtEmpty.TemporaryVariables, out resultVar));
                    }
                    bool oneClassReturn;
                    ParameterSignature tmpReturnParam = this.GetReturnParameterSignature(generator2, out oneClassReturn);
                    if (!oneClassReturn)
                    {
                        // 一回Selection<>を作成しないといけない
                        string tmpTypename = tmpReturnParam.GetTypeName();
                        string tmpResultVar;
                        writer.WriteLine(generator2.GetCodeOfDeclareNew(tmpTypename, new[] { resultVar }, out tmpResultVar));
                        resultVar = tmpResultVar;
                    }
                    writer2.WriteLine(generator.GetCodeOfSubstitution(returnVariableName, resultVar));
                });
                return(returnVariableName);
            }
        }