void Parser::parse() { int id_ctr = 0; scan->next(); while(scan->type != -1) { Symbol s; s.scope = std::string("scope"); s.symid = std::to_string(id_ctr); s.value = std::string(scan->val); s.kind = std::to_string(scan->type); s.data["key1"] = std::string("val1"); s.data["key2"] = std::string("val2"); symbols[s.symid] = s; scan->next(); id_ctr++; } for(std::pair<std::string,Symbol> pair : symbols) { std::cout << "scope " << pair.second.scope << std::endl; std::cout << "symid " << pair.second.symid << std::endl; std::cout << "value " << pair.second.value << std::endl; std::cout << "kind " << pair.second.kind << std::endl; for(std::pair<std::string,std::string> datum : pair.second.data) std::cout << datum.first << " : " << datum.second << std::endl; std::cout << std::endl; } }
/** * Initialize Table * ================================ * * The following reads in the PEG in the passed filename and converts the * grammar specification into a set of tokens for traversal when parsing other files * according to said grammar. */ void Parser::initializeTable(Scanner& input) { // These regexes are used to read in a custom PEG grammar. // Refer to /grammars/arithmetic.peg for a more thorough explanation // on the grammar. Note all other terms can be manipulated just // by reading in the remainder of a line or reading in words. Regex arrowOperator = Regex::fromPool("pparser-arrow", "\\->"); Regex markedWord = Regex::fromPool("pparser-marked-word", "\\A+'?"); // On any given line, the first two terminals should be the nonterminal // being defined and the arrow operator or we've encountered a comment. while(input.peek() != EOF) { if(input.peek() == PPARSER_COMMENT) { input.readLine(); } else { // First read in nonterminal and find start if possible std::string nonterminal = input.next(markedWord); if(nonterminal.back() == PPARSER_START) { nonterminal.pop_back(); if(start.empty()) { start = nonterminal; } else { throw InvalidGrammar("Multiple starting nonterminals", input.getCurrentState()); } } // Can now read in the arrow operator input.next(arrowOperator); // Rest of line is dedicated to definition table[nonterminal] = std::make_shared<Choices>(input); } } // Must have at least one starting nonterminal if(start.empty()) { throw InvalidGrammar("No starting nonterminal specified"); } }
// Created by Clayton Minicus on 3/2/16. // Copyright © 2016 Clayton Minicus. All rights reserved. // #include <stdio.h> #include "catch.hpp" #include "scanner.h" TEST_CASE("scanner scans correctly", "[scanner]") { Token t; // ------------------------------- Empty ----------------------------------- SECTION("scanner scans empty file correctly") { Scanner s(""); t = s.next(); REQUIRE(t.to_string() == "eof@(1:1)"); } // ----------------------------- Integers ---------------------------------- SECTION("scanner scans single digit integers correctly") { Scanner s("1"); t = s.next(); REQUIRE(t.to_string() == "integer<1>@(1:1)"); } SECTION("scanner scans multiple digit integers correctly") { Scanner s("12345"); t = s.next(); REQUIRE(t.to_string() == "integer<12345>@(1:1)"); }