options { JDK_VERSION = "1.6"; STATIC = false; IGNORE_CASE = false; } PARSER_BEGIN(DataParser) package org.simantics.databoard.parser; import org.simantics.databoard.parser.ast.type.*; import org.simantics.databoard.parser.ast.value.*; import java.util.ArrayList; import java.util.List; import java.util.Collections; /** * Parser for data type definitions. * @author Hannu Niemist� */ public class DataParser { } PARSER_END(DataParser) /*** Lexer *********************************************************/ SKIP: { | | } TOKEN: { ";" | "(" | ")" | "?" | "[" | "]" | "{" | "}" | "|" | "&" | ":" | "," | ".." | "." | "=" | "<" | ">" | "type" | "true" | "false" | "null" | "map" | "referable" | { matchedToken.image = StringEscapeUtils.unescape( matchedToken.image.substring(1,matchedToken.image.length()-1)); } | { matchedToken.image = matchedToken.image.substring(3,matchedToken.image.length()-3); } | <#POSITIVE_INTEGER: (["0"-"9"])+ > | > | "." (["e","E"] )? | "." (["e","E"] )? | ["e","E"] | "NaN" | "Infinity" ) > | | "])* ">"> { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } } /*** Type parser ***************************************************/ List typeDefinitions() : { AstTypeDefinition def; List result = new ArrayList(); } { ( def=typeDefinition() { result.add(def); } )* { return result; } } AstTypeDefinition typeDefinition() : { Token name; AstType type; } { "type" name= "=" type=type() { return new AstTypeDefinition(name.image, type); } } AstType type() : { AstType type; } { type=simpleType() { return type; } | type=unionType() { return type; } } AstType unionType() : { List components = new ArrayList(4); } { ( "|" unionComponent(components) )+ { return new AstUnionType(components); } } private void unionComponent(List components) : { Token tag; AstType type; } { tag= ( type=simpleType() { components.add(new AstComponent(tag.image, type)); } | { components.add(new AstComponent(tag.image, AstRecordType.EMPTY_RECORD)); } ) } AstType simpleType() : { AstType type; } { type=basicType() ( "[" type=arraySuffix(type) )* { return type; } } private AstType arraySuffix(AstType componentType) : { Token t1, t2; Integer v1; } { "]" { return new AstArrayType(componentType, null, null); } | ".." t1= "]" { v1 = Integer.parseInt(t1.image); return new AstArrayType(componentType, null, v1); } | t1= { v1 = Integer.parseInt(t1.image); } ( "]" { return new AstArrayType(componentType, v1, v1); } | ".." ( "]" { return new AstArrayType(componentType, v1, null); } | t2= "]" { return new AstArrayType(componentType, v1, Integer.parseInt(t2.image)); } ) ) } AstType basicType() : { AstType type; boolean referable = false; } { "(" type = tupleType() ")" { return type; } | ("referable" {referable=true;})? "{" type = recordType(referable) "}" { return type; } | type = typeReference() { return type; } } AstType typeReference() : { Token name; List parameters = Collections.emptyList(); List attributes = Collections.emptyList(); } { name= ("(" { parameters = new ArrayList(2); attributes = new ArrayList(2); } parameter(parameters, attributes) ("," parameter(parameters, attributes))* ")")? { return new AstTypeReference(name.image, parameters, attributes); } } private void parameter(List parameters, List attributes) : { Token key; String value; AstType type; } { LOOKAHEAD( "=") key= "=" value=attributeValue() { attributes.add(new AstAttribute(key.image, value)); } | type=type() { parameters.add(type); } } String numericValue() : {} { ( | ) { return token.image; } | "-" ( | ) { return "-" + token.image; } } String range() : { Token open, close; String first = "", second = ""; } { ( "[" | "(" ) { open = token; } ( first = numericValue() )? ".." ( second = numericValue() )? ( "]" | ")" ) { close = token; } { return open.image + first + ".." + second + close.image; } } String attributeValue() : { String str; } { ( | "true" | "false" ) { return token.image; } | str=numericValue() { return str; } | str=range() { return str; } } AstType tupleType() : { AstType type; ArrayList types; } { type = type() { types = new ArrayList(3); types.add(type); } ( "," type = type() { types.add(type); } )* { if(types.size()==1) return types.get(0); else return new AstTupleType(types); } | { return new AstTupleType(Collections.emptyList()); } } AstType recordType(boolean referable) : { AstComponent component; ArrayList components; } { component = component() { components = new ArrayList(3); components.add(component); } ( "," component = component() { components.add(component); } )* { return new AstRecordType(referable, components); } | { return new AstRecordType(referable, Collections.emptyList()); } } AstComponent component() : { Token field; AstType type; } { (field= | field="type" | field="referable") ":" type=type() { return new AstComponent(field.image, type); } } /*** Value parser **************************************************/ List valueDefinitions() : { AstValueDefinition def; List result = new ArrayList(); } { ( def=valueDefinition() { result.add(def); } )* { return result; } } AstValueDefinition valueDefinition() : { Token name; AstValue value; AstType type; } { name= ":" type=type() "=" value=value() { return new AstValueDefinition(name.image, type, value); } } AstValue value() : { AstValue value; AstType type; } { value = basicValue() ( ":" type = type() { value = new AstVariant(value, type); } )* { return value; } } AstValue basicValue() : { Token tag; AstValue temp; } { "null" { return AstNull.NULL; } | { return new AstString(token.image); } | { return new AstString(token.image); } | { return new AstInteger(token.image); } | { return new AstFloat(token.image); } | "true" { return AstBoolean.TRUE; } | "false" { return AstBoolean.FALSE; } | "map" "{" temp=map() "}" { return temp; } | "[" temp=array() "]" { return temp; } | "{" temp=record() "}" { return temp; } | "(" temp=tuple() ")" { return temp; } | tag= ( temp=basicValue() { return new AstTaggedValue(tag.image, temp); } | { return new AstReference(tag.image); } ) } AstArray array() : { ArrayList components; AstValue value; } { { components = new ArrayList(); } value=value() { components.add(value); } ("," value=value() { components.add(value); })* { return new AstArray(components); } | { return AstArray.EMPTY; } } AstValue tuple() : { ArrayList components; AstValue value; } { { components = new ArrayList(); } value=value() { components.add(value); } ("," value=value() { components.add(value); })* { if(components.size() == 1) return components.get(0); else return new AstTuple(components); } | { return AstTuple.EMPTY; } } AstRecord record() : { ArrayList components; AstComponentAssignment assignment; } { { components = new ArrayList(); } assignment=assignment() { components.add(assignment); } ("," assignment=assignment() { components.add(assignment); })* { return new AstRecord(components); } | { return AstRecord.EMPTY; } } AstMap map() : { ArrayList components; AstMapAssignment assignment; } { { components = new ArrayList(); } assignment=mapAssignment() { components.add(assignment); } ("," assignment=mapAssignment() { components.add(assignment); })* { return new AstMap(components); } | { return AstMap.EMPTY; } } AstComponentAssignment assignment() : { Token name; AstValue value; } { name= "=" value=value() { return new AstComponentAssignment(name.image, value); } } AstMapAssignment mapAssignment() : { AstValue key; AstValue value; } { key=value() "=" value=value() { return new AstMapAssignment(key, value); } }