2

我正在编辑 Web 电子表格的功能,我需要在其中识别单元格引用、范围引用,然后根据我的要求对它们进行着色。我能够识别单元格引用并为其着色,但无法识别固定单元格引用($a$1、$a1、a$1 等),因为它在输入美元('$')符号后抛出错误。谁可以帮我这个事。

当我尝试将单元格引用输入为“$A$1”时,在为行引用输入第二个美元符号后它不会抛出任何可行的异常,我不知道为什么。如何读取“$”符号以识别固定单元格引用?

仅供参考,我已经扩展了 @ antlr3 找到的语法 - 生成解析树

我正在使用语法进行单元格/范围参考,如下所示

CELLREFERENCE
    :  '$'?('a'..'z'|'A'..'Z')+'$'?('0'..'9')+
    ;

RANGEREFERENCE
    : '$'?('a'..'z'|'A'..'Z')+'$'?('0'..'9')+ ':' '$'?('a'..'z'|'A'..'Z')+'$'?('0'..'9')+
    ;

This will work for identifying the colon,

RANGEREFERENCE : CELLREFERENCE ((':' CELLREFERENCE)=> ':' CELLREFERENCE)?;

Still not sure about the '$' issue in cell reference.

请在此处找到完整的语法:

grammar Excel;

options {
  output=AST;
  language=JavaScript;
}

tokens {
    // define pseudo-operations
    FUNC;
    CALL;
    NEGATE;
}

parse
  :  exp EOF -> exp
  ;

exp
  :  orExp
  ;

orExp
  :  andExp (OR^ andExp)*
  ;

andExp
  :  eqExp (AND^ eqExp)*
  ;

eqExp
    : relExp (( EQUALS | NOTEQUALS)^ relExp)*
    ;

relExp
    : addExp ( (LT^|LTEQ^|GT^|GTEQ^) addExp)*
    ;

addExp
    : multExp ( (PLUS^| MINUS^) multExp)*
    ;
multExp 
    : unaryExp (( MULT^ | DIV^ | MOD^ |POW^| IS^) unaryExp)*
    ;

unaryExp
  :  NOT atom -> ^(NOT atom)
  |  MINUS atom -> ^(NEGATE atom)
  |  ASSIGN atom -> ^(ASSIGN atom)
  |  atom
  ;

atom
  :  TRUE
  |  FALSE
  |  INT
  |  FLOAT
  |  function
  |  CELLREFERENCE
  |  RANGEREFERENCE
  |  '(' exp ')' -> exp
  ;

POW : '^';
DIV : '/';
MOD : '%';
MULT : '*';
PLUS : '+';
MINUS : '-';
LT   : '<';
LTEQ : '<=';
GT   : '>';
GTEQ : '>=';
EQUALS : '==';
ASSIGN: '=';
NOTEQUALS : '<>';
INT    : '0'..'9'+;
FLOAT  : ('0'..'9')* '.' ('0'..'9')+;
OR     : 'or' ;
AND    : 'and' ;
IS     : 'is' ;
NOT    : 'not' ;
TRUE   : 'true' ;
FALSE  : 'false' ;

function
    :   IDENT '(' ( exp (',' exp)* )? ')' -> ^(FUNC IDENT (exp)*)
    ;
CELLREFERENCE
    :  '$'?('a'..'z'|'A'..'Z')+'$'?('0'..'9')+
    ;

RANGEREFERENCE
    : '$'?('a'..'z'|'A'..'Z')+'$'?('0'..'9')+ ':' '$'?('a'..'z'|'A'..'Z')+'$'?('0'..'9')+
    ;

IDENT
    :   ('a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' |'0'..'9')*
    ;   

SPACE  : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;} ;

ERRCHAR : Err =. { /*console.log($Err);*/ } ;
4

1 回答 1

1

我无法重现它。

当我复制粘贴您的原始语法时(没有谓词( ... )=>!),并将parse规则更改为:

parse
  :  (t=. {console.log('type:', $t.type, 'text:', $t.text);})* EOF
     //exp EOF -> exp
  ;

然后我生成一个词法分析器/解析器:

java -cp antlr-3.3-complete.jar org.antlr.Tool Excel.g

并使用测试 html 文件:

<html>
  <head>
    <script type="text/javascript" src="antlr3-all-min.js"></script>
    <script type="text/javascript" src="ExcelLexer.js"></script>
    <script type="text/javascript" src="ExcelParser.js"></script>    
    <script type="text/javascript">

    function init() {
      var evalButton = document.getElementById("eval");
      evalButton.onclick = evalExpression;
    }

    function evalExpression() {
      document.getElementById("answer").innerHTML = "";
      var Excelression = document.getElementById("src").value;
      if(Excelression) {
        var lexer = new ExcelLexer(new org.antlr.runtime.ANTLRStringStream(Excelression));
        var tokens = new org.antlr.runtime.CommonTokenStream(lexer);
        var parser = new ExcelParser(tokens);
        parser.parse().getTree();
      }
    }

    </script>
  </head>
  <body onload="init()">
    <input id="src" type="text" size="35" />
    <button id="eval">evaluate</button>
    <div id="answer"></div>
  </body>
</html>

然后$a$1 $a$1:$a$9在文本字段中输入输入,我看到以下输出被打印到我的 Chrome 控制台:

类型:28 文本:$a$1
类型:29 文本:$a$1:$a$9

Excel.tokens 文件包含:

细胞参考=28
范围参考=29
于 2013-01-17T19:14:33.640 回答