Revisión | 670 (tree) |
---|---|
Tiempo | 2018-05-12 12:30:07 |
Autor | y-moriguchi |
supports tokens
@@ -38,6 +38,7 @@ | ||
38 | 38 | import net.morilib.automata.dfa.DFAs; |
39 | 39 | import net.morilib.automata.nfa.NFAObject; |
40 | 40 | import net.morilib.automata.nfa.RegexParseException; |
41 | +import net.morilib.nina.misc.Trie; | |
41 | 42 | import net.morilib.range.CharSets; |
42 | 43 | import net.morilib.range.Interval; |
43 | 44 | import net.morilib.range.IntervalsInt; |
@@ -678,6 +679,9 @@ | ||
678 | 679 | private String name; |
679 | 680 | private int nfaFlag; |
680 | 681 | |
682 | + // | |
683 | + private Trie trie = null; | |
684 | + | |
681 | 685 | public DBS createState(NinaEvent q) { |
682 | 686 | DBS s; |
683 | 687 |
@@ -1144,6 +1148,69 @@ | ||
1144 | 1148 | } |
1145 | 1149 | } |
1146 | 1150 | |
1151 | + private Trie getTrie(NinaEvent event) { | |
1152 | + String tokendef; | |
1153 | + if(trie != null) { | |
1154 | + return trie; | |
1155 | + } else if((tokendef = event.getOption("token")) == null) { | |
1156 | + return trie = new Trie(); | |
1157 | + } | |
1158 | + trie = new Trie(); | |
1159 | + for(String token : tokendef.split(" +")) { | |
1160 | + trie.add(token); | |
1161 | + } | |
1162 | + return trie; | |
1163 | + } | |
1164 | + | |
1165 | + private void _linkBackquoteLookahead(NinaEvent event, | |
1166 | + Trie.Node node, | |
1167 | + DBS state) { | |
1168 | + NinaLanguageOption langopt = event.getLanguageOption(); | |
1169 | + String look = langopt.getLookaheadMark() + langopt.getLookahead(); | |
1170 | + String commit = look + langopt.getLookaheadCommit(); | |
1171 | + if(node != null && node.countEdges() > 0) { | |
1172 | + for(int ch : node.getEdges()) { | |
1173 | + DBS stateNew = _linkc(event, state, ch, look); | |
1174 | + _linkBackquoteLookahead(event, node.get(ch), stateNew); | |
1175 | + } | |
1176 | + state.linkOthers(vertex, commit); | |
1177 | + } | |
1178 | + } | |
1179 | + | |
1180 | + private void _linkBackquote(NinaEvent event, | |
1181 | + CharSequence seq, | |
1182 | + DBS state, | |
1183 | + int flag) { | |
1184 | + int pos = 0, ch; | |
1185 | + Trie trie = getTrie(event); | |
1186 | + Trie.Node node = trie.getRoot(); | |
1187 | + DBS stateNew = state, stateGet; | |
1188 | + NinaLanguageOption langopt = event.getLanguageOption(); | |
1189 | + String look = langopt.getLookahead(); | |
1190 | + String commit = ""; | |
1191 | + | |
1192 | + for(; pos < seq.length() - 1; pos++) { | |
1193 | + ch = seq.charAt(pos); | |
1194 | + node = node == null ? null : node.get(ch); | |
1195 | + if(stateNew.edges == null) { | |
1196 | + stateNew = _linkc(event, stateNew, ch, look); | |
1197 | + } else if((stateGet = stateNew.edges.map(ch)) != null) { | |
1198 | + stateNew = stateGet; | |
1199 | + } else { | |
1200 | + stateNew = _linkc(event, stateNew, ch, look); | |
1201 | + } | |
1202 | + commit = look + langopt.getLookaheadCommit(); | |
1203 | + } | |
1204 | + ch = seq.charAt(pos); | |
1205 | + node = node == null ? null : node.get(ch); | |
1206 | + if(node != null && node.countEdges() > 0) { | |
1207 | + stateNew = _linkc(event, stateNew, ch, look); | |
1208 | + _linkBackquoteLookahead(event, node, stateNew); | |
1209 | + } else { | |
1210 | + _linkv(event, stateNew, vertex, ch, commit); | |
1211 | + } | |
1212 | + } | |
1213 | + | |
1147 | 1214 | private void _link1(NinaEvent q, DBS v) { |
1148 | 1215 | CharSequence s; |
1149 | 1216 | int k, b, l, f; |
@@ -1157,6 +1224,8 @@ | ||
1157 | 1224 | x = v; |
1158 | 1225 | if(b == '"') { |
1159 | 1226 | _linkdq(q, s, v, f); |
1227 | + } else if(b == '`') { | |
1228 | + _linkBackquote(q, s, v, f); | |
1160 | 1229 | } else { |
1161 | 1230 | for(k = 0; k < l; k++) { |
1162 | 1231 | x = _linkc(q, x, s.charAt(k), null); |
@@ -63,6 +63,7 @@ | ||
63 | 63 | PACK, MACHN, TYPE, TYP2, TYP3, |
64 | 64 | OPTN, OPTV, OPTQ, ALIAS, ALI_V, ALI_Q, |
65 | 65 | PLB_1, PLB_2, PDF_1, PDF_2, PDF_3, REQ1, REQ2, VTYP1, SETCM, |
66 | + TOK_1, | |
66 | 67 | SETCH, |
67 | 68 | COMNT, |
68 | 69 | DEF1, DEF2, DEF3, DEF4, DEFI1, DEFI2, |
@@ -415,7 +416,7 @@ | ||
415 | 416 | c = Nina.prendCharcode(q.getCharset(), s.charAt(0)); |
416 | 417 | action.setEdge(q, c); |
417 | 418 | } else { |
418 | - if(qc == '"') { | |
419 | + if(qc == '"' || qc == '`') { | |
419 | 420 | q.options.put("enableLookahead", "true"); |
420 | 421 | } |
421 | 422 | action.setEdgeCharSequence(q, s, qc, qf); |
@@ -903,6 +904,10 @@ | ||
903 | 904 | buf = new StringBuffer(); |
904 | 905 | q.east(); |
905 | 906 | etat = S.SETCM; |
907 | + } else if(buf.toString().equals("token")) { | |
908 | + buf = new StringBuffer(); | |
909 | + q.east(); | |
910 | + etat = S.TOK_1; | |
906 | 911 | } else if(buf.toString().equals("commentHeader")) { |
907 | 912 | buf = new StringBuffer(); |
908 | 913 | q.east(); |
@@ -1192,6 +1197,18 @@ | ||
1192 | 1197 | etat = S.COMNT; |
1193 | 1198 | } |
1194 | 1199 | break; |
1200 | + case TOK_1: | |
1201 | + if(q.get() == Quadro.EQ_TO_LEFT) { | |
1202 | + q.set(' '); q.east(); | |
1203 | + } else if(q.get() >= 0) { | |
1204 | + buf.appendCodePoint(q.get()); | |
1205 | + q.set(' '); q.east(); | |
1206 | + } else { | |
1207 | + q.options.put("token", q.getOptionNvl( | |
1208 | + "token", "") + " " + buf.toString()); | |
1209 | + etat = S.COMNT; | |
1210 | + } | |
1211 | + break; | |
1195 | 1212 | case SETCH: |
1196 | 1213 | if(q.get() >= 0) { |
1197 | 1214 | buf.appendCodePoint(q.get()); |
@@ -2029,7 +2046,8 @@ | ||
2029 | 2046 | q.set(Quadro.ENTRY); |
2030 | 2047 | etat = S.F2_N; |
2031 | 2048 | } |
2032 | - } else if(q.get() == '\'' || q.get() == '"') { | |
2049 | + } else if(q.get() == '\'' || q.get() == '"' || | |
2050 | + (q.get() == '`' && !q.isOptionDefined(ENABLE_REGEX_BY_BACKQUOTE))) { | |
2033 | 2051 | quote = q.get(); |
2034 | 2052 | q.set(Quadro.W2); |
2035 | 2053 | q.east(); |
@@ -2652,7 +2670,8 @@ | ||
2652 | 2670 | q.set(Quadro.ENTRY); |
2653 | 2671 | etat = S.F3_N; |
2654 | 2672 | } |
2655 | - } else if(q.get() == '\'' || q.get() == '"') { | |
2673 | + } else if(q.get() == '\'' || q.get() == '"' || | |
2674 | + (q.get() == '`' && !q.isOptionDefined(ENABLE_REGEX_BY_BACKQUOTE))) { | |
2656 | 2675 | quote = q.get(); |
2657 | 2676 | quoteFlag = -1; |
2658 | 2677 | q.set(Quadro.E2); |
@@ -0,0 +1,64 @@ | ||
1 | +/* | |
2 | + * Copyright 2013-2018 Yuichiro Moriguchi | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package net.morilib.nina.misc; | |
17 | + | |
18 | +import java.util.HashMap; | |
19 | +import java.util.Map; | |
20 | + | |
21 | +public class Trie { | |
22 | + | |
23 | + public static class Node { | |
24 | + // | |
25 | + private Map<Integer, Node> nodes = new HashMap<Integer, Node>(); | |
26 | + | |
27 | + public Node get(int ch) { | |
28 | + return nodes.get(ch); | |
29 | + } | |
30 | + | |
31 | + public boolean containsEdge(int ch) { | |
32 | + return nodes.containsKey(ch); | |
33 | + } | |
34 | + | |
35 | + public Iterable<Integer> getEdges() { | |
36 | + return nodes.keySet(); | |
37 | + } | |
38 | + | |
39 | + public int countEdges() { | |
40 | + return nodes.size(); | |
41 | + } | |
42 | + } | |
43 | + | |
44 | + // | |
45 | + private Node root = new Node(); | |
46 | + | |
47 | + public Node getRoot() { | |
48 | + return root; | |
49 | + } | |
50 | + | |
51 | + public void add(String string) { | |
52 | + Node node = root; | |
53 | + for(int i = 0; i < string.length(); i++) { | |
54 | + int ch = string.charAt(i); | |
55 | + if(node.containsEdge(ch)) { | |
56 | + node = node.get(ch); | |
57 | + } else { | |
58 | + Node nodeNew = new Node(); | |
59 | + node.nodes.put(ch, nodeNew); | |
60 | + node = nodeNew; | |
61 | + } | |
62 | + } | |
63 | + } | |
64 | +} |
@@ -1456,6 +1456,7 @@ | ||
1456 | 1456 | { |
1457 | 1457 | __Logprint("match failed: try lookahead: ", c); |
1458 | 1458 | LOOKAHEAD_RB(); |
1459 | + c = _Read(); | |
1459 | 1460 | b = en.Accepted(); |
1460 | 1461 | EOF |
1461 | 1462 | [ -n "$ENABLE_BACKTRACK" ] && cat << EOF |
@@ -1283,6 +1283,7 @@ | ||
1283 | 1283 | } else if(__lookaheadw_ptr >= 0) { |
1284 | 1284 | __logprint("match failed: try lookahead: ", c); |
1285 | 1285 | LOOKAHEAD_RB(); |
1286 | + c = _read(); | |
1286 | 1287 | b = en.accepted(); |
1287 | 1288 | EOF |
1288 | 1289 | [ -n "$ENABLE_BACKTRACK" ] && cat << EOF |
@@ -985,6 +985,7 @@ | ||
985 | 985 | } else if(this.__lookaheadw_ptr >= 0) { |
986 | 986 | this.__logprint("match failed: try lookahead: ", c); |
987 | 987 | this._f_LOOKAHEAD_RB(); |
988 | + c = this._read(rd); | |
988 | 989 | b = en.accepted(this); |
989 | 990 | EOF |
990 | 991 | [ -n "$ENABLE_BACKTRACK" ] && cat << EOF |