如果文本相同,如何区分两个ANTLR4令牌?

时间:2017-07-21 19:52:28

标签: parsing antlr antlr4

我正在为过滤器查询解析器编写一个antlr4语法(类似于Github问题查询)。理论上,查询应该如下:

tag:abc AND user:john

但是,我在解析像:

这样的问题时遇到了问题
tag:tag

第一个标签应该表示我们按标签过滤而第二个标签只是文本。

我的语法看起来像这样:

parse
 : expression? EOF
 ;

expression
 : expression  operator  expression
 | WHITESPACE* selector WHITESPACE*
 ;

selector:
    SELECTOR ':' value=TEXT;

operator
 : AND | OR | WHITESPACE
 ;

SELECTOR     :  TAG | USER;
AND          : 'AND';
OR           : 'OR';
TAG          : 'tag' ;
USER         : 'user' ;
WHITESPACE   : (' ' | '\t') ;
TEXT_CHAR    : ~[ :];
TEXT         : TEXT_CHAR+;

2 个答案:

答案 0 :(得分:0)

TAGUSER分开:

selector: key=TAG  COLON value=TEXT
        | key=USER COLON value=TEXT
        ;

每当选择器规则匹配时,相应的SelectorContext#key字段将包含实际匹配的TAGUSER令牌。

答案 1 :(得分:0)

您可以使用以下代码代替选择器:

<html>
<head>
<title>Space shooter</title>
<style>
* {
    margin:0;
}
canvas {
    background: url("http://www.ufointernationalproject.com/wp-content/uploads/2017/03/space-03.jpg");
}
</style>
</head>
<body>
<canvas id="canvas" width="1350" height="630"></canvas>
<script>
var ctx = document.getElementById("canvas").getContext("2d"),
    lastShot = Date.now(),
    fireRate = 120,
    bullets = [],
    enemies = [],
    enemySpeed = 1.5,
    bulletSpeed = 20,
    player = {
        x: 600,
        y: 250,
        leftPressed: false,
        rightPressed: false,
        upPressed: false,
        downPressed: false,
        spacePressed: false,
        speed: 5
    };
var playerImage = new Image();
playerImage.src = "https://3.bp.blogspot.com/-jGC08Dy0zg8/U405cNq1-MI/AAAAAAAABqU/38d5rmV1S8Y/s1600/redfighter0006.png";
var enemyImage = new Image();
enemyImage.src = "https://a.fsdn.com/con/app/proj/partartspace/screenshots/Spaceship14.png/1";

function spawnEnemes() {
    enemies.push({
        x:Math.floor(Math.random() * 1250) + 1,  
        y:-100
    })
}
setInterval(spawnEnemes, 500);

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(playerImage, player.x,player.y, 100, 100);

    if (player.leftPressed) {
        player.x -= player.speed;
    }
    if (player.rightPressed) {
        player.x += player.speed;
    }
    if (player.upPressed) {
        player.y -= player.speed;
    }
    if (player.downPressed) {
        player.y += player.speed;
    }
    if (player.spacePressed && Date.now() - lastShot > fireRate) {
        bullets.push({
            x: player.x+50,
            y: player.y
        });
        lastShot = Date.now();
    }   

    bullets.forEach(function(bullet){       
        ctx.beginPath();
        ctx.arc(bullet.x, bullet.y, 5, 0, 2 * Math.PI);
        ctx.fillStyle = "red";
        ctx.fill(); 
        bullet.y -= bulletSpeed;                    
    }); 

    enemies.forEach(function(enemy){
        ctx.drawImage(enemyImage, enemy.x, enemy.y, 100,100);
        enemy.y += enemySpeed;  
    }); 

    for (var enemy = 0; enemy < enemies.length; enemy ++){
        if(player.x < enemies[enemy].x + 80 &&
               player.x + 80 > enemies[enemy].x &&
               player.y < enemies[enemy].y + 65 &&
               player.y + 100  > enemies[enemy].y)
            {
                document.location.reload();
            }
        for (var bullet = 0; bullet < bullets.length; bullet ++) {
            if(bullets[bullet].y < enemies[enemy].y + 70 &&
               bullets[bullet].y > enemies[enemy].y &&
               bullets[bullet].x < enemies[enemy].x + 100 &&
               bullets[bullet].x > enemies[enemy].x)    
            {
                bullets.splice(bullet, 1);
                enemies.splice(enemy, 1);               
            }                   
        }   
    }

    requestAnimationFrame(draw);
}
draw();

document.body.addEventListener("keydown", function(e) {
    if (e.keyCode === 37) {
        player.leftPressed = true;
    }
    else if (e.keyCode === 39) {
        player.rightPressed = true;
    }
    else if (e.keyCode === 38) {
        player.upPressed = true;
    }
    else if (e.keyCode === 40) {
        player.downPressed = true;
    }
    else if (e.keyCode === 32) {
        player.spacePressed = true;
    }
});
document.body.addEventListener("keyup", function(e) {
    if (e.keyCode === 37) {
        player.leftPressed = false;
    }
    else if (e.keyCode === 39) {
        player.rightPressed = false;
    }
    else if (e.keyCode === 38) {
        player.upPressed = false;
    }
    else if (e.keyCode === 40) {
        player.downPressed = false;
    }
    else if (e.keyCode === 32) {
        player.spacePressed = false;
    }
});
</script>
</body>
</html>