OSDN Git Service

test done
authorleo <leo@ae02f08e-27ec-0310-ae8c-8ba02fe2eafd>
Mon, 1 Jun 2009 03:15:13 +0000 (03:15 +0000)
committerleo <leo@ae02f08e-27ec-0310-ae8c-8ba02fe2eafd>
Mon, 1 Jun 2009 03:15:13 +0000 (03:15 +0000)
git-svn-id: http://www.xerial.org/svn/project/XerialJ/trunk/xerial-core@3341 ae02f08e-27ec-0310-ae8c-8ba02fe2eafd

src/main/java/org/xerial/silk/SilkPushParser.java
src/main/java/org/xerial/silk/impl/SilkFunction.java
src/main/java/org/xerial/silk/impl/SilkFunctionArg.java
src/main/java/org/xerial/silk/impl/SilkNodeParser.java

index c3c859a..2c4da3e 100644 (file)
@@ -34,21 +34,19 @@ import java.util.regex.Pattern;
 
 import org.antlr.runtime.ANTLRStringStream;
 import org.antlr.runtime.CommonTokenStream;
-import org.antlr.runtime.RecognitionException;
-import org.antlr.runtime.tree.Tree;
 import org.xerial.core.XerialError;
 import org.xerial.core.XerialErrorCode;
 import org.xerial.core.XerialException;
 import org.xerial.silk.impl.SilkDataLine;
+import org.xerial.silk.impl.SilkElement;
 import org.xerial.silk.impl.SilkFunction;
 import org.xerial.silk.impl.SilkLexer;
 import org.xerial.silk.impl.SilkNode;
+import org.xerial.silk.impl.SilkNodeParser;
 import org.xerial.silk.impl.SilkParser;
 import org.xerial.silk.impl.SilkPreamble;
-import org.xerial.silk.impl.SilkParser.silkNode_return;
 import org.xerial.util.StringUtil;
 import org.xerial.util.antlr.ANTLRUtil;
-import org.xerial.util.bean.impl.BeanUtilImpl;
 import org.xerial.util.log.Logger;
 
 /**
@@ -211,33 +209,33 @@ public class SilkPushParser
                 // 60,000 lines/sec (SilkPushParser after consuming the lexer input)
 
                 // 17000 lines/sec 
-                silkNode_return ret = parser.silkNode();
-                Tree t = (Tree) ret.getTree();
 
-                // 8500 -> 12000 lines/sec
-
-                switch (t.getType())
-                {
-                case SilkParser.Function:
+                try
                 {
-                    SilkFunction func = BeanUtilImpl.createBeanFromParseTree(SilkFunction.class, t,
-                            SilkParser.tokenNames);
-                    push(new SilkEvent(SilkEventType.FUNCTION, func));
-                    continue;
+                    SilkNodeParser nodeParser = new SilkNodeParser(tokenStream);
+                    SilkElement elem = nodeParser.parse();
+                    if (elem instanceof SilkNode)
+                        push(new SilkEvent(SilkEventType.NODE, (SilkNode) elem));
+                    else if (elem instanceof SilkFunction)
+                        push(new SilkEvent(SilkEventType.FUNCTION, (SilkFunction) elem));
+
                 }
-                case SilkParser.SilkNode:
+                catch (XerialException e)
                 {
-                    SilkNode node = BeanUtilImpl.populateBeanWithParseTree(new SilkNode(), t, SilkParser.tokenNames);
-                    //SilkNode node = Lens.loadANTLRParseTree(SilkNode.class, t, SilkParser.tokenNames);
-                    push(new SilkEvent(SilkEventType.NODE, node));
-                    continue;
-                }
-                default:
-                    throw new XerialError(XerialErrorCode.INVALID_INPUT, String.format(
-                            "line=%d: invalid data type: %s", lineCount, parser.getTokenNames()[t.getType()]));
+                    if (e.getErrorCode() == XerialErrorCode.PARSE_ERROR)
+                    {
+                        // only report warning message
+                        _logger.warn(String.format("parse error at line=%d: %s", lineCount, e));
+                    }
+                    else
+                        throw e;
                 }
 
-                // 17,000 lines/sec (SilkPushParser)
+                continue;
+
+                // 50,000 lines/sec (SilkPushParser when using recursive descent parser)
+
+                // 17,000 lines/sec (SilkPushParser when using ANTLR parser)
 
                 // 1500 lines/sec
             }
@@ -245,11 +243,11 @@ public class SilkPushParser
             // EOF
             push(EOFEvent);
         }
-        catch (RecognitionException e)
-        {
-            throw new XerialException(XerialErrorCode.INVALID_INPUT, String.format("parse error line=%d: %s",
-                    lineCount, e.getMessage()));
-        }
+        //        catch (RecognitionException e)
+        //        {
+        //            throw new XerialException(XerialErrorCode.INVALID_INPUT, String.format("parse error line=%d: %s",
+        //                    lineCount, e.getMessage()));
+        //        }
         catch (IOException e)
         {
             throw new XerialException(XerialErrorCode.IO_EXCEPTION, String.format("line=%d: %s", lineCount, e
index 6dcf136..9cc992c 100644 (file)
@@ -80,6 +80,11 @@ public class SilkFunction implements SilkElement, SilkValue
         argumentList.add(argument);
     }
 
+    public void addKeyAndValue(String key, String value)
+    {
+        argumentList.add(new SilkFunctionArg(key, value));
+    }
+
     public List<SilkFunctionArg> getArgumentList()
     {
         return argumentList;
index 8436499..b5f1c23 100644 (file)
@@ -43,7 +43,7 @@ public class SilkFunctionArg
     public SilkFunctionArg()
     {}
 
-    private SilkFunctionArg(String argName, String value)
+    public SilkFunctionArg(String argName, String value)
     {
         this.argName = argName;
         setValue(value);
index 4bffe5d..1c53fc7 100644 (file)
@@ -37,7 +37,7 @@ import org.xerial.util.Functor;
 import org.xerial.util.StringUtil;
 
 /**
- * 
+ * Recursive descent parser for {@link SilkNode} and {@link SilkFunction}
  * 
  * @author leo
  * 
@@ -56,7 +56,10 @@ public class SilkNodeParser
         switch (tokenStream.LA(1))
         {
         case NodeIndent:
-            return parseSilkNode();
+            if (tokenStream.LA(2) == At)
+                return parseFunction();
+            else
+                return parseSilkNode();
         case FunctionIndent:
             SilkFunction func = parseFunction();
             return func;
@@ -94,7 +97,9 @@ public class SilkNodeParser
         switch (tokenStream.LA(1))
         {
         case LParen:
+            consume();
             parseAttributeList(node);
+            testAndConsume(RParen);
             break;
         default:
         {
@@ -145,7 +150,7 @@ public class SilkNodeParser
         switch (nextToken)
         {
         case At:
-            SilkFunction func = parseFunctionInternal();
+            SilkFunction func = parseFunctionInternal(new SilkFunction());
             node.setFunction(func);
             break;
         case PlainOneLine:
@@ -164,15 +169,32 @@ public class SilkNodeParser
             break;
         }
         default:
-            throw unexpectedToken(tokenStream.LT(1));
+            throw unexpectedToken(tokenStream.LT(1), At, PlainOneLine, String, JSON);
         }
 
     }
 
-    private SilkFunction parseFunctionInternal()
+    private String parseNodeValue() throws XerialException
     {
-        // TODO
-        return null;
+        int nextToken = tokenStream.LA(1);
+
+        switch (nextToken)
+        {
+        case At:
+            // TODO
+            throw new XerialException(XerialErrorCode.PARSE_ERROR, "nested function is not yet supported");
+        case PlainOneLine:
+        case String:
+        case JSON:
+        {
+            Token t = getToken(1);
+            consume();
+            return t.getText();
+        }
+        default:
+            throw unexpectedToken(tokenStream.LT(1), At, PlainOneLine, String, JSON);
+        }
+
     }
 
     private void parsePlural(SilkNode node)
@@ -300,15 +322,90 @@ public class SilkNodeParser
         case PlainOneLine:
         case String:
             consume();
-            return t.getText();
+            return t.getText().trim();
         default:
             throw unexpectedToken(t, PlainOneLine, String);
         }
     }
 
-    private SilkFunction parseFunction()
+    private SilkFunction parseFunction() throws XerialException
     {
-        return null;
+        SilkFunction func = new SilkFunction();
+        switch (tokenStream.LA(1))
+        {
+        case NodeIndent:
+        {
+            Token t = getToken(1);
+            func.setNodeIndent(t.getText());
+            consume();
+            parseFunctionInternal(func);
+            return func;
+        }
+        case FunctionIndent:
+        {
+            Token t = getToken(1); // function indent
+            func.setNodeIndent(t.getText());
+            consume();
+
+            Token funcName = testAndConsume(PlainOneLine);
+            func.setName(funcName.getText().trim());
+
+            parseFunctionArgs(func);
+
+            return func;
+        }
+        default:
+
+            throw unexpectedToken(tokenStream.LT(1), NodeIndent, FunctionIndent);
+        }
+
+    }
+
+    private void parseFunctionArgs(SilkFunction func) throws XerialException
+    {
+        testAndConsume(LParen);
+        if (!nextTokenIs(RParen))
+        {
+            parseFunctionArg(func);
+            while (nextTokenIs(Comma))
+            {
+                consume();
+                parseFunctionArg(func);
+            }
+        }
+
+        testAndConsume(RParen);
+
+    }
+
+    private void parseFunctionArg(SilkFunction func) throws XerialException
+    {
+        if (nextTokenIs(String) || nextTokenIs(PlainOneLine))
+        {
+            if (tokenStream.LA(2) == Colon)
+            {
+                Token key = getToken(1);
+                consume();
+                consume();
+                String value = parseNodeValue();
+                func.addKeyAndValue(key.getText().trim(), value.trim());
+                return;
+            }
+        }
+
+        String value = parseNodeValue();
+        func.addArgument(value);
+    }
+
+    private SilkFunction parseFunctionInternal(SilkFunction func) throws XerialException
+    {
+        testAndConsume(At);
+        Token funcName = testAndConsume(PlainOneLine);
+        func.setName(funcName.getText().trim());
+
+        parseFunctionArgs(func);
+
+        return func;
     }
 
     private XerialException unexpectedToken(Token t) throws XerialException