X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.spreadsheet%2Fsrc%2Forg%2Fsimantics%2Fspreadsheet%2Fsolver%2Fformula%2Fparser%2FSheetFormulaParser.jj;fp=bundles%2Forg.simantics.spreadsheet%2Fsrc%2Forg%2Fsimantics%2Fspreadsheet%2Fsolver%2Fformula%2Fparser%2FSheetFormulaParser.jj;h=fb86e614fa82ec57f17f7d3982aa1e7e8a99537a;hb=5c67a96d34fe904b8c4b0375cd08ff1d543bf369;hp=0000000000000000000000000000000000000000;hpb=9a37dabc6c0212ed3e14499c88df3208cd06f9b0;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.spreadsheet/src/org/simantics/spreadsheet/solver/formula/parser/SheetFormulaParser.jj b/bundles/org.simantics.spreadsheet/src/org/simantics/spreadsheet/solver/formula/parser/SheetFormulaParser.jj new file mode 100644 index 000000000..fb86e614f --- /dev/null +++ b/bundles/org.simantics.spreadsheet/src/org/simantics/spreadsheet/solver/formula/parser/SheetFormulaParser.jj @@ -0,0 +1,205 @@ +options { + JDK_VERSION = "1.8"; + STATIC = false; + IGNORE_CASE = false; + UNICODE_INPUT = true; + JAVA_UNICODE_ESCAPE = false; +} + +PARSER_BEGIN(SheetFormulaParser) +package org.simantics.spreadsheet.graph.parser; + +import org.simantics.spreadsheet.graph.parser.ast.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Collections; + +/** + * Parser for spreadsheet formulas + * @author Antti Villberg + */ +public class SheetFormulaParser { +} +PARSER_END(SheetFormulaParser) + +/*** Lexer *********************************************************/ + +SKIP: +{ +| +| +} + +TOKEN: +{ ";" | "(" | ")" | "?" | "[" | "]" +| "{" | "}" | "|" | "&" | "+" | "*" | "/" | "^" +| "," | ".." | "." | "=" | "<" | ">" | "<>" +| "true" | "false" | "null" | "TRUE" | "FALSE" +| < #LETTER: [ + "\u0024", //DOLLAR SIGN: milreis, escudo + "\u0041"-"\u005a", //LATIN CAPITAL LETTER A - LATIN CAPITAL LETTER Z + "\u005f", //LOW LINE: spacing underscore + "\u0061"-"\u007a", //LATIN SMALL LETTER A - LATIN SMALL LETTER Z + "\u00aa"-"\u00ad", // 00AA FEMININE ORDINAL INDICATOR: spanish + // 00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK: left guillemet + // 00AC NOT SIGN: angled dash + // 00AD SOFT HYPHEN: discretionary hyphen + "\u00b5"-"\u00b6", // 00B5 MICRO SIGN: greek small letter mu + // 00B6 PILCROW SIGN: paragraph sign + "\u00ba"-"\u00bb", // 00BA MASCULINE ORDINAL INDICATOR: spanish + // 00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK : right guillemet + "\u00c0"-"\u00d6", //LATIN CAPITAL LETTER A WITH GRAVE - LATIN CAPITAL LETTER O WITH DIAERESIS + "\u00d8"-"\u00f6", //LATIN CAPITAL LETTER O WITH STROKE - LATIN SMALL LETTER O WITH DIAERESIS + "\u00f8"-"\u00ff", //LATIN SMALL LETTER O WITH STROKE - LATIN SMALL LETTER Y WITH DIAERESIS + "\u0100"-"\u1fff", //LATIN CAPITAL LETTER A WITH MACRON - GREEK DASIA:reversed comma + "\u3040"-"\u318f", //Hiragana - Hangul + "\u3300"-"\u337f", //Squared Katakana + "\u3400"-"\u3d2d", //CJK Unified Ideographs Extension A + "\u4e00"-"\u9fff", //CJK Unified Ideographs + "\uf900"-"\ufaff", //CJK Compatibility Ideographs + "\ufb00"-"\ufb06", //LATIN SMALL LIGATURE FF -LATIN SMALL LIGATURE ST + "\ufb13"-"\ufb17", //ARMENIAN SMALL LIGATURE MEN NOW - ARMENIAN SMALL LIGATURE MEN XEH + "\ufb1f"-"\ufb28", //HEBREW LIGATURE YIDDISH YOD YOD PATAH -HEBREW LETTER WIDE TAV + "\ufb2a"-"\ufb36", //HEBREW LETTER SHIN WITH SHIN DOT - HEBREW LETTER ZAYIN WITH DAGESH + "\ufb38"-"\ufb3e", //HEBREW LETTER TET WITH DAGESH - HEBREW LETTER MEM WITH DAGESH + "\ufb40"-"\ufb41", //HEBREW LETTER NUN WITH DAGESH - HEBREW LETTER SAMEKH WITH DAGESH + "\ufb43"-"\ufb44", //HEBREW LETTER FINAL PE WITH DAGESH - HEBREW LETTER PE WITH DAGESH + "\ufb46"-"\ufb4f", //HEBREW LETTER TSADI WITH DAGESH - HEBREW LIGATURE ALEF LAMED + "\ufb50"-"\ufdd7", //Arabic Presentation Forms(A) - ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM + "\ufdf0"-"\ufdfd", //ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM -ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM + "\ufe70"-"\ufefc", //Arabic Presentation Forms(B) - ARABIC LIGATURE LAM WITH ALEF FINAL FORM + "\uff1f"-"\uff3a", //FULLWIDTH QUESTION MARK - FULLWIDTH LATIN CAPITAL LETTER Z + "\uff3f"-"\uff5e", //FULLWIDTH LOW LINE - FULLWIDTH TILDE + "\uff61"-"\uffbe", //Halfwidth CJK punctuation:HALFWIDTH IDEOGRAPHIC FULL STOP - HALFWIDTH HANGUL LETTER HIEUH + "\uffc2"-"\uffc7", //HALFWIDTH HANGUL LETTER A - HALFWIDTH HANGUL LETTER E + "\uffca"-"\uffcf", //HALFWIDTH HANGUL LETTER YEO - HALFWIDTH HANGUL LETTER OE + "\uffd2"-"\uffd7", //HALFWIDTH HANGUL LETTER YO - HALFWIDTH HANGUL LETTER YU + "\uffda"-"\uffdc" //HALFWIDTH HANGUL LETTER EU - HALFWIDTH HANGUL LETTER I + ] + > +| <#ALPHANUM: < LETTER > | ["0"-"9"] > +| + { matchedToken.image = SheetParserUtils.unescape( + matchedToken.image.substring(1,matchedToken.image.length()-1)); } +| + { matchedToken.image = SheetParserUtils.unescape( + matchedToken.image.substring(1,matchedToken.image.length()-1)); } +| + { matchedToken.image = matchedToken.image.substring(3,matchedToken.image.length()-3); } +| +| <#CELL_RANGE_PART: (["$"]){0,1}(["A"-"Z"]){1,5}(["$"]){0,1}(["0"-"9"]){0,5} > +| [":"] > +| (< ALPHANUM >)* > +| <#POSITIVE_INTEGER: (["0"-"9"])+ > +| "." (["e","E"] )? + | "." (["e","E"] )? + | ["e","E"] + ) > +| > + +} + +AstValue primary() : { + Token tok; + AstValue temp; + AstRange tempRange; +} { + "null" { return AstNull.NULL; } + | "true" { return AstBoolean.TRUE; } + | "false" { return AstBoolean.FALSE; } + | "TRUE" { return AstBoolean.TRUE; } + | "FALSE" { return AstBoolean.FALSE; } + | { return new AstString(token.image); } + | { return new AstString(token.image); } + | { return new AstDouble(token.image); } + | { return new AstInteger(Integer.parseInt(token.image)); } + | LOOKAHEAD(2) (tok = | tok = ) "!" tempRange = range() { return tempRange.inSheet(tok.image); } + | LOOKAHEAD(2) temp = apply() { return temp; } | "(" temp = relation() ")" { return temp; } + | temp = range() { return temp; } + | temp = array() { return temp; } + | { return new AstIdentifier(token.image); } +} + +AstApply apply() : { AstArgList al; + Token tok; +} { + LOOKAHEAD(3) tok = "(" ")" { return new AstApply(tok.image, null); } | + tok = "(" al = arglist() ")" { return new AstApply(tok.image, al); } } + +AstValue array() : { + AstArray arr = new AstArray(); + AstValue temp; +} { + LOOKAHEAD(2) "{" "}" { return new AstArray(); } | + "{" temp = relation() { arr.add(temp); } "," ( temp = relation() { arr.add(temp); } )* "}" { return arr; } } + +AstRange range() : { + Token temp1; + Token temp2; +} { + LOOKAHEAD(2) { return new AstRange(token.image); } + | { return new AstRange(token.image); } + | "#REF!" { return AstRange.REF; } +} + +AstArgList arglist() : { + AstArgList ret = new AstArgList(); + AstValue temp; +} { + temp = relation() { ret.add(temp); } ( (";"|",") { temp = AstNothing.INSTANCE; } (temp = relation())? { ret.add(temp); } )* { return ret; } +} + +AstValue relation() : { + AstRelation ret; + String op; + AstValue ex; +} { + ex = arithmetic_expression() { ret = new AstRelation(ex); } ( op = rel_op() ex = arithmetic_expression() { ret.setRight(op, ex); } )? { return ret.simplify(); } } + +String rel_op() : { +} { + "<" { return "< ";} | "<=" { return "<=";} | ">" { return " >";} | ">=" { return " >=";} | "=" { return "=";} | "<>" { return "<>";} +} + +// +AstValue arithmetic_expression() : { + AstArithmeticExpression ret; + String op = null; + AstValue temp; +} { + (op = add_op())? temp = term() { ret = new AstArithmeticExpression(op, temp); } ( LOOKAHEAD(2) op = add_op() temp = term() { ret.add(op, temp); } )* { return ret.simplify(); } +} + +String add_op() : { +} { + "+" { return "+";} | "-" { return "-";} | "&" { return "&";} +} + +AstValue term() : { + AstTerm ret; + String op; + AstValue temp; +} { + temp = factor() { ret = new AstTerm(temp); } (op = mul_op() temp = factor() { ret.add(op, temp); } )* { return ret.simplify(); } +} + + +String mul_op() : { +} { + "*" { return "*";} | "/" { return "/";} +} + +AstValue factor() : { + AstFactor ret; + String op; + AstValue temp; +} { + temp = primary() { ret = new AstFactor(temp); } (op = factor_op() temp = primary() { ret.add(op, temp); } )* { return ret.simplify(); } +} + +String factor_op() : { +} { + "^" { return "^";} +} +