parser.rs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. use std::{iter::Peekable, str::Chars};
  2. use indexmap::IndexMap;
  3. use itertools::Itertools;
  4. use super::{
  5. ast::{
  6. Constant, Constants, Statement, StatementType, Statements, UnparsedConstants,
  7. UnparsedWitnesses, Variable, Witness, Witnesses,
  8. },
  9. error::ErrorEmitter,
  10. lexer::{Token, TokenType},
  11. opcode::Opcode,
  12. types::Type,
  13. };
  14. pub struct Parser {
  15. tokens: Vec<Token>,
  16. error: ErrorEmitter,
  17. }
  18. impl Parser {
  19. pub fn new(filename: &str, source: Chars, tokens: Vec<Token>) -> Self {
  20. // For nice error reporting, we'll load everything into a string
  21. // vector so we have references to lines.
  22. let lines: Vec<String> = source.as_str().lines().map(|x| x.to_string()).collect();
  23. let error = ErrorEmitter::new("Parser", filename, lines.clone());
  24. Parser { tokens, error }
  25. }
  26. pub fn parse(self) -> (Constants, Witnesses, Statements) {
  27. // We use these to keep state when iterating
  28. let mut declaring_constant = false;
  29. let mut declaring_contract = false;
  30. let mut declaring_circuit = false;
  31. let mut constant_tokens = vec![];
  32. let mut contract_tokens = vec![];
  33. let mut circuit_tokens = vec![];
  34. // Single statement in the circuit
  35. let mut circuit_statement = vec![];
  36. // All the circuit statements
  37. let mut circuit_statements = vec![];
  38. let mut ast = IndexMap::new();
  39. let mut namespace = String::new();
  40. let mut ast_inner = IndexMap::new();
  41. let mut namespace_found = false; // Nasty
  42. let mut iter = self.tokens.iter();
  43. while let Some(t) = iter.next() {
  44. // Start by declaring a section
  45. if !declaring_constant && !declaring_contract && !declaring_circuit {
  46. if t.token_type != TokenType::Symbol {
  47. // TODO: Revisit
  48. // TODO: Visit this again when we are allowing imports
  49. unimplemented!();
  50. }
  51. // The sections we must be declaring in our source code
  52. match t.token.as_str() {
  53. "constant" => {
  54. declaring_constant = true;
  55. // Eat all the tokens within the `constant` section
  56. for inner in iter.by_ref() {
  57. constant_tokens.push(inner.clone());
  58. if inner.token_type == TokenType::RightBrace {
  59. break
  60. }
  61. }
  62. }
  63. "contract" => {
  64. declaring_contract = true;
  65. // Eat all the tokens within the `contract` section
  66. for inner in iter.by_ref() {
  67. contract_tokens.push(inner.clone());
  68. if inner.token_type == TokenType::RightBrace {
  69. break
  70. }
  71. }
  72. }
  73. "circuit" => {
  74. declaring_circuit = true;
  75. // Eat all the tokens within the `circuit` section
  76. // TODO: Revisit when we support if/else and loops
  77. for inner in iter.by_ref() {
  78. circuit_tokens.push(inner.clone());
  79. if inner.token_type == TokenType::RightBrace {
  80. break
  81. }
  82. }
  83. }
  84. x => {
  85. self.error.emit(format!("Unknown `{}` proof section", x), t.line, t.column)
  86. }
  87. }
  88. }
  89. // We shouldn't be reaching these states
  90. if declaring_constant && (declaring_contract || declaring_circuit) {
  91. unreachable!()
  92. }
  93. if declaring_contract && (declaring_constant || declaring_circuit) {
  94. unreachable!()
  95. }
  96. if declaring_circuit && (declaring_constant || declaring_contract) {
  97. unreachable!()
  98. }
  99. // Now go through the token vectors and work it through
  100. if declaring_constant {
  101. self.check_section_structure("constant", constant_tokens.clone());
  102. // TODO: Do we need this?
  103. if namespace_found && namespace != constant_tokens[0].token {
  104. self.error.emit(
  105. format!(
  106. "Found `{}` namespace. Expected `{}`.",
  107. constant_tokens[0].token, namespace
  108. ),
  109. constant_tokens[0].line,
  110. constant_tokens[0].column,
  111. );
  112. } else {
  113. namespace = constant_tokens[0].token.clone();
  114. namespace_found = true;
  115. }
  116. let constants_cloned = constant_tokens.clone();
  117. let mut constants_map = IndexMap::new();
  118. // This is everything between the braces: { .. }
  119. let mut constants_inner = constants_cloned[2..constant_tokens.len() - 1].iter();
  120. while let Some((typ, name, comma)) = constants_inner.next_tuple() {
  121. if comma.token_type != TokenType::Comma {
  122. self.error.emit(
  123. "Separator is not a comma".to_string(),
  124. comma.line,
  125. comma.column,
  126. );
  127. }
  128. if constants_map.contains_key(name.token.as_str()) {
  129. self.error.emit(
  130. format!(
  131. "Section `constant` already contains the token `{}`.",
  132. &name.token
  133. ),
  134. name.line,
  135. name.column,
  136. );
  137. }
  138. constants_map.insert(name.token.clone(), (name.clone(), typ.clone()));
  139. }
  140. ast_inner.insert("constant".to_string(), constants_map);
  141. declaring_constant = false;
  142. }
  143. if declaring_contract {
  144. self.check_section_structure("contract", contract_tokens.clone());
  145. // TODO: Do we need this?
  146. if namespace_found && namespace != contract_tokens[0].token {
  147. self.error.emit(
  148. format!(
  149. "Found `{}` namespace. Expected `{}`.",
  150. contract_tokens[0].token, namespace
  151. ),
  152. contract_tokens[0].line,
  153. contract_tokens[0].column,
  154. );
  155. } else {
  156. namespace = contract_tokens[0].token.clone();
  157. namespace_found = true;
  158. }
  159. let contract_cloned = contract_tokens.clone();
  160. let mut contract_map = IndexMap::new();
  161. // This is everything between the braces: { .. }
  162. let mut contract_inner = contract_cloned[2..contract_tokens.len() - 1].iter();
  163. while let Some((typ, name, comma)) = contract_inner.next_tuple() {
  164. if comma.token_type != TokenType::Comma {
  165. self.error.emit(
  166. "Separator is not a comma".to_string(),
  167. comma.line,
  168. comma.column,
  169. );
  170. }
  171. if contract_map.contains_key(name.token.as_str()) {
  172. self.error.emit(
  173. format!(
  174. "Section `contract` already contains the token `{}`.",
  175. &name.token
  176. ),
  177. name.line,
  178. name.column,
  179. );
  180. }
  181. contract_map.insert(name.token.clone(), (name.clone(), typ.clone()));
  182. }
  183. ast_inner.insert("contract".to_string(), contract_map);
  184. declaring_contract = false;
  185. }
  186. if declaring_circuit {
  187. self.check_section_structure("circuit", contract_tokens.clone());
  188. if circuit_tokens[circuit_tokens.len() - 2].token_type != TokenType::Semicolon {
  189. self.error.emit(
  190. "Circuit section does not end with a semicolon. Would never finish parsing.".to_string(),
  191. circuit_tokens[circuit_tokens.len()-2].line,
  192. circuit_tokens[circuit_tokens.len()-2].column
  193. );
  194. }
  195. // TODO: Do we need this?
  196. if namespace_found && namespace != circuit_tokens[0].token {
  197. self.error.emit(
  198. format!(
  199. "Found `{}` namespace. Expected `{}`.",
  200. circuit_tokens[0].token, namespace
  201. ),
  202. circuit_tokens[0].line,
  203. circuit_tokens[0].column,
  204. );
  205. } else {
  206. namespace = circuit_tokens[0].token.clone();
  207. namespace_found = true;
  208. }
  209. for i in circuit_tokens.clone()[2..circuit_tokens.len() - 1].iter() {
  210. if i.token_type == TokenType::Semicolon {
  211. circuit_statements.push(circuit_statement.clone());
  212. // println!("{:?}", circuit_statement);
  213. circuit_statement = vec![];
  214. continue
  215. }
  216. circuit_statement.push(i.clone());
  217. }
  218. declaring_circuit = false;
  219. }
  220. }
  221. ast.insert(namespace.clone(), ast_inner);
  222. // TODO: Verify there are both constant/contract sections
  223. // TODO: Verify there is a circuit section
  224. // TODO: Check that there are no duplicate names in constants, contract
  225. // and circuit assignments
  226. // Clean up the `constant` section
  227. let c = ast.get(&namespace).unwrap().get("constant").unwrap();
  228. let constants = self.parse_ast_constants(c);
  229. // Clean up the `contract` section
  230. let c = ast.get(&namespace).unwrap().get("contract").unwrap();
  231. let witnesses = self.parse_ast_contract(c);
  232. // Clean up the `circuit` section
  233. let stmt = self.parse_ast_circuit(circuit_statements);
  234. (constants, witnesses, stmt)
  235. }
  236. fn check_section_structure(&self, section: &str, tokens: Vec<Token>) {
  237. if tokens[0].token_type != TokenType::String {
  238. self.error.emit(
  239. format!("{} section declaration must start with a naming string.", section),
  240. tokens[0].line,
  241. tokens[0].column,
  242. );
  243. }
  244. if tokens[1].token_type != TokenType::LeftBrace {
  245. self.error.emit(
  246. format!(
  247. "{} section opening is not correct. Must be opened with a left brace `{{`",
  248. section
  249. ),
  250. tokens[0].line,
  251. tokens[0].column,
  252. );
  253. }
  254. if tokens[tokens.len() - 1].token_type != TokenType::RightBrace {
  255. self.error.emit(
  256. format!(
  257. "{} section closing is not correct. Must be closed with a right brace `}}`",
  258. section
  259. ),
  260. tokens[0].line,
  261. tokens[0].column,
  262. );
  263. }
  264. if (section == "constant" || section == "contract") &&
  265. tokens[2..tokens.len() - 1].len() % 3 != 0
  266. {
  267. self.error.emit(
  268. format!(
  269. "Invalid number of elements in `{}` section. Must be pairs of `type:name` separated with a comma `,`",
  270. section
  271. ),
  272. tokens[0].line,
  273. tokens[0].column,
  274. );
  275. }
  276. }
  277. fn parse_ast_constants(&self, ast: &UnparsedConstants) -> Constants {
  278. let mut ret = vec![];
  279. for (k, v) in ast {
  280. if &v.0.token != k {
  281. self.error.emit(
  282. format!("Constant name `{}` doesn't match token `{}`.", v.0.token, k),
  283. v.0.line,
  284. v.0.column,
  285. );
  286. }
  287. if v.0.token_type != TokenType::Symbol {
  288. self.error.emit(
  289. format!("Constant name `{}` is not a symbol.", v.0.token),
  290. v.0.line,
  291. v.0.column,
  292. );
  293. }
  294. if v.1.token_type != TokenType::Symbol {
  295. self.error.emit(
  296. format!("Constant type `{}` is not a symbol.", v.1.token),
  297. v.1.line,
  298. v.1.column,
  299. );
  300. }
  301. match v.1.token.as_str() {
  302. "EcFixedPoint" => {
  303. ret.push(Constant {
  304. name: k.to_string(),
  305. typ: Type::EcFixedPoint,
  306. line: v.0.line,
  307. column: v.0.column,
  308. });
  309. }
  310. "EcFixedPointShort" => {
  311. ret.push(Constant {
  312. name: k.to_string(),
  313. typ: Type::EcFixedPointShort,
  314. line: v.0.line,
  315. column: v.0.column,
  316. });
  317. }
  318. "EcFixedPointBase" => {
  319. ret.push(Constant {
  320. name: k.to_string(),
  321. typ: Type::EcFixedPointBase,
  322. line: v.0.line,
  323. column: v.0.column,
  324. });
  325. }
  326. x => {
  327. self.error.emit(
  328. format!("`{}` is an illegal constant type", x),
  329. v.1.line,
  330. v.1.column,
  331. );
  332. }
  333. }
  334. }
  335. ret
  336. }
  337. fn parse_ast_contract(&self, ast: &UnparsedWitnesses) -> Witnesses {
  338. let mut ret = vec![];
  339. for (k, v) in ast {
  340. if &v.0.token != k {
  341. self.error.emit(
  342. format!("Witness name `{}` doesn't match token `{}`.", v.0.token, k),
  343. v.0.line,
  344. v.0.column,
  345. );
  346. }
  347. if v.0.token_type != TokenType::Symbol {
  348. self.error.emit(
  349. format!("Witness name `{}` is not a symbol.", v.0.token),
  350. v.0.line,
  351. v.0.column,
  352. );
  353. }
  354. if v.1.token_type != TokenType::Symbol {
  355. self.error.emit(
  356. format!("Witness type `{}` is not a symbol.", v.1.token),
  357. v.1.line,
  358. v.1.column,
  359. );
  360. }
  361. match v.1.token.as_str() {
  362. "Base" => {
  363. ret.push(Witness {
  364. name: k.to_string(),
  365. typ: Type::Base,
  366. line: v.0.line,
  367. column: v.0.column,
  368. });
  369. }
  370. "Scalar" => {
  371. ret.push(Witness {
  372. name: k.to_string(),
  373. typ: Type::Scalar,
  374. line: v.0.line,
  375. column: v.0.column,
  376. });
  377. }
  378. "MerklePath" => {
  379. ret.push(Witness {
  380. name: k.to_string(),
  381. typ: Type::MerklePath,
  382. line: v.0.line,
  383. column: v.0.column,
  384. });
  385. }
  386. "Uint32" => {
  387. ret.push(Witness {
  388. name: k.to_string(),
  389. typ: Type::Uint32,
  390. line: v.0.line,
  391. column: v.0.column,
  392. });
  393. }
  394. "Uint64" => {
  395. ret.push(Witness {
  396. name: k.to_string(),
  397. typ: Type::Uint64,
  398. line: v.0.line,
  399. column: v.0.column,
  400. });
  401. }
  402. x => {
  403. self.error.emit(
  404. format!("`{}` is an illegal witness type", x),
  405. v.1.line,
  406. v.1.column,
  407. );
  408. }
  409. }
  410. }
  411. ret
  412. }
  413. fn parse_ast_circuit(&self, statements: Vec<Vec<Token>>) -> Vec<Statement> {
  414. let mut stmts = vec![];
  415. for statement in statements {
  416. let (mut left_paren, mut right_paren) = (0, 0);
  417. for i in &statement {
  418. match i.token.as_str() {
  419. "(" => left_paren += 1,
  420. ")" => right_paren += 1,
  421. _ => {}
  422. }
  423. }
  424. if left_paren != right_paren {
  425. self.error.emit(
  426. "Incorrect number of left and right parenthesis for statement.".to_string(),
  427. statement[0].line,
  428. statement[0].column,
  429. );
  430. }
  431. // C = poseidon_hash(pub_x, pub_y, value, token, serial, coin_blind)
  432. // | | | |
  433. // V V V V
  434. // variable opcode args
  435. // assign
  436. // constrain_instance(C)
  437. // | |
  438. // V V
  439. // opcode args
  440. let mut iter = statement.iter().peekable();
  441. let mut stmt = Statement::default();
  442. let mut parsing = false;
  443. while let Some(token) = iter.next() {
  444. if !parsing {
  445. if let Some(next_token) = iter.peek() {
  446. if next_token.token_type == TokenType::Assign {
  447. stmt.typ = StatementType::Assignment;
  448. stmt.variable = Some(Variable {
  449. name: token.token.clone(),
  450. typ: Type::Dummy,
  451. line: token.line,
  452. column: token.column,
  453. });
  454. // Skip over the `=` token.
  455. iter.next();
  456. parsing = true;
  457. continue
  458. }
  459. if next_token.token_type == TokenType::LeftParen {
  460. stmt.typ = StatementType::Call;
  461. stmt.variable = None;
  462. parsing = true;
  463. }
  464. if !parsing {
  465. self.error.emit(
  466. format!("Illegal token `{}`", next_token.token),
  467. next_token.line,
  468. next_token.column,
  469. );
  470. }
  471. }
  472. }
  473. // This matching could be moved over into the semantic analyzer.
  474. // We could just parse any kind of symbol here, and then do lookup
  475. // from the analyzer, to see if the calls actually exist and are
  476. // supported.
  477. // But for now, we'll just leave it here and expand later.
  478. match token.token.as_str() {
  479. "poseidon_hash" => {
  480. stmt.args = self.parse_function_call(token, &mut iter);
  481. stmt.opcode = Opcode::PoseidonHash;
  482. stmt.line = token.line;
  483. stmts.push(stmt.clone());
  484. parsing = false;
  485. continue
  486. }
  487. "constrain_instance" => {
  488. stmt.args = self.parse_function_call(token, &mut iter);
  489. stmt.opcode = Opcode::ConstrainInstance;
  490. stmt.line = token.line;
  491. stmts.push(stmt.clone());
  492. parsing = false;
  493. continue
  494. }
  495. "calculate_merkle_root" => {
  496. stmt.args = self.parse_function_call(token, &mut iter);
  497. stmt.opcode = Opcode::CalculateMerkleRoot;
  498. stmt.line = token.line;
  499. stmts.push(stmt.clone());
  500. parsing = false;
  501. continue
  502. }
  503. "ec_mul_short" => {
  504. stmt.args = self.parse_function_call(token, &mut iter);
  505. stmt.opcode = Opcode::EcMulShort;
  506. stmt.line = token.line;
  507. stmts.push(stmt.clone());
  508. parsing = false;
  509. continue
  510. }
  511. "ec_mul_base" => {
  512. stmt.args = self.parse_function_call(token, &mut iter);
  513. stmt.opcode = Opcode::EcMulBase;
  514. stmt.line = token.line;
  515. stmts.push(stmt.clone());
  516. parsing = false;
  517. continue
  518. }
  519. "ec_mul" => {
  520. stmt.args = self.parse_function_call(token, &mut iter);
  521. stmt.opcode = Opcode::EcMul;
  522. stmt.line = token.line;
  523. stmts.push(stmt.clone());
  524. parsing = false;
  525. continue
  526. }
  527. "ec_get_x" => {
  528. stmt.args = self.parse_function_call(token, &mut iter);
  529. stmt.opcode = Opcode::EcGetX;
  530. stmt.line = token.line;
  531. stmts.push(stmt.clone());
  532. parsing = false;
  533. continue
  534. }
  535. "ec_get_y" => {
  536. stmt.args = self.parse_function_call(token, &mut iter);
  537. stmt.opcode = Opcode::EcGetY;
  538. stmt.line = token.line;
  539. stmts.push(stmt.clone());
  540. parsing = false;
  541. continue
  542. }
  543. "ec_add" => {
  544. stmt.args = self.parse_function_call(token, &mut iter);
  545. stmt.opcode = Opcode::EcAdd;
  546. stmt.line = token.line;
  547. stmts.push(stmt.clone());
  548. parsing = false;
  549. continue
  550. }
  551. "base_add" => {
  552. stmt.args = self.parse_function_call(token, &mut iter);
  553. stmt.opcode = Opcode::BaseAdd;
  554. stmt.line = token.line;
  555. stmts.push(stmt.clone());
  556. parsing = false;
  557. continue
  558. }
  559. "base_mul" => {
  560. stmt.args = self.parse_function_call(token, &mut iter);
  561. stmt.opcode = Opcode::BaseMul;
  562. stmt.line = token.line;
  563. stmts.push(stmt.clone());
  564. parsing = false;
  565. continue
  566. }
  567. x => {
  568. self.error.emit(
  569. format!("Unimplemented function call `{}`", x),
  570. token.line,
  571. token.column,
  572. );
  573. }
  574. }
  575. }
  576. }
  577. // println!("{:#?}", stmts);
  578. stmts
  579. }
  580. fn parse_function_call(
  581. &self,
  582. token: &Token,
  583. iter: &mut Peekable<std::slice::Iter<'_, Token>>,
  584. ) -> Vec<Variable> {
  585. if let Some(next_token) = iter.peek() {
  586. if next_token.token_type != TokenType::LeftParen {
  587. self.error.emit(
  588. "Invalid function call opening. Must start with a `(`".to_string(),
  589. next_token.line,
  590. next_token.column,
  591. );
  592. }
  593. // Skip the opening parenthesis
  594. iter.next();
  595. } else {
  596. self.error.emit("Premature ending of statement".to_string(), token.line, token.column);
  597. }
  598. // Eat up function arguments
  599. let mut args = vec![];
  600. while let Some((arg, sep)) = iter.next_tuple() {
  601. args.push(Variable {
  602. name: arg.token.clone(),
  603. typ: Type::Dummy,
  604. line: arg.line,
  605. column: arg.column,
  606. });
  607. if sep.token_type == TokenType::RightParen {
  608. // Reached end of args
  609. break
  610. }
  611. if sep.token_type != TokenType::Comma {
  612. self.error.emit(
  613. "Argument separator is not a comma (`,`)".to_string(),
  614. sep.line,
  615. sep.column,
  616. );
  617. }
  618. }
  619. args
  620. }
  621. }