当前位置: 首页 > 知识库问答 >
问题:

解析规则无咖啡因文法antlr4

怀飞扬
2023-03-14

我正在为用ANTLR4编写的Decaf编程语言创建解析器和lexer规则。我试图解析一个测试文件,但不断地得到一个错误,一定是语法有问题,但我无法理解。

我的测试文件如下所示:

class Program {
  int i[10];
}

错误是:第2行:8不匹配的输入“10”应为INT_LITERAL

下面是完整的decaf.g4语法文件

grammar Decaf;


/*
  LEXER RULES
  -----------
  Lexer rules define the basic syntax of individual words and symbols of a
  valid Decaf program. Lexer rules follow regular expression syntax.
  Complete the lexer rules following the Decaf Language Specification.
*/



CLASS : 'class';

INT : 'int';

RETURN : 'return';

VOID : 'void';

IF : 'if';

ELSE : 'else';

FOR : 'for';

BREAK : 'break';

CONTINUE : 'continue';

CALLOUT : 'callout';

TRUE : 'True' ;

FALSE : 'False' ;

BOOLEAN : 'boolean';

LCURLY : '{';

RCURLY : '}';

LBRACE : '(';

RBRACE : ')';


LSQUARE : '[';

RSQUARE : ']';
ADD : '+';

SUB : '-';

MUL : '*';

DIV : '/';

EQ : '=';

SEMI : ';';

COMMA : ',';

AND : '&&';

LESS : '<';

GREATER : '>';

LESSEQUAL : '<=' ;

GREATEREQUAL : '>=' ;

EQUALTO : '==' ;

NOTEQUAL : '!=' ;

EXCLAMATION : '!';



fragment CHAR : (' '..'!') | ('#'..'&') | ('('..'[') | (']'..'~') | ('\\'[']) | ('\\"') | ('\\') | ('\t') | ('\n');

CHAR_LITERAL : '\'' CHAR '\'';

//STRING_LITERAL : '"' CHAR+ '"' ;


HEXMARK : '0x';

fragment HEXA : [a-fA-F];

fragment HEXDIGIT : DIGIT | HEXA ;

HEX_LITERAL : HEXMARK HEXDIGIT+;


STRING : '"' (ESC|.)*? '"';

fragment ESC : '\\"' | '\\\\';




fragment DIGIT : [0-9];

DECIMAL_LITERAL : DIGIT(DIGIT)*;



COMMENT : '//' ~('\n')* '\n' -> skip;

WS : (' ' | '\n' | '\t' | '\r') + -> skip;

fragment ALPHA : [a-zA-Z] | '_';

fragment ALPHA_NUM : ALPHA | DIGIT;



ID : ALPHA ALPHA_NUM*;

INT_LITERAL : DECIMAL_LITERAL | HEX_LITERAL;

BOOL_LITERAL : TRUE | FALSE;

/*
  PARSER RULES
  ------------
  Parser rules are all lower case, and make use of lexer rules defined above
  and other parser rules defined below. Parser rules also follow regular
  expression syntax. Complete the parser rules following the Decaf Language
  Specification.
*/




program : CLASS ID LCURLY field_decl* method_decl* RCURLY EOF;

field_name : ID | ID LSQUARE INT_LITERAL RSQUARE;

field_decl : datatype field_name (COMMA field_name)* SEMI;

method_decl : (datatype | VOID) ID LBRACE ((datatype ID) (COMMA datatype ID)*)? RBRACE block;

block : LCURLY var_decl* statement* RCURLY;

var_decl : datatype ID (COMMA ID)* SEMI;


datatype : INT | BOOLEAN;

statement : location assign_op expr SEMI
        | method_call SEMI
        | IF LBRACE expr RBRACE block (ELSE block)?
        | FOR ID EQ expr COMMA expr block
        | RETURN (expr)? SEMI
        | BREAK SEMI
        | CONTINUE SEMI
        | block;
        
assign_op : EQ
          | ADD EQ
          | SUB EQ;
          
          
method_call : method_name LBRACE (expr (COMMA expr)*)? RBRACE
            | CALLOUT LBRACE STRING(COMMA callout_arg (COMMA callout_arg)*) RBRACE;


method_name : ID;

location : ID | ID LSQUARE expr RSQUARE;


expr : location
     | method_call
     | literal
     | expr bin_op expr
     | SUB expr
     | EXCLAMATION expr
     | LBRACE expr RBRACE;

 callout_arg : expr
            | STRING ;

bin_op : arith_op
      | rel_op
      | eq_op
      | cond_op;


arith_op : ADD | SUB | MUL | DIV | '%' ;

rel_op : LESS | GREATER | LESSEQUAL | GREATEREQUAL ;

eq_op : EQUALTO | NOTEQUAL ;

cond_op : AND | '||' ;

literal : INT_LITERAL | CHAR_LITERAL | BOOL_LITERAL ;

共有1个答案

后化
2023-03-14

每当有2个或更多的lexer规则匹配相同的字符时,首先定义的规则将获胜。在您的示例中,这两个规则都符合10:

DECIMAL_LITERAL : DIGIT(DIGIT)*;

INT_LITERAL : DECIMAL_LITERAL | HEX_LITERAL;

由于int_literal是在decimal_literal之后定义的,所以lexer永远不会创建int_literal标记。如果您现在尝试在解析器规则中使用它,您将得到一条发布的错误消息

解决方案:从lexer中删除int_literal并创建解析器规则:

int_literal : DECIMAL_LITERAL | HEX_LITERAL;
 类似资料:
  • 我试图在新的Android项目中创建浓缩咖啡UI测试,但我面临以下问题。 如果我试图创建一个空的测试类: 我总是收到以下错误消息: 几乎所有导入的库都标记为未使用。 建筑gradle文件包含以下内容: 如果我把这些设置放在我的其他测试项目上,它是有效的,所以我不知道会出什么问题? 我遵循了这个教程:” http://www.vogella.com/tutorials/AndroidTestingE

  • 我正在尝试在kitkat版本上切换飞行模式,在root模拟器上。我正在使用浓缩咖啡进行自动化,并且我有一个场景,我必须打开飞行模式并在应用程序中执行某些步骤 我用以下方法修改了时间: 但是我无法切换到飞行模式,我尝试了不同的模式...使用上述方法并使用adb命令修改了以下行 有人可以帮助代码或adb脚本,我可以通过它打开和关闭飞行模式

  • 在Espresso中,应用程序启动,测试以以下代码开始:onView(withId(r.id.choosebooktitle)).perform(click()); 这会崩溃,因为显示器仍然显示启动屏幕,而chooseBookTitle只有在之后才可见。如何防止谷歌-浓缩咖啡会在它出现之前点击键? (我不想插入等待循环,而是保持事件驱动。在更糟糕的情况下,我回到Robotium)

  • CloudGate解析规则可以直接导入使用,不需要任何额外的操作,非常方便! 规则列表 规则名称 下载地址 Surge https://async.be/Rule/Basic/Hosts Shadowrocket https://async.be/Rule/Basic/Hosts 解析规则 简要概述:通过实时同步Hosts信息源达到自动更新,同时使用解析模板进行生成。 无需任何其他操作,导入即可使

  • template.defaults.rules art-template 可以自定义模板解析规则,默认配置了原始语法与标准语法。 修改界定符 // 原始语法的界定符规则 template.defaults.rules[0].test = /<%(#?)((?:==|=#|[=-])?)[ \t]*([\w\W]*?)[ \t]*(-?)%>/; // 标准语法的界定符规则 template.def

  • 我不能进口浓缩咖啡套餐 这是我的应用程序分级文件 onView(with text(“hello world!”)).check(matches(issplayed())); 我是不是漏掉了什么?