Skip to content

Instantly share code, notes, and snippets.

@jensb1
Created March 19, 2021 09:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jensb1/04b1a6d425bd18a29db2a319d141daff to your computer and use it in GitHub Desktop.
Save jensb1/04b1a6d425bd18a29db2a319d141daff to your computer and use it in GitHub Desktop.
LISP Parser in PEGTL
#if !defined( __cpp_exceptions )
#include <iostream>
int main()
{
std::cerr << "Exception support required, example unavailable." << std::endl;
return 1;
}
#else
#include <iomanip>
#include <iostream>
#include <tao/pegtl.hpp>
#include <tao/pegtl/contrib/parse_tree.hpp>
#include <tao/pegtl/contrib/analyze.hpp>
#include <tao/pegtl/contrib/trace.hpp>
using namespace tao;
namespace grammar
{
// https://github.com/clojure/clojure-clr/blob/eac97b74c73e476f78ed59871b0d6f62b7a27406/Clojure/Clojure/CljCompiler/Compiler.cs
using namespace tao::pegtl;
struct number : plus< digit > {};
template< typename Key >
struct key : seq< Key, not_at< identifier_other > > {}; //keyword cannot be folloed by identifier
// keyword definitions
struct str_def : TAO_PEGTL_STRING("def") {};
struct str_defn : TAO_PEGTL_STRING("defn") {};
struct key_def : key<str_def> {};
struct key_defn : key<str_defn> {};
struct keywords : sor<key_def, key_defn> {};
struct name : seq< not_at< keywords >, identifier > {};
struct single : one< 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '"', '\'', '0', '\n' > {};
struct spaces : seq< one< 'z' >, star< space > > {};
struct hexbyte : if_must< one< 'x' >, xdigit, xdigit > {};
struct decbyte : if_must< digit, rep_opt< 2, digit > > {};
struct unichar : if_must< one< 'u' >, one< '{' >, plus< xdigit >, one< '}' > > {};
struct escaped : if_must< one< '\\' >, sor< hexbyte, decbyte, unichar, single, spaces > > {};
struct regular : not_one< '\r', '\n' > {};
struct character : sor< escaped, regular > {};
struct atom : sor<name,number> {};
struct sexpr;
//struct list : seq<opt<keywords>, sexpr, name> {};
struct list : sor<atom, space, sexpr> {};
struct func_name : name {};
struct sexpr_call : seq< one<'('>, until<func_name, space>, until<one<')'>, list>> {};
struct sexpr_kw : seq< one<'('>, until<keywords, space>, until<one<')'>, list>> {};
struct sexpr : sor<sexpr_kw, sexpr_call> {};
struct main : until< eof, must< sor<sexpr, space, atom>> > {};
//struct main : until< eof, must< sexpr> > {}; //TODO
// clang-format on
template< typename Rule >
using selector = pegtl::parse_tree::selector< Rule,
pegtl::parse_tree::store_content::on<
//sexpr, keywords, name,
//list,
func_name,
keywords,
name,
sexpr,
number
>
>;
template< typename Rule >
struct action
{};
} // namespace sexpr
typedef pegtl::parse_tree::node pnode;
void print_cell(const std::unique_ptr<pnode> &n, int depth = 0) {
for (const auto& c : n->children) {
if(c->has_content()) {
for(int j=0; j<depth; j++) std::cout << " ";
std::cout << c->type << ": " << c->string() << '\n';
}
print_cell(c, depth+1);
}
}
int main( int argc, char** argv ) // NOLINT(bugprone-exception-escape)
{
if( tao::pegtl::analyze< grammar::main >() != 0 ) {
return 1;
}
for( int i = 1; i < argc; ++i ) {
std::string fn;
pegtl::argv_input in( argv, i );
try {
auto root = pegtl::parse_tree::parse< grammar::main, grammar::selector >( in );
std::cout << std::endl;
print_cell(root);
}
catch( const pegtl::parse_error& e ) {
const auto p = e.positions().front();
std::cerr << e.what() << '\n'
<< in.line_at( p ) << '\n'
<< std::setw( p.column ) << '^' << '\n';
}
}
return 0;
}
#endif
/*
define type structure (objects)
prototype functions
(def c)
(defn a [] 1)
(->>
a
#(filter starts-with "asdf" %1)
(reduce +)
)
lLLVMWindowsManifest -lLLVMXRay -lLLVMLibDriver -lLLVMDlltoolDriver -lLLVMCoverage -lLLVMLineEditor -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Info -lLLVMWebAssemblyDisassembler -lLLVMWebAssemblyAsmParser -lLLVMWebAssemblyCodeGen -lLLVMWebAssemblyDesc -lLLVMWebAssemblyInfo -lLLVMSystemZDisassembler -lLLVMSystemZAsmParser -lLLVMSystemZCodeGen -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSparcDisassembler -lLLVMSparcAsmParser -lLLVMSparcCodeGen -lLLVMSparcDesc -lLLVMSparcInfo -lLLVMRISCVDisassembler -lLLVMRISCVAsmParser -lLLVMRISCVCodeGen -lLLVMRISCVDesc -lLLVMRISCVInfo -lLLVMPowerPCDisassembler -lLLVMPowerPCAsmParser -lLLVMPowerPCCodeGen -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMMSP430Disassembler -lLLVMMSP430AsmParser -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMipsDisassembler -lLLVMMipsAsmParser -lLLVMMipsCodeGen -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMLanaiDisassembler -lLLVMLanaiCodeGen -lLLVMLanaiAsmParser -lLLVMLanaiDesc -lLLVMLanaiInfo -lLLVMHexagonDisassembler -lLLVMHexagonCodeGen -lLLVMHexagonAsmParser -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMBPFDisassembler -lLLVMBPFAsmParser -lLLVMBPFCodeGen -lLLVMBPFDesc -lLLVMBPFInfo -lLLVMAVRDisassembler -lLLVMAVRAsmParser -lLLVMAVRCodeGen -lLLVMAVRDesc -lLLVMAVRInfo -lLLVMARMDisassembler -lLLVMARMAsmParser -lLLVMARMCodeGen -lLLVMARMDesc -lLLVMARMUtils -lLLVMARMInfo -lLLVMAMDGPUDisassembler -lLLVMAMDGPUAsmParser -lLLVMAMDGPUCodeGen -lLLVMAMDGPUDesc -lLLVMAMDGPUUtils -lLLVMAMDGPUInfo -lLLVMAArch64Disassembler -lLLVMAArch64AsmParser -lLLVMAArch64CodeGen -lLLVMAArch64Desc -lLLVMAArch64Utils -lLLVMAArch64Info -lLLVMOrcJIT -lLLVMMCJIT -lLLVMJITLink -lLLVMOrcTargetProcess -lLLVMOrcShared -lLLVMInterpreter -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMeSymbolize -lLLVMDebugInfoPDB -lLLVMDebugInfoGSYM -lLLVMOption -lLLVMObjectYAML -lLLVMMCA -lLLVMMCDisassembler -lLLVMLTO -lLLVMPasses -lLLVMCFGuard -lLLVMCoroutines -lLLVMObjCARCOpts -lLLVMHelloNew -lLLVMipo -lLLVMVectorize -lLLVMLinker -lLLVMInstrumentation -lLLVMFrontendOpenMP -lLLVMFrontendOpenACC -lLLVMExtensions -lLLVMDWARFLinker -lLLVMGlobalISel -lLLVMMIRParser -lLLVMAsmPrinter -lLLVMDebugInfoDWARF -lLLVMSelectionDAG -lLLVMCodeGen -lLLVMIRReader -lLLVMAsmParser -lLLVMInterfaceStub -lLLVMFileCheck -lLLVMFuzzMutate -lLLVMTarget -lLLVMScalarOpts -lLLVMInstCombine -lLLVMAggressiveInstCombine -lLLVMTransformUtils -lLLVMBitWriter -lLLVMAnalysis -lLLVMProfileData -lLLVMObject -lLLVMTextAPI -lLLVMMCParser -lLLVMMC -lLLVMDebugInfoCodeView -lLLVMDebugInfoMSF -lLLVMBitReader -lLLVMCore -lLLVMRemarks -lLLVMBitstreamReader -lLLVMBinaryFormat -lLLVMTableGen -lLLVMSupport -lLLVMDemangle
all all-targets analysis binaryformat bitreader bitstreamreader bitwriter codegen core coroutines debuginfocodeview debuginfodwarf debuginfogsym debuginfomsf debuginfopdb demangle dlltooldriver dwarflinker engine executionengine extensions filecheck fuzzmutate globalisel instcombine instrumentation interfacestub ipo irreader jitlink libdriver linker lto mc mca mcdisassembler mcjit mcparser mips mipsasmparser mipscodegen mipsdesc mipsdisassembler mipsinfo mirparser msp430 msp430asmparser msp430codegen msp430desc msp430disassembler msp430info native nativecodegen nvptx nvptxcodegen nvptxdesc nvptxinfo objcarcopts object objectyaml option orcjit orcshared orctargetprocess passes powerpc powerpcasmparser powerpccodegen powerpcdesc powerpcdisassembler powerpcinfo profiledata remarks riscv riscvasmparser riscvcodegen riscvdesc riscvdisassembler riscvinfo runtimedyld scalaropts selectiondag sparc sparcasmparser sparccodegen sparcdesc sparcdisassembler sparcinfo support symbolize systemz systemzasmparser systemzcodegen systemzdesc systemzdisassembler systemzinfo tablegen target textapi transformutils vectorize webassembly webassemblyasmparser webassemblycodegen webassemblydesc webassemblydisassembler webassemblyinfo windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info xcore xcorecodegen xcoredesc xcoredisassembler xcoreinfo xray
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment