{"id":18818960,"url":"https://github.com/imagemlt/imagemltyacc","last_synced_at":"2026-07-03T08:31:27.327Z","repository":{"id":201349552,"uuid":"165373051","full_name":"imagemlt/ImagemltYacc","owner":"imagemlt","description":"编译原理大作业 语法分析器yacc LR1","archived":false,"fork":false,"pushed_at":"2019-01-13T19:58:19.000Z","size":27,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-05-22T07:55:32.390Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/imagemlt.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-01-12T10:05:16.000Z","updated_at":"2019-01-13T19:58:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"0b60e6ac-e421-4edd-bafe-a3f28bb8afde","html_url":"https://github.com/imagemlt/ImagemltYacc","commit_stats":null,"previous_names":["imagemlt/imagemltyacc"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/imagemlt/ImagemltYacc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imagemlt%2FImagemltYacc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imagemlt%2FImagemltYacc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imagemlt%2FImagemltYacc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imagemlt%2FImagemltYacc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/imagemlt","download_url":"https://codeload.github.com/imagemlt/ImagemltYacc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imagemlt%2FImagemltYacc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270781393,"owners_count":24643820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-16T02:00:11.002Z","response_time":91,"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":"2024-11-08T00:19:37.844Z","updated_at":"2025-10-30T14:52:23.646Z","avatar_url":"https://github.com/imagemlt.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ImagemltYacc\n\n### 实验2 语法分析器Yacc\n\n#### 实验目的\n\n- Parser生成器：根据指定的CFG生成对应的`Parser.java`\n- `Parser.java` 跟据由Lab1生成的token序列构造语法树并且输出自底向上算法中的每一步规约过程。\n\n#### 实现的思路：\n\n- LR1分析算法，根据CFG生成LR1状态转换表ACTION与GOTO\n- 处理二义性的文法的移入规约冲突：如果移入的产生式的优先级大于规约的产生式的优先级则采取移入动作；否则采取规约动作\n\n#### 案例\n\n##### 文法描述文件：\n\n```\nID\nDIGITS\nASS\nIF\nELSE\nRETURN\nTYPE\n{\n}\n(\n)\n;\nCOMMA\narithmetic_op\nlogical_op\n%%\nSTART\n%%\n\n%%\nSTART:{ START }\nSTART:function_statement\nSTART:START function_statement\nSTART:TERM ;\nSTART:control_statement\nSTART:TERM ; START\n\nTERM:arithmetic_expression\nTERM:assignment_statement\nTERM:declaration_statement\n\nassignment_statement:ID ASS arithmetic_expression\n\n\n\nfunction_statement:TYPE ID ( ) { START }\nfunction_statement:TYPE ID ( ) { START RETURN arithmetic_expression ; }\nfunction_statement:TYPE ID ( func_parameter_declaration ) { START }\nfunction_statement:TYPE ID ( func_parameter_declaration ) { START RETURN arithmetic_expression ; }\nfunction_statement:TYPE ID ( func_parameter_declaration ) { RETURN arithmetic_expression ; }\n\ndeclaration_statement:TYPE ID\ndeclaration_statement:declaration_statement COMMA ID\ndeclaration_statement:declaration_statement COMMA declaration_statement\n\ncontrol_statement:IF ( logical_expression ) START\ncontrol_statement:IF ( logical_expression ) START ELSE START\ncall_expression:ID ( parameters_expression )\n\nparameters_expression:parameters_expression COMMA parameters_expression\nparameters_expression:arithmetic_expression\n\nfunc_parameter_declaration:TYPE ID\nfunc_parameter_declaration:func_parameter_declaration COMMA func_parameter_declaration\n\n\narithmetic_expression:arithmetic_expression arithmetic_op arithmetic_expression\narithmetic_expression:ID\narithmetic_expression:DIGITS\narithmetic_expression:call_expression\narithmetic_expression:( logical_expression )\n\nlogical_expression:logical_expression logical_op logical_expression\nlogical_expression:ID\nlogical_expression:DIGITS\n\n\n%%\npublic static void main(String[] args) {\n        Parser parser = new Parser();\n        try{\n            parser.shiftReduce(parser.readTokens(new FileReader(\"/tmp/tokens\")));\n        }\n        catch(Exception e){\n            e.printStackTrace();\n        }\n    }\n\n```\n\n这里的文法是一个存在二义性的文法，然而仍然可以利用带有优先级判断的LR1分析来解决产生的移入规约冲突问题。\n\n运行`java -jar ImagemltYacc.jar /tmp/yacc /tmp/Parser.java`可以生成针对该文法的Parser\n\n#### 源文件Source.c\n\n```c\nfloat func(int m,int n){\n\treturn m+n;\n}\nint main(){\n\tint a,b;\n\ta=0;\n\tif(a\u003e0){\n\t\ta=func(a,b);\n\t}\n\telse\n\t{\n\t\ta=5;\n\t}\n\treturn 1;\n}\n```\n\n#### token序列\n\n```\nTYPE,float\nID,func\n(,(\nTYPE,int\nID,m\nCOMMA,,\nTYPE,int\nID,n\n),)\n{,{\nRETURN,return\nID,m\narithmetic_op,+\nID,n\n;,;\n},}\nTYPE,int\nID,main\n(,(\n),)\n{,{\nTYPE,int\nID,a\nCOMMA,,\nID,b\n;,;\nID,a\nASS,=\nDIGITS,0\n;,;\nIF,if\n(,(\nID,a\nlogical_op,\u003e\nDIGITS,0\n),)\n{,{\nID,a\nASS,=\nID,func\n(,(\nID,a\nCOMMA,,\nID,b\n),)\n;,;\n},}\nELSE,else\n{,{\nID,a\nASS,=\nDIGITS,5\n;,;\n},}\nRETURN,return\nDIGITS,1\n;,;\n},}\n\n```\n\n\n\n#### 生成的Parser\n\n```java\n/*\n* too long to show \n*/\n\n```\n\n运行`javac Parser.java` `java Parser`可以对Lab1生成的Token序列进行语法分析。Parser类的成员属性parsedTree即为解析后的多叉树，同时输出自底向上分析流程的规约步骤\n\n```\nfunc_parameter_declaration-\u003eTYPE ID \tint m\nfunc_parameter_declaration-\u003eTYPE ID \tint n\nfunc_parameter_declaration-\u003efunc_parameter_declaration COMMA func_parameter_declaration \tfunc_parameter_declaration , func_parameter_declaration\narithmetic_expression-\u003eID \tm\narithmetic_expression-\u003eID \tn\narithmetic_expression-\u003earithmetic_expression arithmetic_op arithmetic_expression \tarithmetic_expression + arithmetic_expression\nfunction_statement-\u003eTYPE ID ( func_parameter_declaration ) { RETURN arithmetic_expression ; } \tfloat func ( func_parameter_declaration ) { return arithmetic_expression ; }\nSTART-\u003efunction_statement \tfunction_statement\ndeclaration_statement-\u003eTYPE ID \tint a\ndeclaration_statement-\u003edeclaration_statement COMMA ID \tdeclaration_statement , b\nTERM-\u003edeclaration_statement \tdeclaration_statement\narithmetic_expression-\u003eDIGITS \t0\nassignment_statement-\u003eID ASS arithmetic_expression \ta = arithmetic_expression\nTERM-\u003eassignment_statement \tassignment_statement\nlogical_expression-\u003eID \ta\nlogical_expression-\u003eDIGITS \t0\nlogical_expression-\u003elogical_expression logical_op logical_expression \tlogical_expression \u003e logical_expression\narithmetic_expression-\u003eID \ta\nparameters_expression-\u003earithmetic_expression \tarithmetic_expression\narithmetic_expression-\u003eID \tb\nparameters_expression-\u003earithmetic_expression \tarithmetic_expression\nparameters_expression-\u003eparameters_expression COMMA parameters_expression \tparameters_expression , parameters_expression\ncall_expression-\u003eID ( parameters_expression ) \tfunc ( parameters_expression )\narithmetic_expression-\u003ecall_expression \tcall_expression\nassignment_statement-\u003eID ASS arithmetic_expression \ta = arithmetic_expression\nTERM-\u003eassignment_statement \tassignment_statement\nSTART-\u003eTERM ; \tTERM ;\nSTART-\u003e{ START } \t{ START }\narithmetic_expression-\u003eDIGITS \t5\nassignment_statement-\u003eID ASS arithmetic_expression \ta = arithmetic_expression\nTERM-\u003eassignment_statement \tassignment_statement\nSTART-\u003eTERM ; \tTERM ;\nSTART-\u003e{ START } \t{ START }\ncontrol_statement-\u003eIF ( logical_expression ) START ELSE START \tif ( logical_expression ) START else START\nSTART-\u003econtrol_statement \tcontrol_statement\nSTART-\u003eTERM ; START \tTERM ; START\nSTART-\u003eTERM ; START \tTERM ; START\narithmetic_expression-\u003eDIGITS \t1\nfunction_statement-\u003eTYPE ID ( ) { START RETURN arithmetic_expression ; } \tint main ( ) { START return arithmetic_expression ; }\nSTART-\u003eSTART function_statement \tSTART function_statement\n[+]ACCEPT!\n```\n\n#### 核心算法描述\n\n##### 项目结构\n\n\n- ImagemltYacc.CFG.CFG类：CFG文法描述\n- ImagemltYacc.CFG.State类：CFG中的各个状态\n- ImagemltYacc.CFG.Token类：表示Token\n- ImagemltYacc.CFG.Production类：表示产生式\n- ImagemltYacc.LR.Action类 表示Action表中的移入、规约、接受动作\n- ImagemltYacc.LR1Automation类 LR1自动机\n- ImagemltYacc.LR1Item  LR1项目\n- ImagemltYacc.LRItem LR0项目\n- ImagemltYacc.SingleProduction类 表示单个产生式\n- io包中的类用于解析Yacc文件、输出Scanner\n\n\n\n#### 核心算法\n\n- `class CFG`\n  - `public boolean removeDirectLeftRecursion(Production production)`\n    - 消除直接左递归 其实LR1中并不需要\n  - removeLeftRecurision()\n    - 消除左递归算法（LR1不需要）\n  - removeEpsilonExpressions()\n    - 消除空产生式\n  - `public void removeCommonSubExpressions()`\n    - 消除公共左因子\n  - `public void getFirsts()`\n    - 获取所有项目的first集\n  - public void getFollows()\n    - 获取所有项目的follow集\n  - Broaden()\n    - 扩展CFG，加入新的开始点\n- class LR1Automation\n  - `public HashSet\u003cLR1Item\u003e getlr1Closure(LR1Item item)`\n    - 获取某个LR1项目的LR1闭包\n  - `public HashSet\u003cLR1Item\u003e getlr1Closure(HashSet\u003cLR1Item\u003e items)`\n    - 获取某个项目集的LR1闭包\n  - `public HashSet\u003cLR1Item\u003e getExtendClosure(HashSet\u003cLR1Item\u003e items,State s)`\n    - 获取某个项目集转移后的LR1闭包\n  - `public void generateLR1Clousres()`\n    - 根据CFG获取所有的LR1项目闭包\n  - `public void generateActionGoto() throws Exception`\n    - 根据CFG生成Action表和Goto表，并且加入了错误处理，当产生移入规约冲突并且冲突无法解决的情况下报错。\n- 生成的`Parser`类\n  - 内部类`class TreeNode`\n    - 多叉树的节点，用于构造最后的语法树\n  - 内部类Token\n    - 表示Token的一个类\n  - `Integer[][] gotoTable` \n    - goto表，用一个二维数组表示\n  - `HashMap\u003cInteger,HashMap\u003cInteger,Pair\u003cACTION,Integer\u003e\u003e\u003e actionTable`\n    - Action表，用一个HashMap表示\n  - `public void shiftReduce(Vector\u003cToken\u003e tokens) throws Exception`\n    - 移入规约推导算法,如果检测到语法错误将跑出异常。\n    - 利用两个栈来辅助构造最后的语法树。\n  - `private TreeNode parsedTree;`\n    - 这个成员变量就是最后的语法多叉树，可以在F5调试中看一下结构\n    - Child成员表示所有的子节点，依次类推。\n\n#### 程序开发中遇到的一些问题以及解决方法：\n\n遇到的最显著的问题就是移入规约的冲突问题，比如在if else语句中的移入规约冲突。最后使用引入优先级来解决了问题。\n\n与词法分析器的项目类似，多次使用Stack HashMap HashSet以优化程序的运行效率。\n\n\n\n#### 感受\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimagemlt%2Fimagemltyacc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fimagemlt%2Fimagemltyacc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimagemlt%2Fimagemltyacc/lists"}