OSDN Git Service

imported from subversion repository
[xerial/xerial-core.git] / src / main / java / org / xerial / silk / impl / SilkLexerState.java
1 /*--------------------------------------------------------------------------\r
2  *  Copyright 2009 Taro L. Saito\r
3  *\r
4  *  Licensed under the Apache License, Version 2.0 (the "License");\r
5  *  you may not use this file except in compliance with the License.\r
6  *  You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  *  Unless required by applicable law or agreed to in writing, software\r
11  *  distributed under the License is distributed on an "AS IS" BASIS,\r
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  *  See the License for the specific language governing permissions and\r
14  *  limitations under the License.\r
15  *--------------------------------------------------------------------------*/\r
16 //--------------------------------------\r
17 // XerialJ\r
18 //\r
19 // SilkLexerState.java\r
20 // Since: 2009/01/29 20:12:51\r
21 //\r
22 // $URL$\r
23 // $Author$\r
24 //--------------------------------------\r
25 package org.xerial.silk.impl;\r
26 \r
27 import org.xerial.util.ArrayDeque;\r
28 import org.xerial.util.Deque;\r
29 import org.xerial.util.graph.Automaton;\r
30 import org.xerial.util.graph.AutomatonCursor;\r
31 \r
32 /**\r
33  * Lexer state DFA\r
34  * \r
35  * <pre>\r
36  *  DEFAULT -(NodeStart)-&gt; KEY \r
37  *  KEY -&gt; (Colon) -&gt; OUT\r
38  *  OUT -&gt; (LParen) -&gt; IN\r
39  *  IN -&gt; (Colon) -&gt; IN\r
40  *   \r
41  *  ($current = ANY) -&gt; (Other) -&gt; ($current)\r
42  * </pre>\r
43  * \r
44  * @author leo\r
45  * \r
46  */\r
47 public class SilkLexerState\r
48 {\r
49     public static enum State {\r
50         INIT, OUT_KEY, OUT_VALUE, IN_VALUE, IN_KEY, IN_FUNC_NAME\r
51     };\r
52 \r
53     public static enum Symbol {\r
54         NodeStart, Colon, EnterParen, LeaveParen, LeaveValue, At\r
55     }\r
56 \r
57     private static final Automaton<State, Symbol> automaton = new Automaton<State, Symbol>();\r
58     private Deque<State> stateStack = new ArrayDeque<State>();\r
59 \r
60     //private State beforeJSONState = State.INIT;\r
61     //private int nestLevel = 0;\r
62     private final AutomatonCursor<State, Symbol> cursor;\r
63 \r
64     static\r
65     {\r
66         automaton.addTransition(State.INIT, Symbol.NodeStart, State.OUT_KEY);\r
67         automaton.addTransition(State.OUT_KEY, Symbol.EnterParen, State.IN_KEY);\r
68         automaton.addTransition(State.OUT_KEY, Symbol.Colon, State.OUT_VALUE);\r
69         //automaton.addTransition(State.OUT_VALUE, Symbol.EnterParen, State.IN_KEY);\r
70         automaton.addTransition(State.IN_KEY, Symbol.Colon, State.IN_VALUE);\r
71         automaton.addTransition(State.IN_VALUE, Symbol.LeaveValue, State.IN_KEY);\r
72         automaton.addTransition(State.IN_VALUE, Symbol.EnterParen, State.IN_KEY);\r
73 \r
74         automaton.addTransition(State.OUT_VALUE, Symbol.At, State.OUT_KEY);\r
75 \r
76         for (State each : State.values())\r
77             automaton.addStarTransition(each, each);\r
78     }\r
79 \r
80     public SilkLexerState()\r
81     {\r
82         cursor = automaton.cursor(State.INIT);\r
83     }\r
84 \r
85     public State transit(Symbol input)\r
86     {\r
87         State current = getCurrentState();\r
88         switch (input)\r
89         {\r
90         case At:\r
91             stateStack.addLast(current);\r
92             break;\r
93         case EnterParen:\r
94             if (current != State.OUT_VALUE)\r
95                 stateStack.addLast(current);\r
96             break;\r
97         case LeaveParen:\r
98             if (current != State.OUT_VALUE)\r
99             {\r
100                 if (!stateStack.isEmpty())\r
101                 {\r
102                     State prevState = stateStack.removeLast();\r
103                     cursor.reset(prevState);\r
104                     return prevState;\r
105                 }\r
106             }\r
107             break;\r
108         }\r
109 \r
110         return cursor.transit(input);\r
111     }\r
112 \r
113     public State getCurrentState()\r
114     {\r
115         return cursor.getState();\r
116     }\r
117 \r
118     public boolean isInKey()\r
119     {\r
120         State current = cursor.getState();\r
121         return current == State.IN_KEY || current == State.OUT_KEY;\r
122     }\r
123 \r
124     public boolean isValue()\r
125     {\r
126         State current = cursor.getState();\r
127         return current == State.IN_VALUE || current == State.OUT_VALUE;\r
128     }\r
129 \r
130     public boolean isInValue()\r
131     {\r
132         return getCurrentState() == State.IN_VALUE;\r
133     }\r
134 \r
135     public boolean isOutValue()\r
136     {\r
137         return getCurrentState() == State.OUT_VALUE;\r
138     }\r
139 \r
140     public void reset()\r
141     {\r
142         cursor.reset(State.INIT);\r
143         stateStack.clear();\r
144         //        beforeJSONState = State.INIT;\r
145         //        nestLevel = 0;\r
146     }\r
147 \r
148 }\r