首页 > 解决方案 > Antlr4 没有检测到从 1 到 8 的整数,词法分析器问题

问题描述

antlr 4 c# 存在无法识别整数标记的问题。它适用于数字 1 和 9,但不适用于 1 到 9!

我尝试重建语法,但它不起作用:(。

这是我的语法:

grammar simplerlang;

// Parser

program   : statement+ ;
statement : let | print ;
let       : VAR '=' INT ;
print     : 'print' (INT | VAR) ;

// Lexer

VAR : [a-z]+ ;
INT : [0–9]+ ;
WS  : [ \n\t]+ -> skip;

这是我的 C# 代码:

using System;
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Tree;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SuperSimpleTestLang
{
    class Program
    {

        static Dictionary<string, int> variableMap = new Dictionary<string, int>();

        static void Main(string[] args)
        {
            while (true)
            {
                Console.Write("> ");
                string _in = Console.ReadLine();
                AntlrInputStream input = new AntlrInputStream(_in);
                simplerlangLexer lexer = new simplerlangLexer(input);
                CommonTokenStream tokens = new CommonTokenStream(lexer);
                simplerlangParser parser = new simplerlangParser(tokens);

                IParseTree tree = parser.statement();
                ParseTreeWalker walker = new ParseTreeWalker();
                walker.Walk(new simplerlangCustomListener(), tree);
            }
        }

        class simplerlangCustomListener : simplerlangBaseListener
        {
            public override void ExitPrint(simplerlangParser.PrintContext ctx)
            {
                if (ctx.INT() != null)
                {
                    Console.WriteLine(ctx.INT().GetText());
                }
                else if (ctx.VAR() != null)
                {
                    Console.WriteLine(variableMap[ctx.VAR().GetText()]);
                }
            }

            public override void ExitLet(simplerlangParser.LetContext ctx)
            {
                variableMap.Add(ctx.VAR().GetText(),
                int.Parse(ctx.INT().GetText()));
            }
        }
    }


}

输入:打印1

输出: 第 1:6 行令牌识别错误:'1' 第 1:7 行在''缺少 {VAR, INT}

输入:打印 0 输出: 0

输入:打印 9 输出: 9

标签: c#antlr4

解决方案


VAR : [a-z]+ ;
INT : [0–9]+ ;

如果您仔细观察这两行,您会注意到 0 和 9 之间的破折号比 a 和 z 之间的破折号要长。这意味着这不是一个常规的破折号,而是一个 Unicode 破折号(或类似的东西)。

So ANTLR doesn't recognize this as a range, but as a character class matching 0, 9 or an emdash.


推荐阅读