PageRenderTime 25ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/sablecc-3.2/src/org/sablecc/sablecc/ResolveIds.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 672 lines | 549 code | 106 blank | 17 comment | 93 complexity | 91a72883df651ec93be51a470c5e68bd MD5 | raw file
  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2. * This file is part of SableCC. *
  3. * See the file "LICENSE" for copyright information and the *
  4. * terms and conditions for copying, distribution and *
  5. * modification of SableCC. *
  6. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  7. package org.sablecc.sablecc;
  8. import org.sablecc.sablecc.analysis.*;
  9. import org.sablecc.sablecc.node.*;
  10. import java.util.*;
  11. import java.io.*;
  12. public class ResolveIds extends DepthFirstAdapter
  13. {
  14. public final Map helpers = new TypedTreeMap(
  15. StringComparator.instance,
  16. StringCast.instance,
  17. NodeCast.instance);
  18. public final Map states = new TypedTreeMap(
  19. StringComparator.instance,
  20. StringCast.instance,
  21. NodeCast.instance);
  22. public final Map tokens = new TypedTreeMap(
  23. StringComparator.instance,
  24. StringCast.instance,
  25. NodeCast.instance);
  26. public final Map ignTokens = new TypedTreeMap(
  27. StringComparator.instance,
  28. StringCast.instance,
  29. NodeCast.instance);
  30. public final Map prods = new TypedTreeMap(
  31. StringComparator.instance,
  32. StringCast.instance,
  33. NodeCast.instance);
  34. public final Map alts = new TypedHashMap(
  35. StringCast.instance,
  36. NodeCast.instance);
  37. public final Map elems = new TypedHashMap(
  38. StringCast.instance,
  39. NodeCast.instance);
  40. public final Map names = new TypedHashMap(
  41. NodeCast.instance,
  42. StringCast.instance);
  43. public final Map errorNames = new TypedHashMap(
  44. NodeCast.instance,
  45. StringCast.instance);
  46. public final Map elemTypes = new TypedHashMap(
  47. NodeCast.instance,
  48. StringCast.instance);
  49. public final Map altsElemNameTypes = new TypedHashMap(
  50. StringCast.instance,
  51. StringCast.instance);
  52. // This map will serve for simpleTerm and simplelistTerm type within an altTransform
  53. // Inside an altTransform, one would look at this map to know its type. (P... or T...)
  54. public final Map altsElemTypes = new TypedHashMap(
  55. StringCast.instance,
  56. StringCast.instance);
  57. public final Map fixedTokens = new TypedHashMap(
  58. NodeCast.instance,
  59. BooleanCast.instance);
  60. public final List tokenList = new TypedLinkedList(StringCast.instance);
  61. public final LinkedList stateList = new TypedLinkedList(StringCast.instance);
  62. public File pkgDir;
  63. public String pkgName = "";
  64. private boolean processingStates;
  65. private boolean processingIgnTokens;
  66. String currentProd;
  67. String currentAlt;
  68. private int lastLine;
  69. private int lastPos;
  70. public ResolveIds(File currentDir)
  71. {
  72. pkgDir = currentDir;
  73. }
  74. public void inAGrammar(AGrammar node)
  75. {
  76. TPkgId[] temp = (TPkgId []) node.getPackage().toArray(new TPkgId[0]);
  77. if(temp.length > 0)
  78. {
  79. pkgName = temp[0].getText();
  80. pkgDir = new File(pkgDir, temp[0].getText());
  81. for(int i=1; i<temp.length; i++)
  82. {
  83. pkgName += "." + temp[i].getText();
  84. pkgDir = new File(pkgDir, temp[i].getText());
  85. }
  86. if(!pkgDir.exists())
  87. {
  88. if(!pkgDir.mkdirs())
  89. {
  90. throw new RuntimeException("Unable to create " + pkgDir.getAbsolutePath());
  91. }
  92. }
  93. }
  94. }
  95. public void caseAProd(AProd node)
  96. {
  97. //inAProd code.
  98. currentProd = name(node.getId().getText());
  99. String name = "P" + currentProd;
  100. if(prods.put(name, node) != null)
  101. {
  102. error(node.getId(), name);
  103. }
  104. names.put(node, name);
  105. //list of inAAlt code.
  106. Object []list_alt = (Object [])node.getAlts().toArray();
  107. for(int i = 0; i< list_alt.length; i++)
  108. {
  109. ((PAlt)list_alt[i]).apply(this);
  110. }
  111. }
  112. public void caseAIdBasic(AIdBasic node)
  113. {
  114. String name = node.getId().getText();
  115. // Only helpers can be used inside tokens definition
  116. if(helpers.get(name) == null)
  117. {
  118. error2(node.getId(), name);
  119. }
  120. }
  121. public void outAHelperDef(AHelperDef node)
  122. {
  123. String name = node.getId().getText();
  124. // If another helper is used within the current helper,
  125. // it should have been defined before the current one
  126. if(helpers.put(name, node) != null)
  127. {
  128. error(node.getId(), name);
  129. }
  130. names.put(node, name);
  131. }
  132. public void outATokenDef(ATokenDef node)
  133. {
  134. String name = "T" + name(node.getId().getText());
  135. String errorName = errorName(node.getId().getText());
  136. //We are making sure that this token is not yet defined.
  137. if(tokens.put(name, node) != null)
  138. {
  139. error(node.getId(), name);
  140. }
  141. names.put(node, name);
  142. errorNames.put(node, errorName);
  143. tokenList.add(name);
  144. if(node.getLookAhead() != null)
  145. {
  146. Token token = (Token) node.getSlash();
  147. throw new RuntimeException(
  148. "[" + token.getLine() + "," + token.getPos() + "] " +
  149. "Look ahead not yet supported.");
  150. }
  151. }
  152. public void inAStates(AStates node)
  153. {
  154. Object [] list_id = (Object[]) node.getListId().toArray();
  155. String name;
  156. for(int i=0; i<list_id.length; i++)
  157. {
  158. name = ((TId)list_id[i]).getText().toUpperCase();
  159. if(states.put(name, list_id[i]) != null)
  160. {
  161. error((TId)list_id[i], name);
  162. }
  163. names.put(list_id[i], name);
  164. stateList.add(name);
  165. }
  166. }
  167. public void inAIgnTokens(AIgnTokens node)
  168. {
  169. Object [] list_id = (Object[]) node.getListId().toArray();
  170. String name;
  171. for(int i=0; i<list_id.length; i++)
  172. {
  173. name = "T" + name(((TId)list_id[i]).getText());
  174. if(tokens.get(name) == null)
  175. {
  176. error2((TId)list_id[i], name);
  177. }
  178. if(ignTokens.put(name, list_id[i]) != null)
  179. {
  180. error((TId)list_id[i], name);
  181. }
  182. names.put(list_id[i], name);
  183. }
  184. }
  185. private Map stateMap;
  186. public void inAStateList(AStateList node)
  187. {
  188. stateMap = new TypedTreeMap(
  189. StringComparator.instance,
  190. StringCast.instance,
  191. NodeCast.instance);
  192. String name = node.getId().getText().toUpperCase();
  193. if(states.get(name) == null)
  194. {
  195. error2(node.getId(), name);
  196. }
  197. if(stateMap.put(name, node) != null)
  198. {
  199. error(node.getId(), name);
  200. }
  201. }
  202. public void outAStateList(AStateList node)
  203. {
  204. stateMap = null;
  205. }
  206. public void inAStateListTail(AStateListTail node)
  207. {
  208. String name = node.getId().getText().toUpperCase();
  209. if(states.get(name) == null)
  210. {
  211. error2(node.getId(), name);
  212. }
  213. if(stateMap.put(name, node) != null)
  214. {
  215. error(node.getId(), name);
  216. }
  217. }
  218. public void inATransition(ATransition node)
  219. {
  220. String name = node.getId().getText().toUpperCase();
  221. if(states.get(name) == null)
  222. {
  223. error2(node.getId(), name);
  224. }
  225. }
  226. public void caseAAlt(final AAlt alt)
  227. {
  228. if(alt.getAltName() != null)
  229. {
  230. currentAlt =
  231. "A" +
  232. name(alt.getAltName().getText()) +
  233. currentProd;
  234. if(alts.put(currentAlt, alt) != null)
  235. {
  236. error(alt.getAltName(), currentAlt);
  237. }
  238. names.put(alt, currentAlt);
  239. }
  240. else
  241. {
  242. currentAlt = "A" + currentProd;
  243. if(alts.put(currentAlt, alt) != null)
  244. {
  245. error(currentAlt);
  246. }
  247. names.put(alt, currentAlt);
  248. }
  249. AElem list_elem[] = (AElem[]) alt.getElems().toArray(new AElem[0]);
  250. for(int i=0; i<list_elem.length;i++)
  251. {
  252. list_elem[i].apply(this);
  253. }
  254. }
  255. public void defaultcase(Node node)
  256. {
  257. if(node instanceof Token)
  258. {
  259. Token t = (Token) node;
  260. lastLine = t.getLine();
  261. lastPos = t.getPos() + t.getText().length();
  262. }
  263. }
  264. public void caseAAst(AAst node)
  265. {}
  266. public void caseAElem(final AElem elem)
  267. {
  268. if(elem.getElemName() != null)
  269. {
  270. String name = currentAlt + "." +
  271. name(elem.getElemName().getText());
  272. if(elems.put(name, elem) != null)
  273. {
  274. error(elem.getElemName(), name);
  275. }
  276. if(elem.getElemName().getText().equals("class"))
  277. {
  278. error5(elem.getElemName());
  279. }
  280. names.put(elem, name(elem.getElemName().getText()) );
  281. }
  282. else
  283. {
  284. String name = currentAlt + "." +
  285. name(elem.getId().getText());
  286. if(elems.put(name, elem) != null)
  287. {
  288. error(elem.getId(), name);
  289. }
  290. if(elem.getId().getText().equals("class"))
  291. {
  292. error5(elem.getId());
  293. }
  294. names.put(elem, name(elem.getId().getText()));
  295. }
  296. }
  297. public void outAProductions(AProductions prod)
  298. {
  299. prod.apply(new DepthFirstAdapter()
  300. {
  301. public void caseAProd(AProd node)
  302. {
  303. //inAProd code.
  304. currentProd = name(node.getId().getText());
  305. //list of inAAlt code.
  306. Object []list_alt = (Object [])node.getAlts().toArray();
  307. for(int i = 0; i< list_alt.length; i++)
  308. {
  309. ((PAlt)list_alt[i]).apply(this);
  310. }
  311. }
  312. public void caseAAlt(final AAlt alt)
  313. {
  314. if(alt.getAltName() != null)
  315. {
  316. currentAlt = "A" + name(alt.getAltName().getText()) + currentProd;
  317. }
  318. else
  319. {
  320. currentAlt = "A" + currentProd;
  321. }
  322. AElem[] list_elem = (AElem[]) alt.getElems().toArray(new AElem[0]);
  323. for(int i=0; i<list_elem.length;i++)
  324. {
  325. list_elem[i].apply(this);
  326. }
  327. }
  328. public void caseAElem(AElem node)
  329. {
  330. String name = name(node.getId().getText());
  331. String nameOfElem;
  332. if(node.getElemName() != null)
  333. {
  334. nameOfElem = node.getElemName().getText();
  335. }
  336. else
  337. {
  338. nameOfElem = node.getId().getText();
  339. }
  340. if(node.getSpecifier() != null)
  341. {
  342. if(node.getSpecifier() instanceof ATokenSpecifier)
  343. {
  344. if(tokens.get("T" + name) == null)
  345. {
  346. error2(node.getId(), "T" + name);
  347. }
  348. if(ignTokens.get("T" + name) != null)
  349. {
  350. error3(node.getId(), "T" + name);
  351. }
  352. elemTypes.put(node, "T" + name);
  353. if(node.getElemName() != null)
  354. {
  355. altsElemNameTypes.put(currentAlt+"." + node.getElemName().getText(), "T" + name);
  356. }
  357. String type_name = name;
  358. if(node.getUnOp() instanceof AStarUnOp || node.getUnOp() instanceof AQMarkUnOp)
  359. {
  360. type_name += "?";
  361. }
  362. altsElemTypes.put(currentAlt+"." + nameOfElem, "T" + type_name);
  363. }
  364. else
  365. {
  366. if(prods.get("P" + name) == null)
  367. {
  368. error2(node.getId(), "P" + name);
  369. }
  370. elemTypes.put(node, "P" + name);
  371. if(node.getElemName() != null)
  372. {
  373. altsElemNameTypes.put(currentAlt+"." + node.getElemName().getText(), "P" + name);
  374. }
  375. //altsElemTypes.put(currentAlt+"." + nameOfElem, "P" + name);
  376. String type_name = name;
  377. if(node.getUnOp() instanceof AStarUnOp || node.getUnOp() instanceof AQMarkUnOp)
  378. {
  379. type_name += "?";
  380. }
  381. altsElemTypes.put(currentAlt+"." + nameOfElem, "P" + type_name);
  382. }
  383. }
  384. else
  385. {
  386. Object token = tokens.get("T" + name);
  387. Object ignToken = ignTokens.get("T" + name);
  388. Object production = prods.get("P" + name);
  389. if((token == null) && (production == null))
  390. {
  391. error2(node.getId(), "P" + name + " and T" + name);
  392. }
  393. if(token != null)
  394. {
  395. if(production != null)
  396. {
  397. error4(node.getId(), "P" + name + " and T" + name);
  398. }
  399. if(ignToken != null)
  400. {
  401. error3(node.getId(), "T" + name);
  402. }
  403. elemTypes.put(node, "T" + name);
  404. if(node.getElemName() != null)
  405. {
  406. altsElemNameTypes.put(currentAlt+"." + node.getElemName().getText(), "T" + name);
  407. }
  408. String type_name = name;
  409. if(node.getUnOp() instanceof AStarUnOp || node.getUnOp() instanceof AQMarkUnOp)
  410. {
  411. type_name += "?";
  412. }
  413. altsElemTypes.put(currentAlt+"." + nameOfElem, "T" + type_name);
  414. }
  415. else
  416. {
  417. elemTypes.put(node, "P" + name);
  418. if(node.getElemName() != null)
  419. {
  420. altsElemNameTypes.put(currentAlt+"." + node.getElemName().getText(), "P" + name);
  421. }
  422. String type_name = name;
  423. if(node.getUnOp() instanceof AStarUnOp || node.getUnOp() instanceof AQMarkUnOp)
  424. {
  425. type_name += "?";
  426. }
  427. altsElemTypes.put(currentAlt+"." + nameOfElem, "P" + type_name);
  428. }
  429. }
  430. }
  431. }
  432. );
  433. }
  434. public static String name(String s)
  435. {
  436. StringBuffer result = new StringBuffer();
  437. boolean upcase = true;
  438. int length = s.length();
  439. char c;
  440. for(int i = 0; i < length; i++)
  441. {
  442. c = s.charAt(i);
  443. switch(c)
  444. {
  445. case '_':
  446. upcase = true;
  447. break;
  448. case '$':
  449. result.append(c);
  450. upcase = true;
  451. break;
  452. default:
  453. if(upcase)
  454. {
  455. result.append(Character.toUpperCase(c));
  456. upcase = false;
  457. }
  458. else
  459. {
  460. result.append(c);
  461. }
  462. break;
  463. }
  464. }
  465. return result.toString();
  466. }
  467. public static String errorName(String s)
  468. {
  469. StringBuffer result = new StringBuffer();
  470. int length = s.length();
  471. char c;
  472. for(int i = 0; i < length; i++)
  473. {
  474. c = s.charAt(i);
  475. switch(c)
  476. {
  477. case '_':
  478. {
  479. result.append(' ');
  480. }
  481. break;
  482. default:
  483. {
  484. result.append(c);
  485. }
  486. break;
  487. }
  488. }
  489. return result.toString();
  490. }
  491. public void reinit()
  492. {
  493. names.clear();
  494. elemTypes.clear();
  495. }
  496. private static void error(Token token, String name)
  497. {
  498. throw new RuntimeException(
  499. "[" + token.getLine() + "," + token.getPos() + "] " +
  500. "Redefinition of " + name + ".");
  501. }
  502. private void error(String name)
  503. {
  504. throw new RuntimeException(
  505. "[" + lastLine + "," + lastPos + "] " +
  506. "Redefinition of " + name + ".");
  507. }
  508. private static void error2(Token token, String name)
  509. {
  510. throw new RuntimeException(
  511. "[" + token.getLine() + "," + token.getPos() + "] " +
  512. name + " undefined.");
  513. }
  514. private static void error3(Token token, String name)
  515. {
  516. throw new RuntimeException(
  517. "[" + token.getLine() + "," + token.getPos() + "] " +
  518. name + " is ignored.");
  519. }
  520. private static void error4(Token token, String name)
  521. {
  522. throw new RuntimeException(
  523. "[" + token.getLine() + "," + token.getPos() + "] " +
  524. "ambiguous " + name + ".");
  525. }
  526. private static void error5(Token token)
  527. {
  528. throw new RuntimeException(
  529. "[" + token.getLine() + "," + token.getPos() + "] " +
  530. "class is an invalid element name.");
  531. }
  532. public String toString()
  533. {
  534. StringBuffer s = new StringBuffer();
  535. String nl = System.getProperty("line.separator");
  536. s.append("Helpers:");
  537. s.append(nl);
  538. s.append(helpers);
  539. s.append(nl);
  540. s.append("States:");
  541. s.append(nl);
  542. s.append(states);
  543. s.append(nl);
  544. s.append("Tokens:");
  545. s.append(nl);
  546. s.append(tokens);
  547. s.append(nl);
  548. s.append("Ignored Tokens:");
  549. s.append(nl);
  550. s.append(ignTokens);
  551. s.append(nl);
  552. s.append("Productions:");
  553. s.append(nl);
  554. s.append(prods);
  555. s.append(nl);
  556. s.append("Alternatives:");
  557. s.append(nl);
  558. s.append(alts);
  559. s.append(nl);
  560. s.append("Elements:");
  561. s.append(nl);
  562. s.append(elems);
  563. s.append(nl);
  564. return s.toString();
  565. }
  566. }