{"id":34917539,"url":"https://github.com/johnkeeping/sparse","last_synced_at":"2026-05-23T02:33:04.395Z","repository":{"id":14076491,"uuid":"16780059","full_name":"johnkeeping/sparse","owner":"johnkeeping","description":"Clone of git://git.kernel.org/pub/scm/devel/sparse/sparse.git","archived":false,"fork":false,"pushed_at":"2017-02-18T13:57:08.000Z","size":2464,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-03-23T22:11:30.048Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnkeeping.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-02-12T20:03:20.000Z","updated_at":"2017-02-18T13:57:23.000Z","dependencies_parsed_at":"2022-09-12T23:13:08.551Z","dependency_job_id":null,"html_url":"https://github.com/johnkeeping/sparse","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/johnkeeping/sparse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnkeeping%2Fsparse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnkeeping%2Fsparse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnkeeping%2Fsparse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnkeeping%2Fsparse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnkeeping","download_url":"https://codeload.github.com/johnkeeping/sparse/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnkeeping%2Fsparse/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33380663,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T01:21:08.577Z","status":"online","status_checked_at":"2026-05-23T02:00:05.530Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-26T12:51:42.666Z","updated_at":"2026-05-23T02:33:04.381Z","avatar_url":"https://github.com/johnkeeping.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n  sparse (spärs), adj,., spars-er, spars-est.\n\t1. thinly scattered or distributed; \"a sparse population\"\n\t2. thin; not thick or dense: \"sparse hair\"\n\t3. scanty; meager.\n\t4. semantic parse\n  \t[ from Latin: spars(us) scattered, past participle of\n\t  spargere 'to sparge' ]\n\n\tAntonym: abundant\n\nSparse is a semantic parser of source files: it's neither a compiler\n(although it could be used as a front-end for one) nor is it a\npreprocessor (although it contains as a part of it a preprocessing\nphase). \n\nIt is meant to be a small - and simple - library.  Scanty and meager,\nand partly because of that easy to use.  It has one mission in life:\ncreate a semantic parse tree for some arbitrary user for further\nanalysis.  It's not a tokenizer, nor is it some generic context-free\nparser.  In fact, context (semantics) is what it's all about - figuring\nout not just what the grouping of tokens are, but what the _types_ are\nthat the grouping implies.\n\nAnd no, it doesn't use lex and yacc (or flex and bison).  In my personal\nopinion, the result of using lex/yacc tends to end up just having to\nfight the assumptions the tools make. \n\nThe parsing is done in five phases:\n\n - full-file tokenization\n - pre-processing (which can cause another tokenization phase of another\n   file)\n - semantic parsing.\n - lazy type evaluation\n - inline function expansion and tree simplification\n\nNote the \"full file\" part. Partly for efficiency, but mostly for ease of\nuse, there are no \"partial results\". The library completely parses one\nwhole source file, and builds up the _complete_ parse tree in memory.\n\nAlso note the \"lazy\" in the type evaluation.  The semantic parsing\nitself will know which symbols are typedefines (required for parsing C\ncorrectly), but it will not have calculated what the details of the\ndifferent types are.  That will be done only on demand, as the back-end\nrequires the information. \n\nThis means that a user of the library will literally just need to do\n\n  struct string_list *filelist = NULL;\n  char *file;\n\n  action(sparse_initialize(argc, argv, filelist));\n\n  FOR_EACH_PTR_NOTAG(filelist, file) {\n    action(sparse(file));\n  } END_FOR_EACH_PTR_NOTAG(file);\n\nand he is now done - having a full C parse of the file he opened.  The\nlibrary doesn't need any more setup, and once done does not impose any\nmore requirements.  The user is free to do whatever he wants with the\nparse tree that got built up, and needs not worry about the library ever\nagain.  There is no extra state, there are no parser callbacks, there is\nonly the parse tree that is described by the header files. The action\nfuntion takes a pointer to a symbol_list and does whatever it likes with it.\n\nThe library also contains (as an example user) a few clients that do the\npreprocessing, parsing and type evaluation and just print out the\nresults.  These clients were done to verify and debug the library, and\nalso as trivial examples of what you can do with the parse tree once it\nis formed, so that users can see how the tree is organized. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnkeeping%2Fsparse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnkeeping%2Fsparse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnkeeping%2Fsparse/lists"}