{"id":20514836,"url":"https://github.com/pgvalle/simplifiedluacompiler","last_synced_at":"2026-04-20T03:31:28.369Z","repository":{"id":206495546,"uuid":"717066102","full_name":"pgvalle/SimplifiedLuaCompiler","owner":"pgvalle","description":"Trabalho da matéria de compiladores da faculdade. As instruções que segui estão no diretório assets.","archived":false,"fork":false,"pushed_at":"2023-11-27T02:44:35.000Z","size":1056,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-13T07:05:41.457Z","etag":null,"topics":["c","compilers","jesus-christ","lexer","lua","parser"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pgvalle.png","metadata":{"files":{"readme":"README.md","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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-10T13:34:38.000Z","updated_at":"2023-12-01T22:31:10.000Z","dependencies_parsed_at":"2023-11-10T15:07:34.210Z","dependency_job_id":"b9c74fa4-5c46-4257-9630-8f0ad3685dce","html_url":"https://github.com/pgvalle/SimplifiedLuaCompiler","commit_stats":null,"previous_names":["pgvalle/simplifiedluacompiler"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/pgvalle/SimplifiedLuaCompiler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgvalle%2FSimplifiedLuaCompiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgvalle%2FSimplifiedLuaCompiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgvalle%2FSimplifiedLuaCompiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgvalle%2FSimplifiedLuaCompiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pgvalle","download_url":"https://codeload.github.com/pgvalle/SimplifiedLuaCompiler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgvalle%2FSimplifiedLuaCompiler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32031532,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T00:18:06.643Z","status":"online","status_checked_at":"2026-04-20T02:00:06.527Z","response_time":94,"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":["c","compilers","jesus-christ","lexer","lua","parser"],"created_at":"2024-11-15T21:18:27.032Z","updated_at":"2026-04-20T03:31:28.335Z","avatar_url":"https://github.com/pgvalle.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Simplified Lua Compiler\n\n\n\n## Gramática\n\nA gramática original está no documento\n[analise-sintatica.pdf](assets/analise-sintatica.pdf) dentro do diretório assets.\\\nSeguem as observações da transformação LL(1):\n\n1. `Params` e `Names` eram redundantes na gramática.\n2. `FunctionBody` não era necessário.\n3. `Names` e `Name` eu chamei de `Ids` e `id`, respectivamente.\n4. `Stmt` tinha múltiplas regras que iam em “`local ...`” e “`for ...`”.\n5. `Block`, `Exps`, `Field`, `BinOp`, `Vars`, `Function` e `Names` estavam ok.\n6. `Exp` tinha recursão à esquerda.\n7. `PrefixExp` e `Var` tinham recursão indireta. Taquei `PrefixExp` em `Var`, que ganhou recursão à esquerda.\\\nDepois taquei `Var` em `PrefixExp` porque o First de ambos são iguais.\n8. O \"OPT\" virou \"?\" para facilitar.\n\n```\nBlock\n  ::= (Stmt;)*\n\nStmt\n  ::= Vars = Exps\n   |  Function\n   |  do Block end\n   |  while Exp do Block end\n   |  if Exp then Block (elseif Exp then Block ElseIf)* (else Block)? end\n   |  return Exps?\n   |  break\n   |  for id Fors\n   |  local Decls\n\nFors\n  ::= (, id)* in Exps do Block end\n   |  = Exp, Exp (, Exp)? do Block end\n\nDecls\n  ::= Ids = Exps\n   |  Function\n\nExp\n  ::= not Exp Exp2\n   |  -Exp Exp2\n   |  PrefixExp Exp2\n   |  Function Exp2\n   |  { Fields? } Exp2\n   |  nil Exp2\n   |  true Exp2\n   |  false Exp2\n   |  Number Exp2\n   |  String Exp2\n\nExp2\n  ::= BinOp Exp Exp2\n   |  ɛ\n\nExps\n  ::= Exp (, Exp)*\n\nPrefixExp\n  ::= id Var2\n   |  ( Exp ) Var2\n\nField\n  ::= [ Exp ] = Exp\n   |  id = Exp\n\nFields\n  ::= Field (, Field)*\n\nBinOp\n  ::= or | and | \u003c | \u003e | \u003c= | \u003e= | ~= | == | .. | + | - | * | / | ^\n\nVar\n  ::= id Var2\n   |  ( Exp ) [ Exp ] Var2\n\nVar2\n  ::= [ Exp ] Var2\n   |  ɛ\n\nVars\n  ::= Var (, Var)*\n\nFunction\n  ::= function id? ( Ids? ) Block end\n\nIds\n  ::= id (, id)*\n```\n\n## First\n\n```\nBlock      ( break do for function id if local return while ϵ\nStmt       ( break do for function id if local return while\nFors       , in =\nDecls      function id\nExp        ( - false function id nil not number string true {\nExp2       or and \u003c \u003e \u003c= \u003e= ~= == .. + - * / ^ ϵ\nExps       ( - false function id nil not number string true { ϵ\nPrefixExp  ( id\nField      [ id\nFields     [ id ϵ\nBinOp      or and \u003c \u003e \u003c= \u003e= ~= == .. + - * / ^ ϵ\nIds        id\nVar        ( id\nVar2       [ ϵ\nVars       ( id\nFunction   function\n```\n\n## Follow\n\n```\nBlock      EOTS else elseif end\nStmt       ;\nFors       ;\nDecls      ;\nExp        ) , ] do then or and \u003c \u003e \u003c= \u003e= ~= == .. + - * / ^\nExp2       ) , ] do then or and \u003c \u003e \u003c= \u003e= ~= == .. + - * / ^\nExps       ; do\nPrefixExp  ) , ] do then or and \u003c \u003e \u003c= \u003e= ~= == .. + - * / ^\nField      ,\nFields     }\nBinOp      ( - false function id nil not number string true {\nIds        ) =\nVar        , =\nVar2       ) , = ] or and \u003c \u003e \u003c= \u003e= ~= == .. + - * / ^ do then\nVars       =\nFunction   ) , ] ; do then or and \u003c \u003e \u003c= \u003e= ~= == .. + - * / ^\n```\n\n## Implementação\n\nO analisador sintático  está dividido em três arquivos:\n[Parser.h](source/Parser.h), [ParserBase.cpp](source/ParserBase.cpp) e\n[ParserRules.cpp](source/ParserRules.cpp). Utilizei orientação a objetos, assim\ncomo no trabalho de análise léxica. Então existe uma classe Parser, e ela tem um\nLexer e um Token como campos.\n\n#### Observações Gerais\n\nA Primeira coisa importante a se dizer se trata dos nomes das variáveis no\ncódigo. `Exp` virou `Expression`, `Stmt` virou `Statement` e por ai vai.\n\nUm outro ponto é sobre os métodos que implementam as regras. Eu fiz algumas\ncoisas diferentes de como está na gramática:\n\n1. Criei um procedimento para o padrão `do Block end` chamado `do_statement()`.\nEu chamo ele toda vez que o padrão aparece. O porém é que em teoria deveria\nexistir uma regra `DoStmt` ou algo assim, mas criá-la deixaria a gramática\nmaior, então considerei isso somente para a implementação.\n2. As implementações de algumas coisas, como as dos comandos for e if, ficaram\nmeio grandinhas. Por isso eu modulei um pouco mais o código, mesmo não tendo (e\neu não querendo adicionar) as regras `ForStmt` e `IfStmt` na gramática.\n3. `Vars` e `Fields` só são chamados dentro de `Stmt` e suas implementações são\npequenas. Então simplesmente os implementei diretamente dentro de `Exp`.\n\n#### Funcionamento\n\n**NOTA:** O executável precisa exatamente de 1 argumento: o caminho (relativo\nou absoluto) do arquivo a analisar.\n\n`parse()` pega o primeiro token e passa a execução para\n`Block`. Quando `Block` termina, `parse()` verifica se o token atual é o `EOTS`.\nSe for, ótimo. Senão, continua chamando `Block` enquanto não for.\n\nPara tratamento de erro, implementei o método `panic(err_msg, sync_sets)`, que\ndescarta tokens até que se ache algum dentro de `sync_sets`. No caso de encontrar\n`EOTS`, o programa termina.\n\n## Testes\n\n![teste 1](tests/test1.png \"Test1\")\n![teste 2](tests/test2.png \"Test2\")\n![teste 2](tests/test3.png \"Test3\")\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgvalle%2Fsimplifiedluacompiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpgvalle%2Fsimplifiedluacompiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgvalle%2Fsimplifiedluacompiler/lists"}