我的ANTLR语法有错误的结果

时间:2016-07-07 01:51:50

标签: antlr4

我在ANTLR中有一个语法,我有一个文件来测试我的语法。 但我不知道我的输出有什么问题。

这是我的语法:

grammar proj;

start
    : (assign|define|read|write|condition|while|module|callingmodule)+
    ;

assign
    : T_ID T_ENTESAB expentesab T_SEPARATOR
    ;

expentesab
    : T_ID
    | T_NUMBER
    | T_SABETMANTEGHI
    | expentesab operator expentesab
    | expentesab operator
    | operator expentesab
    | T_PARANTEZBAZ expentesab T_PARANTEZBASTE
    | expentesab T_COMMA expentesab
    | T_PARANTEZBAZ expentesab T_COMMA expentesab T_PARANTEZBASTE
    | expentesab T_COMMA T_PARANTEZBAZ expentesab T_PARANTEZBASTE
    ;

operator
    : T_ADD
    | T_SUB
    | T_MUL
    | T_DIV
    | T_POW
    | T_FACT
    | T_AND
    | T_OR
    | T_XOR
    ;

define
    : T_ID T_2POINT T_TYPE T_SEPARATOR
    ;

read
    : T_READ expread T_SEPARATOR
    ;

expread
    : T_ID
    | T_NUMBER
    | operator
    | T_PARANTEZBAZ expread T_PARANTEZBASTE
    | expread operator expread
    ;

write
    : T_WRITE expwrite T_SEPARATOR
    ;

expwrite
    : T_ID
    | T_NUMBER
    | operator
    | T_PARANTEZBAZ expwrite T_PARANTEZBASTE
    | expwrite operator expwrite
    | expwrite T_COMPARE expwrite  
    ;

condition
    : T_IF expcon T_THEN code_if T_ELSE code_if T_SEPARATOR
    | T_IF expcon T_THEN code_if T_SEPARATOR
    ;

expcon
    : assign
    | define
    | expcon T_COMPARE expcon
    | expcon operator expcon
    | operator expcon
    ;

code_if
    : condition
    | block
    | define
    | assign
    | callingmodule
    | code_if operator code_if
    | T_PARANTEZBAZ code_if T_PARANTEZBASTE T_SEPARATOR
    | T_PARANTEZBAZ code_if operator code_if T_PARANTEZBASTE T_SEPARATOR
    ;

callingmodule
    : T_ID T_PARANTEZBAZ params T_PARANTEZBASTE T_SEPARATOR
    | T_ID T_PARANTEZBAZ  T_PARANTEZBASTE T_SEPARATOR
    ;

params
    : expparam(T_COMMA expparam)*
    ;

expparam
    : T_ID
    | shart
    | T_ID operator T_NUMBER
    | T_PARANTEZBAZ expparam T_PARANTEZBASTE
    ;

while
    : T_WHILE expwhile code_while
    ;

expwhile
    : T_SABETMANTEGHI
    | T_NUMBER
    | T_PARANTEZBAZ expwhile T_PARANTEZBASTE
    | expwhile operator expwhile
    | T_ID T_COMPARE T_ID
    | expwhile T_AND expwhile
    | expwhile T_OR expwhile
    | expwhile T_XOR expwhile      
    ;  

code_while 
    : block
    | module
    | callingmodule
    | define
    | assign
    | code_while operator code_while T_SEPARATOR
    | T_PARANTEZBAZ code_while T_PARANTEZBASTE T_SEPARATOR
    | T_PARANTEZBAZ code_while operator code_while T_PARANTEZBASTE T_SEPARATOR
    ;

block
    : T_BEGIN  inner_block  T_END
    ;

inner_block
    : define
    | assign
    | condition 
    | callingmodule
    | block
    | T_ID operator T_ID
    | T_PARANTEZBAZ inner_block T_PARANTEZBASTE T_SEPARATOR
    | T_PARANTEZBAZ T_ID operator T_ID T_PARANTEZBASTE T_SEPARATOR
    ;

module
    : T_MODULE T_ID T_INPUT T_2POINT (define)+ T_OUTPUT T_2POINT T_TYPE block
    | T_MODULE T_ID block 
    ;

shart
    : expcon T_CONDITION code_if T_2POINT code_if
    | expcon T_CONDITION code_if T_2POINT code_if T_SEPARATOR
    ;

T_TYPE: ('s'|'S')('t'|'T')('r'|'R')('i'|'I')('n'|'N')('g'|'G')|('r'|'R')('e'|'E')('a'|'A')('l'|'L')|
('b'|'B')('o'|'O')('o'|'O')('l'|'L');
T_END: ('e'|'E')('n'|'N')('d'|'D');
T_BEGIN:('b'|'B')('e'|'E')('g'|'G')('i'|'I')('n'|'N');
T_WHILE:('w'|'W')('h'|'H')('i'|'I')('l'|'L')('e'|'E');
T_IF:('i'|'I')('f'|'F');
T_THEN:('t'|'T')('h'|'H')('e'|'E')('n'|'N');
T_ELSE:('e'|'E')('l'|'L')('s'|'S')('e'|'E');
T_READ:('r'|'R')('e'|'E')('a'|'A')('d'|'D');
T_WRITE:('w'|'W')('r'|'R')('i'|'I')('t'|'T')('e'|'E');
T_MODULE:('M'|'m')('O'|'o')('D'|'d')('U'|'u')('L'|'l')('E'|'e');
T_INPUT:('I'|'i')('N'|'n')('P'|'p')('U'|'u')('T'|'t');
T_OUTPUT:('O'|'o')('U'|'u')('T'|'t')('P'|'p')('U'|'u')('T'|'t');
T_RETURN:('R'|'r')('E'|'e')('T'|'t')('U'|'u')('R'|'r')('N'|'n');
T_SEPARATOR : ';';
T_SABETMANTEGHI: ('t'|'T')('r'|'R')('u'|'U')('e'|'E')|('f'|'F')('a'|'A')('l'|'L')('s'|'S')('e'|'E');
T_NUMBER:T_HEXNUMBER|T_INTEGERNUMBER;
T_HEXNUMBER: '0' ('x'|'X') ('0'..'9'|'a'..'f'|'A'..'F')+|'0' ('x'|'X') ('0'..'9'|'a'..'f'|'A'..'F')+ '.' ('0'..'9'|'a'..'f'|'A'..'F')+;
T_INTEGERNUMBER:(('0'..'9')+|('0'..'9')+ '.'('0'..'9')+);
T_FUNC:('F'|'f')('U'|'u')|('N'|'n')('C'|'c');
T_ADD: '+';
T_SUB: '-';
T_MUL: '*';
T_DIV: '/';
T_POW: '^';
T_FACT: '!';
T_ENTESAB:'=';
T_X:'x'|'X';
T_AND: ('a'|'A')('n'|'N')('d'|'D');
T_OR: ('o'|'O')('r'|'R');
T_NOT: ('n'|'N')('o'|'O')('t'|'T');
T_XOR: ('x'|'X')('o'|'O')('r'|'R');
T_COMPARE: '>'| '<'| '>='|'<='|  '<>';
T_REMAIN: '%';
T_CONDITION:'?';
T_2POINT:':';
T_PARANTEZBAZ:'(';
T_PARANTEZBASTE:')';
T_COMMA:',';
T_COMMENT:T_COM1LINE|T_COMMULLINE;
T_COM1LINE: '%%' ~( '\t'|'\r')+ -> skip ;
T_COMMULLINE:'%%%' (.|('\t'|'\r'|' '|'\n'))*? '%%%' ->skip;
T_ID :   [a-zA-Z] ([a-zA-Z]|('0'..'9'))*;
T_WS : (('\t'|'\r'|' ')+) ->skip;
T_NEWLINE:('\n')->skip;
T_LEXICALERROR:.;

这是我的输入文件:

%%%This is a sample Written in QUPLA $
@The program compute fibonacci serie%%%
module func
input:
    X:real;
output:
  i:real;
begin
    if x> 0 then
    begin 
        return Func(x-1)+func(x-2);
    end
    begin
    return 1;
    end
end
%% This is the main module &%*&()
module main
begin
    i:real;
    read i;
    write (func(i)?1:2);
end

对于此输入,我有以下错误:

  

第5行期待T_ID,但我有T_ID!

     

第8行期待T_IF,T_WHILE T_READ ....但我有T_IF

1 个答案:

答案 0 :(得分:1)

让我们从您的错误开始。

答案

  

第5行期待T_ID,但我有T_ID!

此错误是由于您的词法分析器规则T_X:'x'|'X';与示例代码的第5行中的X匹配。 X将与T_X lexem匹配,因为T_X lexem是在预期的T_ID lexem之前定义的。答案是: 它不是T_ID令牌,而是T_X

  

第8行期待T_IF,T_WHILE T_READ ....但我有T_IF

在代码示例的第7行中,您尝试定义输出变量i:real。但是在define+定义的输出部分中缺少module规则。我假设你可以有命名输出参数。然后,正确的module规则应如下所示:

module
    : T_MODULE T_ID T_INPUT T_2POINT define+ T_OUTPUT T_2POINT define+ T_TYPE block
    | T_MODULE T_ID  block
    ;

由于缺少define+module规则的定义被中断,第6行output:之后的所有内容都被视为主要规则{{的定义(define)替代1}}。

如果不是这种情况并且您的代码示例错误,那么您应该删除模块start部分中的i:个字符。

无论如何,答案是: 代码示例与您的语法不一致

修改

重新排列您的令牌

您应该按顺序定义您的令牌:

  1. 跳过的代币(例如空白,评论)
  2. 专业代币(例如关键字,运营商,文字)
  3. 一般代币(例如标识符)
  4. 注意规则命名

    您不能使用为您使用ANTLRv4的语言保留的名称。您定义了output语法规则,这将在Java中引发与while关键字的冲突。

    可读性和简单性是关键

    使用pleasent to eye和更简单的ANTLRv4构造:

    • while更改为T_WS : (('\t'|'\r'|' ')+) ->skip;
    • T_WS : [ \t\r]+ -> skip;更改为T_ID : [a-zA-Z] ([a-zA-Z]|('0'..'9'))*;
    • T_ID : [a-zA-Z] [a-zA-Z0-9]*;更改为T_COMMULLINE:'%%%' (.|('\t'|'\r'|' '|'\n'))*? '%%%' ->skip;(点T_COMMULLINE:'%%%' .*? '%%%' -> skip;无论如何都会匹配所有内容,尤其是空白字符)