文章目录

  • 前提
  • 第一种方法(官方)
  • 第二种方法(推荐因为简便)
  • 参考资料


前提

  • 环境: idea2021.3 、jdk1.8 、SpringBoot项目
  • 初步查看官方文档进行尝试。编译原理实验要用,结果没看见有博客介绍啊。有错误请提示,只是简单的看了下文档。

吐槽: 为什么都是介绍lex语法的啊,怎么入门都不懂。。编译原理老师讲的太快了,我t走神了就没听见怎么弄了,吐了。

第一种方法(官方)

先解释方法,后面有例子。

  • 第一点:pom.xml(使用插件加载Jflex)
<build>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
  • 第二点: 在src/main/jflex/及其子目录中创建语法文件(文件后缀包括:.jflex、.jlex、.lex、.flex)

官方文档:

  • This configuration generates java code of a parser for all grammar files (, , , ) found in and its sub-directories..jflex.jlex*.lex*.flexsrc/main/jflex/
  • The name and package of the generated Java source code are the ones defined in the grammar. The generated Java source code is placed in , in sub-directories following the Java convention on package names.target/generated-source/jflex
  • 翻译:这个配置会为在src/main/jflex/及其子目录中找到的所有语法文件(.jflex、.jlex、.lex、.flex)生成Java解析器代码。生成的Java源代码的名称和包名是在语法中定义的。生成的Java源代码放置在target/generated-source/jflex中,遵循Java关于包名的约定。
  • 第三点: 使用maven先clean再compile就可以生成java类了(后面有例子)

比如说: 图示了创建的语法文件和生成的语法文件的位置 (文件位置有要求看下翻译)

idea加载maven load_java


idea加载maven load_maven_02

  • 语法文件例子(来自官方文档的例子,但官方文档好像有点问题,报错少了%%,是复制出问题了吗,反正用gpt修改了下)
    lex语法一点都不懂,服了。
/* JFlex example: partial Java language lexer specification */
import java_cup.runtime.*;

/**
 * This class is a simple example lexer.
 */
%%

%class test1Lexer
%unicode
%cup
%line
%column

%{
  StringBuffer string = new StringBuffer();

  private Symbol symbol(int type) {
    return new Symbol(type, yyline, yycolumn);
  }
  private Symbol symbol(int type, Object value) {
    return new Symbol(type, yyline, yycolumn, value);
  }
%}

LineTerminator = \r|\n|\r\n
InputCharacter = [^\r\n]
WhiteSpace     = {LineTerminator} | [ \t\f]

/* comments */
Comment = {TraditionalComment} | {EndOfLineComment} | {DocumentationComment}

TraditionalComment   = "/*" [^*] ~"*/" | "/*" "*"+ "/"
// Comment can be the last line of the file, without line terminator.
EndOfLineComment     = "//" {InputCharacter}* {LineTerminator}?
DocumentationComment = "/**" {CommentContent} "*"+ "/"
CommentContent       = ( [^*] | \*+ [^/*] )*

Identifier = [:jletter:] [:jletterdigit:]*

DecIntegerLiteral = 0 | [1-9][0-9]*

%state STRING

%%

/* keywords */
<YYINITIAL> "abstract"           { return symbol(sym.ABSTRACT); }
<YYINITIAL> "boolean"            { return symbol(sym.BOOLEAN); }
<YYINITIAL> "break"              { return symbol(sym.BREAK); }

<YYINITIAL> {
  /* identifiers */
  {Identifier}                   { return symbol(sym.IDENTIFIER); }

  /* literals */
  {DecIntegerLiteral}            { return symbol(sym.INTEGER_LITERAL); }
  \"                             { string.setLength(0); yybegin(STRING); }

  /* operators */
  "="                            { return symbol(sym.EQ); }
  "=="                           { return symbol(sym.EQEQ); }
  "+"                            { return symbol(sym.PLUS); }

  /* comments */
  {Comment}                      { /* ignore */ }

  /* whitespace */
  {WhiteSpace}                   { /* ignore */ }
}

<STRING> {
  \"                             { yybegin(YYINITIAL);
                                   return symbol(sym.STRING_LITERAL,
                                   string.toString()); }
  [^\n\r\"\\]+                   { string.append( yytext() ); }
  \\t                            { string.append('\t'); }
  \\n                            { string.append('\n'); }

  \\r                            { string.append('\r'); }
  \\\"                           { string.append('\"'); }
  \\                             { string.append('\\'); }
}

/* error fallback */
[^]                              { throw new Error("Illegal character <"+
                                                     yytext()+">"); }

第二种方法(推荐因为简便)

大概逻辑: SpringBoot项目直接下载插件,然后在src目录下创建语法文件(我用的.jflex.flex都行。语法文件例子直接用上面的例子),然后右键generator生成。如果是第一次运行它,你要选根目录文件夹作为下载jflex库和概述的目录

  • 下载插件
    Grammar-Kit
  • 创建语法文件(在第一种方法上),然后右键文件,点击generator

idea加载maven load_maven_03

  • 第一次运行generator,你要选根目录文件夹作为下载jflex库和概述的目录,我选择了resource下的Jflex文件(我自己创的)作为根目录

idea加载maven load_Java_04

参考资料