添加解析器规则后,ANTLR4在输入时没有可行的替代方案

时间:2018-03-12 16:38:51

标签: parsing xpath xquery antlr antlr4

我试图在angular.module('csvApp').directive('disableMouseWheel', function () { return { restrict: 'E', scope: { idName: '@', idIndex: '=' }, template:'', link: function(scope, element, attrs){ console.log(scope.idName+scope.idIndex.toString()) numtgen_elem = document.getElementById(scope.idName+scope.idIndex.toString()); numtgen_elem.addEventListener("mousewheel", function(event){ this.blur() }); } }; }) 中定义XQuery和XPath的语言。与我的问题相关的文件部分如下:

test.g4

我尝试解析类似grammar test; ap: 'doc' '(' '"' FILENAME '"' ')' '/' rp | 'doc' '(' '"' FILENAME '"' ')' '//' rp ; rp: ...; f: ...; xq: STRING | ... ; FILENAME : [a-zA-Z0-9/_]+ '.xml' ; STRING : '"' [a-zA-Z0-9~!@#$%^&*()=+._ -]+ '"'; WS: [ \n\t\r]+ -> skip; 的内容,但它提供了

doc("movies.xml")//TITLE

但是,如果我删除line 1:4 no viable alternative at input 'doc("movies.xml"' 解析器规则,它可以正常工作。由于STRING出现在FILENAME之前,我不知道为什么它无法将STRINGdoc("movies.xml")//TITLE解析器规则匹配。我怎样才能解决这个问题?谢谢!

1 个答案:

答案 0 :(得分:1)

你的语法中的文字标记只不过是常规标记。所以你的词法分析器将如下所示:

TOKEN_1  : 'doc';
TOKEN_2  : '(';
TOKEN_3  : '"';
TOKEN_4  : ')';
TOKEN_5  : '/'; 
TOKEN_6  : '//';
FILENAME : [a-zA-Z0-9/_]+ '.xml'  ;
STRING   : '"' [a-zA-Z0-9~!@#$%^&*()=+._ -]+ '"';
WS       : [ \n\t\r]+ -> skip;

(他们并没有真正称为TOKEN_...,但这并不重要)

现在,ANTLR创建令牌的方式是尝试匹配尽可能多的字符。每当两个(或更多)规则匹配相同数量的字符时,首先定义的一个"胜出"。根据这两条规则,输入doc("movies.xml")将被标记为如下:

  • doc → TOKEN_1
  • ( → TOKEN_2
  • "movies.xml" → STRING
  • ) → TOKEN_4

由于ANTLR尝试匹配尽可能多的字符,因此"movies.xml"被标记为单个标记。词法分析者不会"听"解析器在给定时间可能需要什么。这就是ANTLR的工作原理,你无法改变它。

仅供参考,用户提供了XPath语法:https://github.com/antlr/grammars-v4/blob/master/xpath/xpath.g4