我的 scala 文件 Scala.g4 ANTLR 语法失败

问题描述 投票:0回答:1

我正在使用 ANTLR 来解析 scala 文件。

我在这里找到了 scala 语言的语法: https://github.com/antlr/grammars-v4/blob/master/scala/Scala.g4

借助 antlr4-maven-plugin,我从语法中生成了 ANTLR 类。

<plugin>
    <groupId>org.antlr</groupId>
    <artifactId>antlr4-maven-plugin</artifactId>
    <version>4.13.1</version>
    <executions>
        <execution>
            <id>antlr-generate</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>antlr4</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <sourceDirectory>src/main/antlr4</sourceDirectory>
        <outputDirectory>target/generated-sources/antlr4</outputDirectory>
        <listener>true</listener>
        <visitor>true</visitor>
    </configuration>
</plugin>

我对运行时有依赖性:

<dependency>
    <groupId>org.antlr</groupId>
    <artifactId>antlr4-runtime</artifactId>
    <version>4.13.1</version>
</dependency>

这是我解析 scala 文件的代码:

public class Main {

    public static void main(String[] args) throws IOException {
        Path filePath = Paths.get(args[0]);
        CharStream charStream = CharStreams.fromPath(filePath , StandardCharsets.UTF_8);
        ScalaLexer lexer = new ScalaLexer(charStream);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        ScalaParser parser = new ScalaParser(tokens);
        ParseTree tree = parser.compilationUnit();
        ParseTreeWalker.DEFAULT.walk(new ScalaBaseListener(), tree);
    }
}

我使用这个 scala 文件 test.scala 作为输入:

object replace {
  def process(node: Node): Seq[Node] = node match {
    case <abc:name>{ value @ _* }</abc:name> => <abc:surname>{ value }</abc:surname>
    case _ => node
  }
}

stderr 表示它发现了意外字符,例如

:
中的
<abc:name>

line 3:13 extraneous input ':' expecting {'-', 'null', 'this', 'super', '(', '_', Id, BooleanLiteral, CharacterLiteral, SymbolLiteral, IntegerLiteral, StringLiteral, FloatingPointLiteral, Varid, NL}
line 3:19 extraneous input '{' expecting {'-', 'null', 'this', 'super', '(', '_', Id, BooleanLiteral, CharacterLiteral, SymbolLiteral, IntegerLiteral, StringLiteral, FloatingPointLiteral, Varid, NL}
line 3:27 mismatched input '@' expecting {'=>', 'if'}
line 3:30 extraneous input '*' expecting {'-', 'null', 'this', 'super', '(', '{', '}', 'type', 'val', '_', 'implicit', 'if', 'while', 'try', 'do', 'for', 'throw', 'return', '+', '~', '!', 'new', 'lazy', 'case', '@', 'var', 'override', 'abstract', 'final', 'sealed', 'private', 'protected', 'import', 'def', 'class', 'object', 'trait', Id, BooleanLiteral, CharacterLiteral, SymbolLiteral, IntegerLiteral, StringLiteral, FloatingPointLiteral}

scala 文件是正确的,它是我要解析的文件的简化版本,可以编译。

我需要在语法中修正什么?

java scala maven antlr
1个回答
0
投票

语法似乎无法处理 XML 文字,因为以下代码已成功解析:

object replace {
  def process(node: Node): Seq[Node] = node match {
    case a => 1
    case _ => node
  }
}

但是,经过 Google 快速搜索后,似乎不再支持 CML 文字,而是被 XML 字符串插值取代。那么,回答你的问题:

我需要在语法中修正什么?

问题是:让词法分析器和解析器识别 XML 文本。一个快速修复方法是添加词法分析器规则:

XmlLiteral
 : '<' ~[ \t\r\n<>]+ '>' (XmlLiteral | ~[<>])*? '</' ~[ \t\r\n<>]+ '>'
 ;

然后将

XmlLiteral
添加到
literal
解析器规则中:

literal
    : '-'? IntegerLiteral
    | '-'? FloatingPointLiteral
    | BooleanLiteral
    | CharacterLiteral
    | StringLiteral
    | SymbolLiteral
    | 'null'
    | XmlLiteral
    ;

然后您的示例输入就被正确解析了。

我说“快速修复”是因为这会导致 XML 文字被标记为单个标记,而不具有任何结构。为了将 XML 正确解析为树本身,需要对词法分析器和解析器语法进行更多更改。

© www.soinside.com 2019 - 2024. All rights reserved.