Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Diff of /trunk/Cm/Cm.Parser/Parameter.cpp [000000] .. [r1] Maximize Restore

  Switch to side-by-side view

--- a
+++ b/trunk/Cm/Cm.Parser/Parameter.cpp
@@ -0,0 +1,263 @@
+#include "Parameter.hpp"
+#include <Soul.Parsing/ParsingDomain.hpp>
+#include <Soul.Parsing/Primitive.hpp>
+#include <Soul.Parsing/Composite.hpp>
+#include <Soul.Parsing/NonTerminal.hpp>
+#include <Soul.Parsing/Exception.hpp>
+#include <Soul.Parsing/StdLib.hpp>
+#include <Cm.Parser/Identifier.hpp>
+#include <Cm.Parser/Expression.hpp>
+
+
+namespace Cm { namespace Parser {
+
+using Cm::Core::Parameter;
+using Cm::Core::ParameterListPtr;
+using Cm::Core::ParameterList;
+using namespace Soul::Parsing;
+
+ParameterParserGrammarPtr ParameterParser::Create()
+{
+    return Create(ParsingDomainPtr(new ParsingDomain()));
+}
+
+ParameterParserGrammarPtr ParameterParser::Create(const ParsingDomainPtr& parsingDomain)
+{
+    ParameterParserGrammarPtr grammar(new ParameterParser(parsingDomain));
+    parsingDomain->AddGrammar(grammar);
+    grammar->CreateRules();
+    grammar->Link();
+    return grammar;
+}
+
+ParameterParser::ParameterParser(const ParsingDomainPtr& parsingDomain_): Soul::Parsing::Grammar("ParameterParser", "Cm.Parser.ParameterParser", parsingDomain_)
+{
+}
+
+ParameterPtr ParameterParser::Parse(const String& content, int fileIndex, const String& fileName, ScopePtr scope, int index)
+{
+    Scanner scanner(content, fileIndex, fileName, Skip());
+    if (Log())
+    {
+        scanner.Log() = XmlLogPtr(new XmlLog(*Log(), MaxLogLineLength()));
+        scanner.Log()->WriteBeginRule("parse");
+    }
+    ObjectStack stack;
+    stack.push(ObjectPtr(new ValueObject<ScopePtr>(scope)));
+    stack.push(ObjectPtr(new ValueObject<int>(index)));
+    Match match = Grammar::Parse(scanner, stack);
+    Position stop = scanner.GetPosition();
+    if (Log())
+    {
+        scanner.Log()->WriteEndRule("parse");
+    }
+    if (!match.Hit() || stop.index != content.length())
+    {
+        if (Start())
+        {
+            throw ExpectationFailure(Start()->Info(), content, scanner.GetPosition(), fileName);
+        }
+        else
+        {
+            throw ParsingException("grammar '" + Name() + "' has no start rule", content, scanner.GetPosition(), fileName);
+        }
+    }
+    ParameterPtr value = *boost::static_pointer_cast< ValueObject<ParameterPtr> >(stack.top());
+    stack.pop();
+    return value;
+}
+
+class ParameterParser::ParameterRuleParser : public RuleParser
+{
+public:
+    ParameterRuleParser(const String& name_, const String& fullName_, ParserPtr definition_):
+        RuleParser(name_, fullName_, definition_), contextStack(), context()
+    {
+        InheritedAttributes().push_back(AttrOrVariable("ScopePtr", "scope"));
+        InheritedAttributes().push_back(AttrOrVariable("int", "index"));
+        ValueTypeName() = "ParameterPtr";
+    }
+    virtual void Enter(ObjectStack& stack)
+    {
+        contextStack.push(context);
+        context = ContextPtr(new Context());
+        context->index = *boost::static_pointer_cast< ValueObject<int> >(stack.top());
+        stack.pop();
+        context->scope = *boost::static_pointer_cast< ValueObject<ScopePtr> >(stack.top());
+        stack.pop();
+    }
+    virtual void Leave(ObjectStack& stack, bool matched)
+    {
+        if (matched)
+        {
+            stack.push(ObjectPtr(new ValueObject<ParameterPtr>(context->value)));
+        }
+        context = contextStack.top();
+        contextStack.pop();
+    }
+    virtual void Link()
+    {
+        ActionParserPtr a0ActionParser = GetAction("A0");
+        a0ActionParser->SetAction(ParsingActionPtr(new MemberParsingAction<ParameterRuleParser>(this, &ParameterRuleParser::A0Action)));
+        ActionParserPtr a1ActionParser = GetAction("A1");
+        a1ActionParser->SetAction(ParsingActionPtr(new MemberParsingAction<ParameterRuleParser>(this, &ParameterRuleParser::A1Action)));
+        NonTerminalParserPtr typeExprNonTerminalParser = GetNonTerminal("TypeExpr");
+        typeExprNonTerminalParser->SetPreCall(PreCallPtr(new MemberPreCall<ParameterRuleParser>(this, &ParameterRuleParser::PreTypeExpr)));
+        typeExprNonTerminalParser->SetPostCall(PostCallPtr(new MemberPostCall<ParameterRuleParser>(this, &ParameterRuleParser::PostTypeExpr)));
+        NonTerminalParserPtr identifierNonTerminalParser = GetNonTerminal("Identifier");
+        identifierNonTerminalParser->SetPostCall(PostCallPtr(new MemberPostCall<ParameterRuleParser>(this, &ParameterRuleParser::PostIdentifier)));
+    }
+    void A0Action(const String& match, const String& content, const Position& position, const String& fileName, bool& pass)
+    {
+        context->value = ParameterPtr(new Parameter(context->fromIdentifier, position, context->scope, context->index, context->fromTypeExpr));
+    }
+    void A1Action(const String& match, const String& content, const Position& position, const String& fileName, bool& pass)
+    {
+        context->value = ParameterPtr(new Parameter("<parameter>", position, context->scope, context->index, context->fromTypeExpr));
+    }
+    void PreTypeExpr(ObjectStack& stack)
+    {
+        stack.push(ObjectPtr(new ValueObject<ScopePtr>(context->scope)));
+    }
+    void PostTypeExpr(ObjectStack& stack, bool matched)
+    {
+        if (matched)
+        {
+            context->fromTypeExpr = *boost::static_pointer_cast< ValueObject<EntityPtr> >(stack.top());
+            stack.pop();
+        }
+    }
+    void PostIdentifier(ObjectStack& stack, bool matched)
+    {
+        if (matched)
+        {
+            context->fromIdentifier = *boost::static_pointer_cast< ValueObject<String> >(stack.top());
+            stack.pop();
+        }
+    }
+private:
+    struct Context : Loki::SmallObject<>
+    {
+        Context(): scope(), index(), value(), fromTypeExpr(), fromIdentifier() {}
+        ScopePtr scope;
+        int index;
+        ParameterPtr value;
+        EntityPtr fromTypeExpr;
+        String fromIdentifier;
+    };
+    typedef boost::shared_ptr<Context> ContextPtr;
+    std::stack<ContextPtr> contextStack;
+    ContextPtr context;
+};
+
+class ParameterParser::ParameterListRuleParser : public RuleParser
+{
+public:
+    ParameterListRuleParser(const String& name_, const String& fullName_, ParserPtr definition_):
+        RuleParser(name_, fullName_, definition_), contextStack(), context()
+    {
+        InheritedAttributes().push_back(AttrOrVariable("ScopePtr", "scope"));
+        ValueTypeName() = "ParameterListPtr";
+        LocalVariables().push_back(AttrOrVariable("int", "index"));
+    }
+    virtual void Enter(ObjectStack& stack)
+    {
+        contextStack.push(context);
+        context = ContextPtr(new Context());
+        context->scope = *boost::static_pointer_cast< ValueObject<ScopePtr> >(stack.top());
+        stack.pop();
+    }
+    virtual void Leave(ObjectStack& stack, bool matched)
+    {
+        if (matched)
+        {
+            stack.push(ObjectPtr(new ValueObject<ParameterListPtr>(context->value)));
+        }
+        context = contextStack.top();
+        contextStack.pop();
+    }
+    virtual void Link()
+    {
+        ActionParserPtr a0ActionParser = GetAction("A0");
+        a0ActionParser->SetAction(ParsingActionPtr(new MemberParsingAction<ParameterListRuleParser>(this, &ParameterListRuleParser::A0Action)));
+        ActionParserPtr a1ActionParser = GetAction("A1");
+        a1ActionParser->SetAction(ParsingActionPtr(new MemberParsingAction<ParameterListRuleParser>(this, &ParameterListRuleParser::A1Action)));
+        NonTerminalParserPtr parameterNonTerminalParser = GetNonTerminal("Parameter");
+        parameterNonTerminalParser->SetPreCall(PreCallPtr(new MemberPreCall<ParameterListRuleParser>(this, &ParameterListRuleParser::PreParameter)));
+        parameterNonTerminalParser->SetPostCall(PostCallPtr(new MemberPostCall<ParameterListRuleParser>(this, &ParameterListRuleParser::PostParameter)));
+    }
+    void A0Action(const String& match, const String& content, const Position& position, const String& fileName, bool& pass)
+    {
+        context->value = ParameterListPtr(new ParameterList("parameterList", position, context->scope));
+        context->index = 0;
+    }
+    void A1Action(const String& match, const String& content, const Position& position, const String& fileName, bool& pass)
+    {
+        context->value->Append(context->fromParameter);
+        ++context->index;
+    }
+    void PreParameter(ObjectStack& stack)
+    {
+        stack.push(ObjectPtr(new ValueObject<ScopePtr>(context->scope)));
+        stack.push(ObjectPtr(new ValueObject<int>(context->index)));
+    }
+    void PostParameter(ObjectStack& stack, bool matched)
+    {
+        if (matched)
+        {
+            context->fromParameter = *boost::static_pointer_cast< ValueObject<ParameterPtr> >(stack.top());
+            stack.pop();
+        }
+    }
+private:
+    struct Context : Loki::SmallObject<>
+    {
+        Context(): scope(), value(), index(), fromParameter() {}
+        ScopePtr scope;
+        ParameterListPtr value;
+        int index;
+        ParameterPtr fromParameter;
+    };
+    typedef boost::shared_ptr<Context> ContextPtr;
+    std::stack<ContextPtr> contextStack;
+    ContextPtr context;
+};
+
+void ParameterParser::GetReferencedGrammars()
+{
+    ParsingDomainPtr parsingDomain = GetParsingDomain();
+    GrammarPtr grammar0 = parsingDomain->GetGrammar("Cm.Parser.Expression");
+    if (!grammar0)
+    {
+        grammar0 = Cm::Parser::Expression::Create(parsingDomain);
+    }
+    ReferencedGrammars().push_back(grammar0);
+    GrammarPtr grammar1 = parsingDomain->GetGrammar("Cm.Parser.Identifier");
+    if (!grammar1)
+    {
+        grammar1 = Cm::Parser::Identifier::Create(parsingDomain);
+    }
+    ReferencedGrammars().push_back(grammar1);
+}
+
+void ParameterParser::CreateRules()
+{
+    AddRule(RuleParserPtr(new ParameterRuleParser("Parameter", "Cm.Parser.ParameterParser.Parameter",
+        ParserPtr(new SequenceParser(
+            ParserPtr(new NonTerminalParser("TypeExpr", "TypeExpr", "TypeExpr", 1)),
+            ParserPtr(new AlternativeParser(
+                ParserPtr(new ActionParser("A0",
+                    ParserPtr(new NonTerminalParser("Identifier", "Identifier", "Identifier", 0)))),
+                ParserPtr(new ActionParser("A1",
+                    ParserPtr(new EmptyParser()))))))))));
+    AddRule(RuleParserPtr(new ParameterListRuleParser("ParameterList", "Cm.Parser.ParameterParser.ParameterList",
+        ParserPtr(new SequenceParser(
+            ParserPtr(new ActionParser("A0",
+                ParserPtr(new EmptyParser()))),
+            ParserPtr(new ListParser(
+                ParserPtr(new ActionParser("A1",
+                    ParserPtr(new NonTerminalParser("Parameter", "Parameter", "Parameter", 2)))),
+                ParserPtr(new CharParser(',')))))))));
+}
+
+} } // Cm.Parser