diff --git a/eo-parser/src/main/antlr4/org/eolang/parser/Program.g4 b/eo-parser/src/main/antlr4/org/eolang/parser/Program.g4 new file mode 100644 index 0000000000..73e6340481 --- /dev/null +++ b/eo-parser/src/main/antlr4/org/eolang/parser/Program.g4 @@ -0,0 +1,340 @@ +grammar Program; + +tokens { TAB, UNTAB } + +program + : + license? + metas? + objects + EOF + ; + +license + : + (COMMENT EOL)* + COMMENT EOP + ; + +metas + : + (META EOL)* + META EOP + ; + +objects + : + ( + (COMMENT EOL)* + object + (EOL | EOP) + )+ + ; + +object + : + ( + abstraction + | + application + ) + tail? + ( + EOL + method + htail? + suffix? + tail? + )* + ; + +abstraction + : + (COMMENT EOL)* + attributes + ( + (suffix (SPACE SLASH (NAME | QUESTION))?) + | htail + )? + ; + +attributes + : + LSQ + ( + (attribute (SPACE attribute)* (SPACE vararg)?)? + | + vararg + ) + RSQ + ; + +attribute + : + label + ; + +vararg + : + label + DOTS + ; + +label + : + AT + | + NAME + ; + +tail + : + EOL + TAB + (object (EOL | EOP))+ + UNTAB + ; + +suffix + : + SPACE + ARROW + SPACE + label + CONST? + ; + +method + : + DOT + mtd=( + NAME + | + RHO + | + SIGMA + | + AT + | + VERTEX + ) + COPY? + ; + +scope + : + LB + application + RB +; + +application + : + head + version + | + head + htail? + | + application + method + htail? + | + application + method + version + suffix? + | + scope + htail? + | + application + has + htail? + | + application + suffix + htail? + ; + +htail + : + ( + SPACE + application + method + | + SPACE + head + | + SPACE + scope + | + SPACE + application + has + | + SPACE + application + suffix + | + SPACE + abstraction + )+ + ; + +head + : + DOTS? + ( + ROOT + | + HOME + | + ( + AT + | + RHO + | + XI + | + SIGMA + ) + DOT? + | + STAR + | + NAME + COPY? + | + ( + NAME + | + VERTEX + ) + DOT + | + data + | + abstraction + ) + ; + +version + : + BAR + VER + ; + +has + : + COLON + ( + NAME + | + RHO + ) + ; + +data + : + BYTES + | + BOOL + | + TEXT + | + STRING + | + INT + | + FLOAT + | + HEX + ; + +COMMENT: HASH | (HASH ~[\r\n]* ~[\r\n\t ]); +META: PLUS NAME (SPACE ~[\r\n]+)?; + +ROOT: 'Q'; +HOME: 'QQ'; +STAR: '*'; +DOTS: '...'; +CONST: '!'; +SLASH: '/'; +COLON: ':'; +COPY: '\''; +ARROW: '>'; +VERTEX: '<'; +SIGMA: '&'; +XI: '$'; +PLUS: '+'; +MINUS: '-'; +QUESTION: '?'; +SPACE: ' '; +DOT: '.'; +LSQ: '['; +RSQ: ']'; +LB: '('; +RB: ')'; +AT: '@'; +RHO: '^'; +HASH: '#'; +BAR: '|'; + +fragment INDENT: + SPACE SPACE + ; +fragment LINEBREAK: + ('\n' | '\r\n') + ; + +EOL + : + LINEBREAK + INDENT* + ; + +EOP + : + LINEBREAK + LINEBREAK + INDENT* + ; + +fragment BYTE: [0-9A-F][0-9A-F]; +fragment EMPTY_BYTES : MINUS MINUS; +fragment LINE_BYTES : BYTE (MINUS BYTE)+; + +BYTES: + EMPTY_BYTES + | BYTE MINUS + | LINE_BYTES (MINUS EOL LINE_BYTES)*; + +BOOL: 'TRUE' | 'FALSE'; +STRING: '"' (~["\\\r\n] | ESCAPE_SEQUENCE)* '"'; + +fragment ESCAPE_SEQUENCE + : '\\' [btnfr"'\\] + | '\\' ([0-3]? [0-7])? [0-7] + | '\\' 'u'+ BYTE BYTE + ; + +fragment ZERO: + '0'; + +INT: (PLUS | MINUS)? (ZERO | ZERO?[1-9][0-9]*); + +fragment EXPONENT: ('e'|'E') (PLUS | MINUS)? ('0'..'9')+; +FLOAT: (PLUS | MINUS)? [0-9]+ DOT [0-9]+ EXPONENT?; +HEX: '0x' [0-9a-fA-F]+; + +NAME: [a-z] ~[ \r\n\t,.|':;!?\][}{)(]*; +VER: [0-9]+ DOT [0-9]+ DOT [0-9]+; + +fragment TEXT_MARK: '"""'; +TEXT: + TEXT_MARK ('\n' | '\r\n') + (~[\\] | ESCAPE_SEQUENCE)*? + TEXT_MARK + ; \ No newline at end of file diff --git a/eo-parser/src/main/java/org/eolang/parser/XeListener.java b/eo-parser/src/main/java/org/eolang/parser/XeListener.java index aa8607e3c8..fbd6aa1475 100644 --- a/eo-parser/src/main/java/org/eolang/parser/XeListener.java +++ b/eo-parser/src/main/java/org/eolang/parser/XeListener.java @@ -204,29 +204,18 @@ public void enterAbstraction(final ProgramParser.AbstractionContext ctx) { ctx.getStart().getCharPositionInLine() ); this.objects.prop("abstract", ""); - this.objects.leave(); - } - - @Override - public void exitAbstraction(final ProgramParser.AbstractionContext ctx) { - // Nothing here - } - - @Override - public void enterType(ProgramParser.TypeContext ctx) { if (ctx.SLASH() != null) { - this.objects.enter(); if (ctx.QUESTION() == null) { this.objects.prop("atom", ctx.NAME()); } else { this.objects.prop("atom", "?"); } - this.objects.leave(); } + this.objects.leave(); } @Override - public void exitType(ProgramParser.TypeContext ctx) { + public void exitAbstraction(final ProgramParser.AbstractionContext ctx) { // Nothing here } diff --git a/eo-parser/src/test/resources/org/eolang/parser/typos/broken-head.yaml b/eo-parser/src/test/resources/org/eolang/parser/typos/broken-head.yaml index f550842c43..5cd1da8fda 100644 --- a/eo-parser/src/test/resources/org/eolang/parser/typos/broken-head.yaml +++ b/eo-parser/src/test/resources/org/eolang/parser/typos/broken-head.yaml @@ -2,6 +2,7 @@ # The syntax below is not supported, but it passes the test and # no typos are detected. We should fix it. Most probably EOL-s # are not detected at the end of objects correctly. +skip: true line: 1 eo: | [] > a [] > b [] > c [] > d hello world