【问题标题】:Lexer and unicode, e.g. German mutated vowel词法分析器和 unicode,例如德语变异元音
【发布时间】:2011-10-28 07:19:21
【问题描述】:

两个问题:
1.为什么字符串abäcd不能识别(ANTLRWorks 1.4.2),语法如下(结果只有abcd,这意味着德语变异元音ä丢失了)?
2. 如何将Vowels 划分为VowelsUpperVowelsLower 并在规则Vowels 中使用这两个规则?

grammar Vowels1a;

CharLower
  : 'a'..'z'
  ;

Vowels
  : 'ä' | 'ö' | 'ü' | 'Ä'| 'Ö' | 'Ü'
  ;

test
  : ( CharLower | Vowels )+
  ;

【问题讨论】:

    标签: unicode char antlr lexer antlrworks


    【解决方案1】:

    ANTLRStarter 写道:

    1 .为什么用下面的语法无法识别字符串abäcd(ANTLRWorks 1.4.2)(结果只有abcd,这意味着缺少德语变异元音ä?

    我无法重现这一点。 ANTLRWorks 的解释器和调试器 (1.4.2) 都生成以下解析树:

    一个小的手动测试也显示了这一点:

    Main.java

    import org.antlr.runtime.*;
    
    public class Main {
      public static void main(String[] args) throws Exception {
        Vowels1aLexer lexer = new Vowels1aLexer(new ANTLRStringStream("abäcd"));
        Vowels1aParser parser = new Vowels1aParser(new CommonTokenStream(lexer));
        parser.test();
      }
    }
    

    元音1a.g

    grammar Vowels1a;
    
    test
     : ( CharLower {System.out.println("CharLower :: " + $CharLower.text);}
       | Vowels    {System.out.println("Vowels    :: " + $Vowels.text);}
       )+
     ;
    
    CharLower
     : 'a'..'z'
     ;
    
    Vowels
     : 'ä' | 'ö' | 'ü' | 'Ä'| 'Ö' | 'Ü'
     ;
    

    并运行演示:

    java -cp antlr-3.3.jar org.antlr.Tool Vowels1a.g 
    javac -cp antlr-3.3.jar *.java
    java -cp .:antlr-3.3.jar Main
    

    将打印:

    CharLower :: a
    CharLower :: b
    Vowels    :: ä
    CharLower :: c
    CharLower :: d
    

    ANTLRStarter 写道:

    2 。如何在 VowelsUpper 和 VowelsLower 中划分元音并在规则元音中使用这两个规则?

    创建两个fragment 规则(VowelsUpperVowelsLower)并让Vowels 匹配这两个fragments:

    Vowels
     : VowelsUpper
     | VowelsLower
     ;
    
    fragment VowelsUpper
     : 'Ä'| 'Ö' | 'Ü'
     ;
    
    fragment VowelsLower
     : 'ä' | 'ö' | 'ü'
     ;
    

    请注意,您不能在解析器规则中使用 fragment 规则,只能在其他词法分析器规则中使用!

    【讨论】:

    • 巴特,再次感谢 - 真的很奇怪。用 ANTLRWorks 的调试器再次尝试 - 同样的问题。明天我会用解释器试试。
    • 我看到 ANTLRWorks 在语法末尾添加了一些垃圾字节,导致它做出奇怪的响应。尝试在普通文本编辑器中打开语法,看看末尾是否有一些奇数字节(并删除它们)。如果仍然相同,请尝试使用 Main 类的命令行演示:必须工作。
    • @ANTLRStarter,我也扩展了我的答案,我错过了你的第二个问题。
    • 是的,感谢您的其他答案之一,我知道这个问题。因此,我以十六进制模式检查奇怪的语法。调试器输出在CharLower :: a 之后抱怨Test_input.txt line 1:2 no viable alternative at character '?'。在十六进制模式下也检查了Test_input.txtabäcd 在十六进制模式下61 62 E4 63 64
    • 演示也可以。刚刚用 ANTLRWorks 1.4.3 试了一下,同样的问题。
    【解决方案2】:

    关于问题 1: 这闻起来很像编码问题。 “61 62 E4 63 64”表示文件使用 iso-8859-1(或 windows-something 变体)编码。 ANTLRWorks 似乎使用 utf-8,我认为没有明显的方法可以改变它。

    我假设您使用该文件作为输入运行调试器。将文件另存为 utf-8 时,它对我来说工作正常,而 iso-8859-1 缺少“ä”。我无法重现 ANTLRWorks 1.4.3 中的 NoViableAlt 错误,输入流中似乎只是缺少“ä” - 也许 java 的 utf8 解码器会默默地跳过无效序列...

    如果您构建自己的应用,您可以自行指定输入流/文件使用的编码。因此,在 Python 中,ANTLRFileStream/ANTLRInputStream 有一个方便的“编码”参数。

    【讨论】:

    • Ben,非常感谢您的努力 - 我只是在调试器中使用输入文本/文本字段和 abäcd。现在用 ANTLRWorks 1.4.2 和 1.4.3 再次检查它。如上所述的问题(但现在没有错误消息)。使用我的文件时,来自 Bart 的 Java 演示有效(编码为 61 62 E4 63 64)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-20
    • 1970-01-01
    相关资源
    最近更新 更多