解析ANTLR 3中的浮点数和单个周期/点

时间:2014-01-13 11:53:34

标签: java antlr cobol

如何解析浮点数,以及ANTLR 3中的单个句点/点?

以下是我的问题的详细信息......

    grammar AntlrCobolParser;

options {
   k=8;
   output=AST;
   language=Java;
}

@header {

package com;
}

@lexer::header {
package com;
}


untilStmt
: 'UNTIL' condition (stopword | DOT)
{
  System.out.println("UNTIL condition: " + $condition.text);
}
;

fragment
condition : ( condWord )+
;

fragment 
condWord : (IDENTIFIER | NUMERIC | HEXNUMBER | STRING)
;


STRING
: '"' (~('"') | ('"') ('"') )* '"'  | '\'' (~('\'') | ('\'') ('\'') )* '\''
;


WS  
: ( BL | '\r' | '\n' | '\u000C' | ',' |  ';' )+
{
  { $channel = HIDDEN; }
}
;

fragment BL : ( ' ' | '\t' ) ;

stopword : word = ( 'DELETE' 'OPEN' | 'REWRITE' | 'STOP' | 'WRITE' | 'ALTER'
  | 'IF' | 'ELSEIF' | 'THEN' | 'ELSE' | 'ENDIF' | 'NEXT' | 'WHEN'
  | 'ENDEVALUATE' | 'ENDPERFORM' | 'ENDSTART' | 'ENDCALL' | 'EXIT')
{
  input.rewind();
}
;

IDENTIFIER
: id=ID1 | id=ID2
;

fragment ID1
: ('0'..'9')+ ('a'..'z'|'A'..'Z'|'-'|'_'|':') ('0'..'9'|':'|'a'..'z'|'A'..'Z'|'-'|'_')*
;

fragment ID2
: ('a'..'z'|'A'..'Z'|':'|'@') ('a'..'z'|'A'..'Z'|'0'..'9'|':'|'-'|'_')*
;

NUMERIC 
: ('+'|'-')? (('0'..'9')+ (('.') ('0'..'9')+)? | ( ('.') ('0'..'9')+ ) )
;

HEXNUMBER
: ('h' | 'H' | 'x' | 'X') ( (QUOTECHAR ('a'..'z'|'A'..'Z'|'0'..'9')+ QUOTECHAR) | (APOSTROPHE ('a'..'z'|'A'..'Z'|'0'..'9')+ APOSTROPHE) ) ;

fragment QUOTECHAR : '"' ;                         
fragment APOSTROPHE: '\'' ;

DOT 
: '.'
;

此解析器语法正确提取所有 UNTIL 条件但在条件结束时给出错误的结果 - 例如DOT。

3700A-FIND-ERRORS.
          MOVE PL-0048-KEY-APPL-CODE-M     TO TBLBKT  (01).
          MOVE PL-0048-KEY-APPL-NBR-M      TO TBLBKT  (02).
          MOVE PL-0048-KEY-SUB-ACCT-M      TO TBLBKT  (03).

          MOVE '0048-KEY-APPL-CODE      '  TO TBLDESC (01).
          MOVE '0048-KEY-APPL-NBR       '  TO TBLDESC (02).
          MOVE '0048-KEY-SUB-ACCT       '  TO TBLDESC (03).

          MOVE 3     TO MAX-ERRORS-CNT.
          PERFORM 6000-BUILD-ERRORS
             THRU 6000-BUILD-ERRORS-EXIT
           VARYING SUB FROM 1 BY 1
             UNTIL SUB GREATER THAN 3.
   3700A-FIND-ERRORS-EXIT.
       EXIT.

在上面的示例中,它将 SUB GREATER THAN 3 3700A-FIND-ERRORS-EXIT 作为UNTIL条件,这是不正确的。我正在尝试解析大型机COBOL源。

请告诉我的假设有什么不正确?

提前致谢! 基肖尔马布

2 个答案:

答案 0 :(得分:2)

很抱歉地说,但你可能会在这里过头。 COBOL是一门难懂的语言 写一个好的解析器。除非你非常了解解析技术和 COBOL语言语法,你在这里受到了很大的伤害。

从我收集到的内容,您正在尝试编写岛屿解析器(请参阅island parsers) 唯一感兴趣的东西是条件表达式。我认为你至少 必须编写一个解析器来首先隔离PROCEDURE DIVISION,然后将其分解为 SECTION/PARAGRAPH/SENTENCE/STATEMENT结构。 一旦提取了STATEMENT,您就可以在岛上解析那些可能包含条件表达式的语句。

为什么需要这么多细节来解析语句中的条件表达式?您的代码示例可用于说明这一点。 你当前的解析器 将UNTIL短语视为:

           UNTIL SUB GREATER THAN 3.

它将3.表示为浮点常量。这不是浮点常数。在更大的代码片段的上下文中:

        PERFORM 6000-BUILD-ERRORS
           THRU 6000-BUILD-ERRORS-EXIT
         VARYING SUB FROM 1 BY 1
           UNTIL SUB GREATER THAN 3.
 3700A-FIND-ERRORS-EXIT.
     EXIT. 

唯一可能的句号代表是句号终止符,也恰好是段落终止符(每个段落) 必须以句点结束 - 下一行代码是新的段落标题,因此前一段必须是段落终止符。)

我确信您可以通过一些特殊的解析规则解决这个特定问题。但这不是我的回应。我的观点是,没有完全理解 COBOL的语法永远无法构建健壮的解析器。

作为您可能遇到的问题类型的说明,请考虑以下条件语句:

    IF A > B AND C

在知道C代表什么之前,无法确定此条件的确切含义。如果C是一个简单的变量,那么意思就是 是:

    IF (A > B) AND (A > C)

但是,如果C是88级别的名称,例如:

    01 WS-X     PIC X.
       88 C     VALUE 'A' THRU 'D'.

含义变为

    IF (A > B) AND (WS-X = 'A' OR
                    WS-X = 'B' OR
                    WS-X = 'C' OR
                    WS-X = 'D')

正如您所看到的,这些是完全不同的。如上所示的条件表达式需要复杂的解析技术 解决。

答案 1 :(得分:1)

您可以使用DOT的定义来完成此操作。如果第72列要求存在问题,请记住,如果您愿意,列73-80可以完全为空白,因此您可以清除第73列并将数据视为第8-73列。

如果你不能那样定义你的DOT ......

处理问题中的示例问题的一种简单方法是预处理PROCEDURE DIVISION代码。识别所有“。”,删除“。”并使用“。”创建一个新行。在第12栏中。确定所有“。”在第72列中,删除“。”又一次用“。”创建一个新行。在第12列中。您必须在执行此操作时忽略字母数字文字(文本以“直到下一个”或“直到下一个”开头)。

这不会以任何方式影响程序(你可以举一个例子并编译它,结果将是相同的,对象的逐字节(不包括编译日期/时间)到原始程序)。即使已经存在只包含“。”的行。改变它们不会有什么坏处,或者你可以将它们保留原样。没有区别。

如果您只是提取条件文本,这将有所帮助。如果你试图完全解析条件,你就会遇到NealB指出的问题。

请记住,有很多地方可以存在条件。具有END-in的所有东西都可以包含条件。例如,AT END中的READ可能并不重要,但ON SIZE ERROR可能存在,{/ 1}}。

在您的示例中,单独的条件(没有VARYING中的信息)会丢失大量上下文。在试图孤立地处理其他条件时,你会遇到类似的问题。

我真的不确定你期望从中得到什么。在该示例中,您有一个条件,它只是查看循环控制变量。你可能有一个看起来相似的条件,它没有查看循环控制变量,只是从查看条件你就无法确定地区分它们。您应该能够提取构成条件的文本,但它可能不是最终过程所需的文本。

我建议手动/半手动执行几个程序,然后一直处理这些数据。如果一切顺利,没问题。如果你需要做出改变,他们可能会否定你现在所做的工作,把你已经完成的工作带到你认为有效的状态,但是你已经给出了要求,这是有缺陷的。