| | 1 | = Formal Grammar for UCUM = |
| | 2 | |
| | 3 | This grammar was created from a parser project employing ANTLR as a LL(*) parser generator. Note that this is only one of many ways to express a formal Grammar for UCUM. Alternatively the grammar could be written for LR-parser generators (e.g. yacc). Lexer rules have been omitted for clarity. The objective is to create UCUM-parsers from a declarative definition of the grammar. |
| | 4 | |
| | 5 | {{{ |
| | 6 | ucumExpr : DIVIDE expr |
| | 7 | | expr |
| | 8 | ; |
| | 9 | multiply : TIMES term |
| | 10 | | DIVIDE term |
| | 11 | ; |
| | 12 | expr : term (multiply)* |
| | 13 | ; |
| | 14 | term : element (exponent)? (ANN)* |
| | 15 | ; |
| | 16 | element : simpleUnit |
| | 17 | | LPAREN expr RPAREN |
| | 18 | | ANN |
| | 19 | ; |
| | 20 | exponent : (SIGN)? DIGITS // allow zero exponent? |
| | 21 | ; |
| | 22 | simpleUnit : prefix metricAtom // prefix is token from lexer |
| | 23 | | metricAtom |
| | 24 | | nonMetricAtom // token from lexer |
| | 25 | | DIGITS // allow zero? |
| | 26 | ; |
| | 27 | metricAtom : baseUnit // token from lexer |
| | 28 | | derivedMetricAtom // token from lexer |
| | 29 | ; |
| | 30 | }}} |
| | 31 | |
| | 32 | The following is an original code snippet from a working project using the ANTLR parser generator: |
| | 33 | |
| | 34 | {{{ |
| | 35 | //... |
| | 36 | startRule returns [UnitExpr u=null] |
| | 37 | : u=ucumExpr EOF // or EOL |
| | 38 | ; |
| | 39 | |
| | 40 | ucumExpr returns [UnitExpr u=null] |
| | 41 | : DIVIDE u=expr { u.invert(); } |
| | 42 | | u=expr |
| | 43 | ; |
| | 44 | |
| | 45 | multiply[UnitExpr a] returns [UnitExpr u=null] |
| | 46 | : TIMES u=term { u=a.multiply(u); } |
| | 47 | | DIVIDE u=term { u.invert(); u=a.multiply(u); } |
| | 48 | ; |
| | 49 | |
| | 50 | expr returns [UnitExpr u=null] |
| | 51 | : u=term (u=multiply[u])* |
| | 52 | ; |
| | 53 | |
| | 54 | term returns [UnitExpr u=null] |
| | 55 | { int exp = 1; } |
| | 56 | : u=element (exp=exponent)? (ANN)* { u.setExponent(exp); } |
| | 57 | ; |
| | 58 | |
| | 59 | element returns [UnitExpr u=null] |
| | 60 | : u=simpleUnit |
| | 61 | | LPAREN u=expr RPAREN |
| | 62 | | ANN { u = new UnitExpr();} |
| | 63 | ; |
| | 64 | |
| | 65 | exponent returns [int exp=1] |
| | 66 | : (s:SIGN)? e:DIGITS // allow zero? |
| | 67 | { |
| | 68 | exp = Integer.parseInt(e.getText()); |
| | 69 | if(s != null && s.getText().equals("-") ) exp *= -1; |
| | 70 | } |
| | 71 | ; |
| | 72 | |
| | 73 | simpleUnit returns [UnitExpr u=null] |
| | 74 | { double p=0; } |
| | 75 | : p=prefix u=metricAtom { u.setPrefix(p); } |
| | 76 | | u=metricAtom |
| | 77 | | u=nonMetricAtom |
| | 78 | | d:DIGITS { u = new UnitExpr(Integer.parseInt(d.getText())); } // allow zero? |
| | 79 | ; |
| | 80 | |
| | 81 | metricAtom returns [UnitExpr u=null] |
| | 82 | : u=baseUnit |
| | 83 | | u=derivedMetricAtom |
| | 84 | ; |
| | 85 | //... lexer definitions follow |
| | 86 | }}} |