📄 dvparse.y
字号:
/* * Copyright (C) 2006 Bill Cox * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA */%{#include "dv.h"dvModule dvCurrentModule;static dvSchema dvCurrentSchema;static dvEnum dvCurrentEnum;static dvClass dvCurrentClass;static dvUnion dvCurrentUnion;static dvProperty dvCurrentProperty;static dvRelationship dvCurrentRelationship;static uint32 dvCurrentEnumValue;static uint32 dvIntWidth;static uint16 dvUnionNumber;/*-------------------------------------------------------------------------------------------------- Provide yyerror function capability.--------------------------------------------------------------------------------------------------*/void dverror( char *message, ...){ char *buff; va_list ap; va_start(ap, message); buff = utVsprintf(message, ap); va_end(ap); utError("Line %d, token \"%s\": %s", dvLineNum, dvlextext, buff);}/*-------------------------------------------------------------------------------------------------- Build a user-defined type property, either an enum or typedef.--------------------------------------------------------------------------------------------------*/static dvProperty buildUserTypeProperty( dvModule module, utSym typeSym, utSym sym){ dvProperty property = dvPropertyCreate(dvCurrentClass, dvCurrentUnion, PROP_UNBOUND, sym); dvPropertySetTypeSym(property, typeSym); dvPropertySetLine(property, dvLineNum); if(module != dvCurrentModule) { /* Bind it now while we know the module */ dvBindProperty(property, module); } return property;}%}%union { utSym symVal; uint32 intVal; dvPropertyType propTypeVal; dvModule moduleVal; dvRelationshipType relationshipType;};%token <symVal> IDENT%token <intVal> INTEGER INTTYPE UINTTYPE%type <propTypeVal> propertyType%type <moduleVal> moduleSpec%type <relationshipType> relationshipType%type <symVal> optLabel optIdent upperIdent%token KWARRAY%token KWBEGIN%token KWBIT%token KWBOOL%token KWCASCADE%token KWCHAR%token KWCHILD_ONLY%token KWCLASS%token KWCREATE_ONLY%token KWDOUBLE%token KWDOUBLY_LINKED%token KWEND%token KWENUM%token KWFIXED_NUMBER%token KWFLOAT%token KWFREE_LIST%token KWHASHED%token KWIMPORT%token KWINHERITANCE%token KWLINKED_LIST%token KWMANDATORY%token KWMODULE%token KWPARENT_ONLY%token KWPERSISTENT%token KWREFERENCE_SIZE%token KWRELATIONSHIP%token KWSCHEMA%token KWSYM%token KWTAIL_LINKED%token KWTYPEDEF%token KWUNION%token KWVOLATILE%token KWUNDO_REDO%%goal: initialize module;initialize: /* Empty */{ dvCurrentUnion = dvUnionNull;}module: moduleHeader moduleParameters '\n' moduleStuff;moduleParameters: /* Empty */| moduleParameters moduleParameter;moduleParameter: KWVOLATILE| KWPERSISTENT{ dvModuleSetPersistent(dvCurrentModule, true);}| KWUNDO_REDO{ dvModuleSetUndoRedo(dvCurrentModule, true);};moduleHeader: KWMODULE upperIdent optIdent{ dvCurrentModule = dvModuleCreate($2, $3); dvCurrentSchema = dvSchemaNull;};optIdent: /* Empty */{ $$ = utSymNull;}| IDENT{ $$ = $1;};moduleStuff: /* Empty */| moduleStuff moduleElement;moduleElement: import| enum| typedef| schema| class| relationship;import: KWIMPORT upperIdent '\n'{ dvModule importModule = dvRootFindModule(dvTheRoot, $2); dvLinkCreate(dvCurrentModule, importModule);};enum: enumHeader KWBEGIN entries KWEND;enumHeader: KWENUM upperIdent optIdent '\n'{ dvCurrentEnum = dvEnumCreate(dvCurrentModule, $2, $3); dvCurrentEnumValue = 0;};entries: entry| entries entry;entry: IDENT '\n'{ dvEntryCreate(dvCurrentEnum, $1, dvCurrentEnumValue); dvCurrentEnumValue++;}| IDENT '=' INTEGER '\n'{ dvCurrentEnumValue = $3; dvEntryCreate(dvCurrentEnum, $1, dvCurrentEnumValue); dvCurrentEnumValue++;};typedef: KWTYPEDEF typedefIdents '\n';typedefIdents: IDENT{ dvTypedefCreate(dvCurrentModule, $1);}| typedefIdents IDENT{ dvTypedefCreate(dvCurrentModule, $2);};schema: KWSCHEMA upperIdent '\n'{ dvCurrentSchema = dvSchemaCreate(dvCurrentModule, $2);};class: classHeader classOptions '\n' KWBEGIN properties KWEND| classHeader classOptions '\n';classHeader: KWCLASS upperIdent optLabel{ dvClass baseClass = dvClassNull; dvModule baseModule = dvModuleNull; if($3 != utSymNull) { baseModule = dvRootFindModule(dvTheRoot, $3); if(baseModule == dvModuleNull) { dverror("Undefined module %s", utSymGetName($3)); } baseClass = dvModuleFindClass(baseModule, $2); if(baseClass == dvClassNull) { dverror("Base class %s not defined in module %s", utSymGetName($2), utSymGetName($3)); } } dvCurrentClass = dvClassCreate(dvCurrentModule, dvCurrentSchema, $2, baseClass); dvUnionNumber = 1;};classOptions: /* Empty */| classOptions classOption;classOption: KWREFERENCE_SIZE INTEGER{ if($2 & 7) { dverror("Reference sizes may only be 8, 16, 32, or 64"); } dvClassSetReferenceSize(dvCurrentClass, $2);}| KWFREE_LIST{ dvClassSetMemoryStyle(dvCurrentClass, MEM_FREE_LIST);}| KWCREATE_ONLY{ dvClassSetMemoryStyle(dvCurrentClass, MEM_CREATE_ONLY);}| KWARRAY{ dvClassSetGenerateArrayClass(dvCurrentClass, true);};properties: property '\n'| union| properties property '\n'| properties union;property: baseProperty| baseProperty KWCASCADE{ dvPropertySetCascade(dvCurrentProperty, true);}| KWARRAY baseProperty{ if(dvCurrentUnion != dvUnionNull) { dverror("Arrays are not allowed in unions"); } dvPropertySetArray(dvCurrentProperty, true);}| KWARRAY baseProperty KWCASCADE{ if(dvCurrentUnion != dvUnionNull) { dverror("Arrays are not allowed in unions"); } dvPropertySetArray(dvCurrentProperty, true); dvPropertySetCascade(dvCurrentProperty, true);};baseProperty: IDENT upperIdent{ dvCurrentProperty = buildUserTypeProperty(dvCurrentModule, $1, $2);}| moduleSpec IDENT upperIdent{ dvCurrentProperty = buildUserTypeProperty($1, $2, $3);}| propertyType upperIdent{ dvCurrentProperty = dvPropertyCreate(dvCurrentClass, dvCurrentUnion, $1, $2); if($1 == PROP_INT || $1 == PROP_UINT) { if(dvIntWidth != 8 && dvIntWidth != 16 && dvIntWidth != 32 && dvIntWidth != 64) { dverror("Valid integer widths are 8, 16, 32, and 64"); } dvPropertySetWidth(dvCurrentProperty, dvIntWidth); }};moduleSpec: IDENT ':'{ dvModule module = dvRootFindModule(dvTheRoot, $1); if(module == dvModuleNull) { module = dvFindModuleFromPrefix($1); } if(module == dvModuleNull) { dverror("Module %s not found", utSymGetName($1)); } $$ = module;}propertyType: INTTYPE{ dvIntWidth = $1; $$ = PROP_INT;}| UINTTYPE{ dvIntWidth = $1; $$ = PROP_UINT;}| KWFLOAT{ $$ = PROP_FLOAT;}| KWDOUBLE{ $$ = PROP_DOUBLE;}| KWBIT{ if(dvCurrentUnion == dvUnionNull) { $$ = PROP_BIT; } else { $$ = PROP_BOOL; }}| KWBOOL{ $$ = PROP_BOOL;}| KWCHAR{ $$ = PROP_CHAR;}| KWENUM{ $$ = PROP_ENUM;}| KWTYPEDEF{ $$ = PROP_TYPEDEF;}| KWSYM{ $$ = PROP_SYM;};union: unionHeader KWBEGIN nonUnionProperties KWEND{ if(dvUnionGetFirstProperty(dvCurrentUnion) == dvPropertyNull) { dvUnionDestroy(dvCurrentUnion); } dvCurrentUnion = dvUnionNull;};unionHeader: KWUNION upperIdent '\n'{ dvCurrentUnion = dvUnionCreate(dvCurrentClass, $2, dvUnionNumber++);};nonUnionProperties: property ':' unionCases '\n'| nonUnionProperties property ':' unionCases '\n';unionCases: unionCase| unionCases unionCase;unionCase: IDENT{ dvCase theCase = dvCaseAlloc(); dvCaseSetEntrySym(theCase, $1); dvPropertyAppendCase(dvCurrentProperty, theCase);}relationship: relationshipHeader relationshipOptions '\n';relationshipHeader: KWRELATIONSHIP upperIdent optLabel upperIdent optLabel relationshipType{ dvClass parent = dvModuleFindClass(dvCurrentModule, $2); dvClass child = dvModuleFindClass(dvCurrentModule, $4); if(parent == dvClassNull) { dverror("Unknown class %s", utSymGetName($2)); } if(child == dvClassNull) { dverror("Unknown class %s", utSymGetName($4)); } dvCurrentRelationship = dvRelationshipCreate(parent, child, $6, $3, $5);};optLabel: /* Empty */{ $$ = utSymNull;}| ':' upperIdent{ $$ = $2;};relationshipOptions: /* Empty */| relationshipOptions relationshipOption;relationshipType: /* Empty */{ $$ = REL_POINTER;}| KWLINKED_LIST{ $$ = REL_LINKED_LIST;}| KWDOUBLY_LINKED{ $$ = REL_DOUBLY_LINKED;}| KWTAIL_LINKED{ $$ = REL_TAIL_LINKED;}| KWARRAY{ $$ = REL_ARRAY;}| KWHASHED{ $$ = REL_HASHED;};relationshipOption: KWCASCADE{ dvRelationshipSetCascade(dvCurrentRelationship, true);}| KWMANDATORY{ dvRelationshipSetMandatory(dvCurrentRelationship, true); dvRelationshipSetCascade(dvCurrentRelationship, true);}| KWPARENT_ONLY{ dvRelationshipSetAccessChild(dvCurrentRelationship, false);}| KWCHILD_ONLY{ dvRelationshipSetAccessParent(dvCurrentRelationship, false);};upperIdent: IDENT{ $$ = dvUpperSym($1);}%%
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -